From 5db24213bde971dd5da6630f8ab0fee4ce47c73f Mon Sep 17 00:00:00 2001 From: Zaine Arch Date: Sun, 14 Dec 2025 21:07:46 +0000 Subject: [PATCH] initial --- #20251122223053-keyboard.org# | 166 +++ .DS_Store | Bin 0 -> 24580 bytes .markdown-preview.html | 43 + 20241210001045-technical.org | 20 + 20241210001045-technical.org~ | 19 + 20241210001045-technical_coding.org~ | 15 + 20241210001045-technical_moc.org | 16 + 20241210001150-aoc_notes.org | 1086 +++++++++++++++++ 20241210001150-aoc_notes.org~ | 1085 ++++++++++++++++ 20241210001206-leetcode_notes.org | 17 + 20241210001206-leetcode_notes.org~ | 17 + 20241210004247-emacs_moc.org | 26 + 20241210004247-emacs_stuff.org | 26 + 20241210004247-emacs_stuff.org~ | 26 + 20241210004329-org_roam.org | 31 + 20241210004329-org_roam.org~ | 29 + 20241210004453-gtd.org | 7 + 20241210004453-gtd.org~ | 7 + 20241210012703-fyp.org | 27 + 20241210012703-fyp.org~ | 27 + 20241210152650-uni.org | 12 + 20241210152650-uni.org~ | 12 + 20241210152650-uni_moc.org | 12 + 20241210152713-tpis.org | 9 + 20241210152713-tpis.org~ | 9 + 20241210232054-uml_fyp.org | 708 +++++++++++ 20241210232054-uml_fyp.org~ | 708 +++++++++++ 20241210233721-brain.org~ | 34 + 20241210233721-brain_moc.org | 30 + 20241210233721-brain_moc.org~ | 32 + ...1161232- job_application_cover_letters.org | 269 ++++ 20241211161232-applications.org | 269 ++++ 20241211161232-applications.org~ | 269 ++++ 20241212011909-career_roam.org~ | 9 + 20241212013207-haskell_notes.org | 54 + 20241212013207-haskell_notes.org~ | 54 + 20241212013902-lazy_evaluation.org | 9 + 20241212013902-lazy_evaluation.org~ | 9 + 20241213005125-c_notes.org | 9 + 20241213005125-c_notes.org~ | 7 + 20241213005156-socket_programming_in_c.org | 31 + 20241213005156-socket_programming_in_c.org~ | 31 + 20241217234535-web_port_notes.org | 246 ++++ 20241217234535-web_port_notes.org~ | 205 ++++ 20241217234944-wp_emacs_config_blorg.org | 7 + 20241217234944-wp_emacs_config_blorg.org~ | 6 + 20241220234456-github_notes.org | 9 + 20241220234456-github_notes.org~ | 8 + 20241231172511-book_notes.org | 16 + 20241231172511-book_notes.org~ | 14 + ...1172543-the_science_of_self_discipline.org | 147 +++ ...172543-the_science_of_self_discipline.org~ | 147 +++ 20250111213016-wp_prefront_cortex_blog.org | 7 + 20250111213016-wp_prefront_cortex_blog.org~ | 6 + 20250120110833-afp.org | 11 + 20250120110833-afp.org~ | 11 + 20250120111047-afp_week1.org | 10 + 20250120111047-afp_week1.org~ | 10 + 20250120113936-afp-lab-1.org~ | 115 ++ 20250120113936-afp_lab_1.org | 115 ++ 20250121110241-afp-lec-1.org~ | 154 +++ 20250121110241-afp_lec_1.org | 154 +++ 20250128110828-afp_week2.org | 11 + 20250128110828-afp_week2.org~ | 9 + 20250128111008-afp_lec_2.org | 43 + 20250128111008-afp_lec_2.org~ | 43 + 20250213124335-i3_wm.org | 16 + 20250213124335-i3_wm.org~ | 16 + 20250214155617-wp_new_emacs_config_blorg.org | 130 ++ 20250214155617-wp_new_emacs_config_blorg.org~ | 129 ++ 20250218110239-afp_week5.org | 7 + 20250218110239-afp_week5.org~ | 7 + 20250218110346-af_wk5_lec1.org~ | 8 + 20250218110346-afp_lec_5.org | 9 + 20250218110346-afp_lec_5.org~ | 9 + 20250218174735-emacs_stuff_keybindings.org | 18 + 20250218174735-emacs_stuff_keybindings.org~ | 13 + 20250226184629-wp_urge_surfing_blorg.org | 69 ++ 20250226184629-wp_urge_surfing_blorg.org~ | 68 ++ 20250314223811-wp_growth_mindset.org | 86 ++ 20250314223811-wp_growth_mindset.org~ | 85 ++ 20250314230952-wp_emotional_intelligence.org | 95 ++ 20250314230952-wp_emotional_intelligence.org~ | 94 ++ 20250324041724-wp_week_12_reflections.org | 9 + 20250324041724-wp_week_12_reflections.org~ | 8 + 20250326002128-emacs_stuff_elisp.org | 82 ++ 20250326002128-emacs_stuff_elisp.org~ | 81 ++ 20250329114733-ise.org | 43 + 20250329114733-ise.org~ | 43 + 20250329114848-ise_week_1.org | 56 + 20250329114848-ise_week_1.org~ | 56 + 20250329121843-ise_week_2.org | 229 ++++ 20250329121843-ise_week_2.org~ | 229 ++++ 20250329142725-ise_week_3.org | 182 +++ 20250329142725-ise_week_3.org~ | 182 +++ 20250329200158-ise_week_4.org | 268 ++++ 20250329200158-ise_week_4.org~ | 268 ++++ 20250329231658-emacs_stuff_magit.org | 46 + 20250331201944-ise_week_5.org | 117 ++ 20250331201944-ise_week_5.org~ | 117 ++ 20250331202447-ise_week_7.org | 134 ++ 20250331202447-ise_week_7.org~ | 134 ++ 20250402185735-java_moc.org | 9 + 20250402185735-technical_java_notes.org | 9 + 20250402185735-technical_java_notes.org~ | 11 + 20250403120140-fyp_report_planning.org | 213 ++++ 20250403120140-fyp_report_planning.org~ | 213 ++++ 20250412234351-wp_sadness.org | 16 + 20250412234351-wp_sadness.org~ | 15 + 20250417173809-linux_moc.org | 11 + 20250417173809-linux_stuff.org | 12 + 20250417173809-linux_stuff.org~ | 11 + 20250417173821-wacom_notes.org | 50 + 20250417173821-wacom_notes.org~ | 50 + 20250420012258-emacs_stuff_evil.org | 35 + 20250420012258-emacs_stuff_evil.org~ | 33 + 20250428133236-systemd_services.org | 44 + 20250428133236-systemd_services.org~ | 44 + 20250430001952-microlise_assessment.org | 91 ++ 20250430001952-microlise_assessment.org~ | 90 ++ 20250516161728-gpg_encryption.org | 35 + 20250516161728-gpg_encryption.org~ | 34 + 20250703183239-linux_arch_linux.org | 16 + 20250703183239-linux_arch_linux.org~ | 10 + 20250715223949-the_clean_coder.html | 331 +++++ 20250715223949-the_clean_coder.org | 289 +++++ 20250715223949-the_clean_coder.org~ | 289 +++++ 20250717230336-recipes_main.org | 9 + 20250717230336-recipes_main.org~ | 9 + 20250717230336-recipes_moc.org | 9 + 20250719174944-recipes_ideas.org | 65 + 20250719174944-recipes_ideas.org~ | 64 + 20250719175023-recipes_done.org | 29 + 20250719175023-recipes_done.org~ | 29 + 20250722221649-career_index.org~ | 50 + 20250722221649-career_moc.org | 52 + 20250722221649-career_moc.org~ | 48 + 20250723171109-maven_pom_file.org | 69 ++ 20250723171109-maven_pom_file.org~ | 69 ++ 20250723182408-book_sgtciy.org~ | 5 + ...723182408-so-good-they-cant-ignore-you.org | 76 ++ ...23182408-so-good-they-cant-ignore-you.org~ | 76 ++ ...723182408-so_good_they_cant_ignore_you.org | 76 ++ 20250723183655-career_capital.org | 11 + 20250723183655-career_capital.org~ | 11 + 20250723183755-deliberate_practice.org | 12 + 20250723183755-deliberate_practice.org~ | 12 + 20250723184233-advanced_networking.org | 29 + 20250723184233-advanced_networking.org~ | 29 + ...184430-stanford_marshmallow_experiment.org | 16 + ...84430-stanford_marshmallow_experiment.org~ | 16 + 20250723185056-neuroplasticity.org | 11 + 20250723185056-neuroplasticity.org~ | 11 + 20250723185829-test_driven_development.org | 10 + 20250723185829-test_driven_development.org~ | 10 + 20250723185943-bowling_kata.org | 13 + 20250723185943-bowling_kata.org~ | 5 + 20250723190203-java_portswrigger_test.org | 648 ++++++++++ 20250723190203-java_portswrigger_test.org~ | 5 + 20250723190656-java_junit_testing.org | 7 + 20250723190656-java_junit_testing.org~ | 5 + 20250723190927-self_hosting.org | 9 + 20250723190927-self_hosting.org~ | 9 + 20250723200800-postgres.org | 64 + 20250724230557-books_org_agenda.org | 487 ++++++++ 20250724230557-books_org_agenda.org~ | 478 ++++++++ 20250727120306-nextcloud.org | 59 + 20250727120306-nextcloud.org~ | 5 + 20250727121051-networking_moc.org | 8 + 20250727122406-database_main.org~ | 7 + 20250727122406-database_moc.org | 7 + 20250727122406-database_moc.org~ | 7 + 20250727174809-books_main.org~ | 12 + 20250727174809-books_moc.org | 12 + 20250727174809-books_moc.org~ | 12 + 20250727174903-book_recs.org | 11 + 20250727174903-book_recs.org~ | 11 + 20250727221512-clean_code.org | 624 ++++++++++ 20250727221512-clean_code.org~ | 612 ++++++++++ 20250804201706-big_o_complexity.org | 115 ++ 20250804201706-big_o_complexity.org~ | 115 ++ 20250804212215-how_to_solve_leetcode.org | 21 + 20250804212215-how_to_solve_leetcode.org~ | 13 + 20250804212606-leetcode_arrays.org | 351 ++++++ 20250804212606-leetcode_arrays.org~ | 330 +++++ 20250804214537-python_set.org | 27 + 20250804214537-python_set.org~ | 22 + 20250805141906-python_dictionary.org | 99 ++ 20250805141906-python_dictionary.org~ | 63 + 20250805143427-python_sorted_function.org | 21 + 20250805143741-python_lambda.org | 36 + 20250805143741-python_lambda.org~ | 6 + 20250806111925-non_technical_moc.org | 8 + 20250806111925-non_technical_moc.org~ | 5 + 20250806155335-emacs_stuff_org_publish.org | 168 +++ 20250806155335-emacs_stuff_org_publish.org~ | 158 +++ 20250819174119-naqshe_hayat.org | 10 + 20250819174119-naqshe_hayat.org~ | 5 + 20250918120519-misc_moc.org | 9 + 20250918120519-misc_moc.org~ | 7 + 20250918120706-wedding_moc.org | 77 ++ 20250918120706-wedding_moc.org~ | 70 ++ 20250926151524-workflow_moc.org | 12 + 20250926151524-workflow_moc.org~ | 6 + 20251002154125-microlise_moc.org | 7 + 20251002154125-microlise_moc.org~ | 5 + 20251002154204-pre_work_prep_microlise.org | 27 + 20251002154204-pre_work_prep_microlise.org~ | 5 + 20251019114736-server_moc.org | 9 + 20251019114736-server_moc.org~ | 7 + 20251019114758-old_nextcloud_server_code.org | 71 ++ 20251019114758-old_nextcloud_server_code.org~ | 71 ++ 20251019114758-old_server_code.org~ | 71 ++ 20251101123637-backlog.org | 9 + 20251101123637-backlog.org~ | 5 + 20251109205925-old_nginx_code.org | 262 ++++ 20251109205925-old_nginx_code.org~ | 7 + 20251122223053-keyboard.org | 203 +++ 20251122223053-keyboard.org~ | 5 + 20251214210526-useful_c_imports.org | 7 + 20251214210526-useful_c_imports.org~ | 6 + assets/Big-O-Notation-3130482830.png | Bin 0 -> 237551 bytes assets/swappy-20250805-152411.png | Bin 0 -> 116505 bytes ...296884686849f0dd6a6f5f6e642ce4594a1438.png | Bin 0 -> 197 bytes ...6a4488b21e9c9fcc08a16156947f5bab6d2771.png | Bin 0 -> 587 bytes ...35aa584277b44dec02ac13aacd1cd7acc851be.png | Bin 0 -> 350 bytes ...860079d8dfebcc942c3e6b65b495a445d9f336.png | Bin 0 -> 180 bytes ...bbff043d0cc4a14caacd74ec795c0a1ec11f2e.png | Bin 0 -> 202 bytes ...6de057eb18f33d9ce2df46505051a77488698f.png | Bin 0 -> 210 bytes ...5d81a43ad57fe5da4c786cb565a1a6ab8bb626.png | Bin 0 -> 468 bytes ...5a7c14da0eed5a277bb96aa1c253b307e54b23.png | Bin 0 -> 587 bytes ...f0956210f41ec16057521ea641aa300fc99f1e.png | Bin 0 -> 324 bytes ...72905fd56b9a16fa7b45eb4b2b2e373d1e67d0.png | Bin 0 -> 197 bytes ...866fa9c245766194eeeb359244fd901090e1e2.png | Bin 0 -> 279 bytes ...1f8c91afecdbe530c1d7260ada3f1c5d3b744f.png | Bin 0 -> 418 bytes ...3ac398ecab748a277726f7718afae46fe8b82f.png | Bin 0 -> 173 bytes ...fa37ebf75968e3cae8fa02423eeef19f520817.png | Bin 0 -> 350 bytes ...f5f8555490fc64077127e29eef0dff2ac4422d.png | Bin 0 -> 178 bytes ...41651405214cbe515cff3fa73813164cedaf2d.png | Bin 0 -> 587 bytes ...130395ce5e5040f6604cb7c3cc1f55c8fc3cfa.png | Bin 0 -> 279 bytes ...26e5c1fa1d520353950d71af186956514e8701.png | Bin 0 -> 407 bytes ...5f0485ae2d07be9744e3e3723ecaf34f800012.png | Bin 0 -> 179 bytes ...dbc01f6593fc8d8a35c50f22f79f29a1dcf898.png | Bin 0 -> 209 bytes ...899afd78a059b0ae4bef408a695041cedb5ddd.png | Bin 0 -> 324 bytes ...25a163ba6edf4c7408c7f718f301a7150e4b11.png | Bin 0 -> 350 bytes ...7dd76637f98f808bbe2f69b2afd12e4c536ffb.png | Bin 0 -> 301 bytes ...a4db7f61fd148ce02f3fd143c05b54dbf2ca7f.png | Bin 0 -> 290 bytes ...a6befc0e7d8c06857316dc32fb3d6545f3e479.png | Bin 0 -> 290 bytes ...ec0d26a12708fe99cdd5876863ff43a1c627d7.png | Bin 0 -> 279 bytes ...4e482436a1dd4e34355f6ae5193641b99c4e3d.png | Bin 0 -> 290 bytes ...ff4f41cef3c8d6b7c75380b409a7fdd5ce36b9.png | Bin 0 -> 210 bytes ...5319670cdf886edbfb7200e6b4dab22965b101.png | Bin 0 -> 407 bytes ...b88f8eb4efd76fc90d4bd25d1ed1b7dd7a5be0.png | Bin 0 -> 407 bytes ...34d39b4a163d0e868354be903873bcc6d09644.png | Bin 0 -> 167 bytes ...6f0fcce4798bef7b2a672a7a2489381b89c772.png | Bin 0 -> 167 bytes ...8b7f9ba4927f1b464c9524a68d0a691854379f.png | Bin 0 -> 210 bytes ...68c360146b207a04126a214f96cd65cc970c51.png | Bin 0 -> 243 bytes ...30ab391bb9b6d4b8ba2c1db82d8eaa789b83b1.png | Bin 0 -> 407 bytes ...690ed0b5aa1efd8594d7c9747276cb01e148b9.png | Bin 0 -> 268 bytes ...a5e90acb8406cda2b0a9e46f45738e7fc64394.png | Bin 0 -> 202 bytes ...3ebf35ab016a6c7144cc6250d8f0e85d777ce6.png | Bin 0 -> 236 bytes ...20bec73c3091c2b13083536db1bc184965ef8a.png | Bin 0 -> 279 bytes ...950c1e472fa38df910785f36c1570a75291377.png | Bin 0 -> 221 bytes ...06c0d84a3df817d72c9bfc9d1bed3d99b83308.png | Bin 0 -> 190 bytes ...bb0e35c6ebe236afab1ca47229361e22b4e241.png | Bin 0 -> 587 bytes ...110cbc92e7c6401dba8b38185aaa1d97011b52.png | Bin 0 -> 202 bytes ...1b4d45bde34f58aaec819408c75071c356821b.png | Bin 0 -> 202 bytes ...200c4e7dce25a1e27e01e1ae86f4105c2fa2dc.png | Bin 0 -> 210 bytes ...2b1f9a19d301ad86f57d82beb069e849b679fd.png | Bin 0 -> 324 bytes ...453e7c12347acad1700f56cd2cb7a7438e0c11.png | Bin 0 -> 167 bytes ...bbbd9603cb09800c1ce9bd9e87995d7c609b1d.png | Bin 0 -> 200 bytes ...f166f42dcd147a8e21383c5aed428f30ca0144.png | Bin 0 -> 181 bytes ...02e6245b6185abae501586409d2f30fc5fa61b.png | Bin 0 -> 167 bytes ...9ee8e3dc18ceac67ab9b63fe21ea4ed4c0e563.png | Bin 0 -> 350 bytes ...ec4e7d4520ebfff12e08231870330d66e166cc.png | Bin 0 -> 468 bytes ...56e3330a950cdef271d8c83a94b334a11a8837.png | Bin 0 -> 290 bytes ...2f698fcba37b4bb5ca9e15873f9f205ca53b99.png | Bin 0 -> 287 bytes ...d27eaf08385a5653d47c5353e882fec619834d.png | Bin 0 -> 324 bytes ...3730ba461b03f192d1c5d7adf2c8ea141ef862.png | Bin 0 -> 202 bytes ...dc76bce6183940e7887fa7869970cce9c992e4.png | Bin 0 -> 468 bytes ...41743fe73d4f222f6c40f99ee4bb426882a0db.png | Bin 0 -> 468 bytes 281 files changed, 18445 insertions(+) create mode 100644 #20251122223053-keyboard.org# create mode 100644 .DS_Store create mode 100644 .markdown-preview.html create mode 100644 20241210001045-technical.org create mode 100644 20241210001045-technical.org~ create mode 100755 20241210001045-technical_coding.org~ create mode 100755 20241210001045-technical_moc.org create mode 100755 20241210001150-aoc_notes.org create mode 100755 20241210001150-aoc_notes.org~ create mode 100755 20241210001206-leetcode_notes.org create mode 100755 20241210001206-leetcode_notes.org~ create mode 100755 20241210004247-emacs_moc.org create mode 100644 20241210004247-emacs_stuff.org create mode 100644 20241210004247-emacs_stuff.org~ create mode 100755 20241210004329-org_roam.org create mode 100755 20241210004329-org_roam.org~ create mode 100755 20241210004453-gtd.org create mode 100755 20241210004453-gtd.org~ create mode 100755 20241210012703-fyp.org create mode 100755 20241210012703-fyp.org~ create mode 100644 20241210152650-uni.org create mode 100644 20241210152650-uni.org~ create mode 100755 20241210152650-uni_moc.org create mode 100755 20241210152713-tpis.org create mode 100755 20241210152713-tpis.org~ create mode 100755 20241210232054-uml_fyp.org create mode 100755 20241210232054-uml_fyp.org~ create mode 100755 20241210233721-brain.org~ create mode 100755 20241210233721-brain_moc.org create mode 100755 20241210233721-brain_moc.org~ create mode 100755 20241211161232- job_application_cover_letters.org create mode 100644 20241211161232-applications.org create mode 100755 20241211161232-applications.org~ create mode 100755 20241212011909-career_roam.org~ create mode 100755 20241212013207-haskell_notes.org create mode 100755 20241212013207-haskell_notes.org~ create mode 100755 20241212013902-lazy_evaluation.org create mode 100755 20241212013902-lazy_evaluation.org~ create mode 100755 20241213005125-c_notes.org create mode 100755 20241213005125-c_notes.org~ create mode 100755 20241213005156-socket_programming_in_c.org create mode 100755 20241213005156-socket_programming_in_c.org~ create mode 100755 20241217234535-web_port_notes.org create mode 100755 20241217234535-web_port_notes.org~ create mode 100755 20241217234944-wp_emacs_config_blorg.org create mode 100755 20241217234944-wp_emacs_config_blorg.org~ create mode 100755 20241220234456-github_notes.org create mode 100755 20241220234456-github_notes.org~ create mode 100755 20241231172511-book_notes.org create mode 100755 20241231172511-book_notes.org~ create mode 100755 20241231172543-the_science_of_self_discipline.org create mode 100755 20241231172543-the_science_of_self_discipline.org~ create mode 100755 20250111213016-wp_prefront_cortex_blog.org create mode 100755 20250111213016-wp_prefront_cortex_blog.org~ create mode 100755 20250120110833-afp.org create mode 100755 20250120110833-afp.org~ create mode 100755 20250120111047-afp_week1.org create mode 100755 20250120111047-afp_week1.org~ create mode 100755 20250120113936-afp-lab-1.org~ create mode 100755 20250120113936-afp_lab_1.org create mode 100755 20250121110241-afp-lec-1.org~ create mode 100755 20250121110241-afp_lec_1.org create mode 100755 20250128110828-afp_week2.org create mode 100755 20250128110828-afp_week2.org~ create mode 100644 20250128111008-afp_lec_2.org create mode 100644 20250128111008-afp_lec_2.org~ create mode 100644 20250213124335-i3_wm.org create mode 100644 20250213124335-i3_wm.org~ create mode 100644 20250214155617-wp_new_emacs_config_blorg.org create mode 100644 20250214155617-wp_new_emacs_config_blorg.org~ create mode 100644 20250218110239-afp_week5.org create mode 100644 20250218110239-afp_week5.org~ create mode 100644 20250218110346-af_wk5_lec1.org~ create mode 100644 20250218110346-afp_lec_5.org create mode 100644 20250218110346-afp_lec_5.org~ create mode 100644 20250218174735-emacs_stuff_keybindings.org create mode 100644 20250218174735-emacs_stuff_keybindings.org~ create mode 100644 20250226184629-wp_urge_surfing_blorg.org create mode 100644 20250226184629-wp_urge_surfing_blorg.org~ create mode 100644 20250314223811-wp_growth_mindset.org create mode 100644 20250314223811-wp_growth_mindset.org~ create mode 100644 20250314230952-wp_emotional_intelligence.org create mode 100644 20250314230952-wp_emotional_intelligence.org~ create mode 100644 20250324041724-wp_week_12_reflections.org create mode 100644 20250324041724-wp_week_12_reflections.org~ create mode 100644 20250326002128-emacs_stuff_elisp.org create mode 100644 20250326002128-emacs_stuff_elisp.org~ create mode 100644 20250329114733-ise.org create mode 100644 20250329114733-ise.org~ create mode 100644 20250329114848-ise_week_1.org create mode 100644 20250329114848-ise_week_1.org~ create mode 100644 20250329121843-ise_week_2.org create mode 100644 20250329121843-ise_week_2.org~ create mode 100644 20250329142725-ise_week_3.org create mode 100644 20250329142725-ise_week_3.org~ create mode 100644 20250329200158-ise_week_4.org create mode 100644 20250329200158-ise_week_4.org~ create mode 100644 20250329231658-emacs_stuff_magit.org create mode 100644 20250331201944-ise_week_5.org create mode 100644 20250331201944-ise_week_5.org~ create mode 100644 20250331202447-ise_week_7.org create mode 100644 20250331202447-ise_week_7.org~ create mode 100644 20250402185735-java_moc.org create mode 100644 20250402185735-technical_java_notes.org create mode 100644 20250402185735-technical_java_notes.org~ create mode 100644 20250403120140-fyp_report_planning.org create mode 100644 20250403120140-fyp_report_planning.org~ create mode 100644 20250412234351-wp_sadness.org create mode 100644 20250412234351-wp_sadness.org~ create mode 100644 20250417173809-linux_moc.org create mode 100644 20250417173809-linux_stuff.org create mode 100644 20250417173809-linux_stuff.org~ create mode 100644 20250417173821-wacom_notes.org create mode 100644 20250417173821-wacom_notes.org~ create mode 100644 20250420012258-emacs_stuff_evil.org create mode 100644 20250420012258-emacs_stuff_evil.org~ create mode 100644 20250428133236-systemd_services.org create mode 100644 20250428133236-systemd_services.org~ create mode 100644 20250430001952-microlise_assessment.org create mode 100644 20250430001952-microlise_assessment.org~ create mode 100644 20250516161728-gpg_encryption.org create mode 100644 20250516161728-gpg_encryption.org~ create mode 100644 20250703183239-linux_arch_linux.org create mode 100644 20250703183239-linux_arch_linux.org~ create mode 100644 20250715223949-the_clean_coder.html create mode 100644 20250715223949-the_clean_coder.org create mode 100644 20250715223949-the_clean_coder.org~ create mode 100644 20250717230336-recipes_main.org create mode 100644 20250717230336-recipes_main.org~ create mode 100644 20250717230336-recipes_moc.org create mode 100644 20250719174944-recipes_ideas.org create mode 100644 20250719174944-recipes_ideas.org~ create mode 100644 20250719175023-recipes_done.org create mode 100644 20250719175023-recipes_done.org~ create mode 100644 20250722221649-career_index.org~ create mode 100644 20250722221649-career_moc.org create mode 100644 20250722221649-career_moc.org~ create mode 100644 20250723171109-maven_pom_file.org create mode 100644 20250723171109-maven_pom_file.org~ create mode 100644 20250723182408-book_sgtciy.org~ create mode 100644 20250723182408-so-good-they-cant-ignore-you.org create mode 100644 20250723182408-so-good-they-cant-ignore-you.org~ create mode 100644 20250723182408-so_good_they_cant_ignore_you.org create mode 100644 20250723183655-career_capital.org create mode 100644 20250723183655-career_capital.org~ create mode 100644 20250723183755-deliberate_practice.org create mode 100644 20250723183755-deliberate_practice.org~ create mode 100644 20250723184233-advanced_networking.org create mode 100644 20250723184233-advanced_networking.org~ create mode 100644 20250723184430-stanford_marshmallow_experiment.org create mode 100644 20250723184430-stanford_marshmallow_experiment.org~ create mode 100644 20250723185056-neuroplasticity.org create mode 100644 20250723185056-neuroplasticity.org~ create mode 100644 20250723185829-test_driven_development.org create mode 100644 20250723185829-test_driven_development.org~ create mode 100644 20250723185943-bowling_kata.org create mode 100644 20250723185943-bowling_kata.org~ create mode 100644 20250723190203-java_portswrigger_test.org create mode 100644 20250723190203-java_portswrigger_test.org~ create mode 100644 20250723190656-java_junit_testing.org create mode 100644 20250723190656-java_junit_testing.org~ create mode 100644 20250723190927-self_hosting.org create mode 100644 20250723190927-self_hosting.org~ create mode 100644 20250723200800-postgres.org create mode 100644 20250724230557-books_org_agenda.org create mode 100644 20250724230557-books_org_agenda.org~ create mode 100644 20250727120306-nextcloud.org create mode 100644 20250727120306-nextcloud.org~ create mode 100644 20250727121051-networking_moc.org create mode 100644 20250727122406-database_main.org~ create mode 100644 20250727122406-database_moc.org create mode 100644 20250727122406-database_moc.org~ create mode 100644 20250727174809-books_main.org~ create mode 100644 20250727174809-books_moc.org create mode 100644 20250727174809-books_moc.org~ create mode 100644 20250727174903-book_recs.org create mode 100644 20250727174903-book_recs.org~ create mode 100644 20250727221512-clean_code.org create mode 100644 20250727221512-clean_code.org~ create mode 100644 20250804201706-big_o_complexity.org create mode 100644 20250804201706-big_o_complexity.org~ create mode 100644 20250804212215-how_to_solve_leetcode.org create mode 100644 20250804212215-how_to_solve_leetcode.org~ create mode 100644 20250804212606-leetcode_arrays.org create mode 100644 20250804212606-leetcode_arrays.org~ create mode 100644 20250804214537-python_set.org create mode 100644 20250804214537-python_set.org~ create mode 100644 20250805141906-python_dictionary.org create mode 100644 20250805141906-python_dictionary.org~ create mode 100644 20250805143427-python_sorted_function.org create mode 100644 20250805143741-python_lambda.org create mode 100644 20250805143741-python_lambda.org~ create mode 100644 20250806111925-non_technical_moc.org create mode 100644 20250806111925-non_technical_moc.org~ create mode 100644 20250806155335-emacs_stuff_org_publish.org create mode 100644 20250806155335-emacs_stuff_org_publish.org~ create mode 100644 20250819174119-naqshe_hayat.org create mode 100644 20250819174119-naqshe_hayat.org~ create mode 100644 20250918120519-misc_moc.org create mode 100644 20250918120519-misc_moc.org~ create mode 100644 20250918120706-wedding_moc.org create mode 100644 20250918120706-wedding_moc.org~ create mode 100644 20250926151524-workflow_moc.org create mode 100644 20250926151524-workflow_moc.org~ create mode 100644 20251002154125-microlise_moc.org create mode 100644 20251002154125-microlise_moc.org~ create mode 100644 20251002154204-pre_work_prep_microlise.org create mode 100644 20251002154204-pre_work_prep_microlise.org~ create mode 100644 20251019114736-server_moc.org create mode 100644 20251019114736-server_moc.org~ create mode 100644 20251019114758-old_nextcloud_server_code.org create mode 100644 20251019114758-old_nextcloud_server_code.org~ create mode 100644 20251019114758-old_server_code.org~ create mode 100644 20251101123637-backlog.org create mode 100644 20251101123637-backlog.org~ create mode 100644 20251109205925-old_nginx_code.org create mode 100644 20251109205925-old_nginx_code.org~ create mode 100644 20251122223053-keyboard.org create mode 100644 20251122223053-keyboard.org~ create mode 100644 20251214210526-useful_c_imports.org create mode 100644 20251214210526-useful_c_imports.org~ create mode 100644 assets/Big-O-Notation-3130482830.png create mode 100644 assets/swappy-20250805-152411.png create mode 100644 ltximg/org-ltximg_01296884686849f0dd6a6f5f6e642ce4594a1438.png create mode 100644 ltximg/org-ltximg_066a4488b21e9c9fcc08a16156947f5bab6d2771.png create mode 100644 ltximg/org-ltximg_0c35aa584277b44dec02ac13aacd1cd7acc851be.png create mode 100644 ltximg/org-ltximg_11860079d8dfebcc942c3e6b65b495a445d9f336.png create mode 100644 ltximg/org-ltximg_1cbbff043d0cc4a14caacd74ec795c0a1ec11f2e.png create mode 100644 ltximg/org-ltximg_1d6de057eb18f33d9ce2df46505051a77488698f.png create mode 100644 ltximg/org-ltximg_205d81a43ad57fe5da4c786cb565a1a6ab8bb626.png create mode 100644 ltximg/org-ltximg_265a7c14da0eed5a277bb96aa1c253b307e54b23.png create mode 100644 ltximg/org-ltximg_26f0956210f41ec16057521ea641aa300fc99f1e.png create mode 100644 ltximg/org-ltximg_2d72905fd56b9a16fa7b45eb4b2b2e373d1e67d0.png create mode 100644 ltximg/org-ltximg_32866fa9c245766194eeeb359244fd901090e1e2.png create mode 100644 ltximg/org-ltximg_3a1f8c91afecdbe530c1d7260ada3f1c5d3b744f.png create mode 100644 ltximg/org-ltximg_3e3ac398ecab748a277726f7718afae46fe8b82f.png create mode 100644 ltximg/org-ltximg_40fa37ebf75968e3cae8fa02423eeef19f520817.png create mode 100644 ltximg/org-ltximg_44f5f8555490fc64077127e29eef0dff2ac4422d.png create mode 100644 ltximg/org-ltximg_4741651405214cbe515cff3fa73813164cedaf2d.png create mode 100644 ltximg/org-ltximg_55130395ce5e5040f6604cb7c3cc1f55c8fc3cfa.png create mode 100644 ltximg/org-ltximg_6026e5c1fa1d520353950d71af186956514e8701.png create mode 100644 ltximg/org-ltximg_635f0485ae2d07be9744e3e3723ecaf34f800012.png create mode 100644 ltximg/org-ltximg_63dbc01f6593fc8d8a35c50f22f79f29a1dcf898.png create mode 100644 ltximg/org-ltximg_6c899afd78a059b0ae4bef408a695041cedb5ddd.png create mode 100644 ltximg/org-ltximg_7425a163ba6edf4c7408c7f718f301a7150e4b11.png create mode 100644 ltximg/org-ltximg_777dd76637f98f808bbe2f69b2afd12e4c536ffb.png create mode 100644 ltximg/org-ltximg_7ca4db7f61fd148ce02f3fd143c05b54dbf2ca7f.png create mode 100644 ltximg/org-ltximg_81a6befc0e7d8c06857316dc32fb3d6545f3e479.png create mode 100644 ltximg/org-ltximg_8aec0d26a12708fe99cdd5876863ff43a1c627d7.png create mode 100644 ltximg/org-ltximg_8c4e482436a1dd4e34355f6ae5193641b99c4e3d.png create mode 100644 ltximg/org-ltximg_91ff4f41cef3c8d6b7c75380b409a7fdd5ce36b9.png create mode 100644 ltximg/org-ltximg_925319670cdf886edbfb7200e6b4dab22965b101.png create mode 100644 ltximg/org-ltximg_93b88f8eb4efd76fc90d4bd25d1ed1b7dd7a5be0.png create mode 100644 ltximg/org-ltximg_9f34d39b4a163d0e868354be903873bcc6d09644.png create mode 100644 ltximg/org-ltximg_a16f0fcce4798bef7b2a672a7a2489381b89c772.png create mode 100644 ltximg/org-ltximg_a38b7f9ba4927f1b464c9524a68d0a691854379f.png create mode 100644 ltximg/org-ltximg_a568c360146b207a04126a214f96cd65cc970c51.png create mode 100644 ltximg/org-ltximg_b430ab391bb9b6d4b8ba2c1db82d8eaa789b83b1.png create mode 100644 ltximg/org-ltximg_b8690ed0b5aa1efd8594d7c9747276cb01e148b9.png create mode 100644 ltximg/org-ltximg_b9a5e90acb8406cda2b0a9e46f45738e7fc64394.png create mode 100644 ltximg/org-ltximg_bc3ebf35ab016a6c7144cc6250d8f0e85d777ce6.png create mode 100644 ltximg/org-ltximg_be20bec73c3091c2b13083536db1bc184965ef8a.png create mode 100644 ltximg/org-ltximg_bf950c1e472fa38df910785f36c1570a75291377.png create mode 100644 ltximg/org-ltximg_c206c0d84a3df817d72c9bfc9d1bed3d99b83308.png create mode 100644 ltximg/org-ltximg_c3bb0e35c6ebe236afab1ca47229361e22b4e241.png create mode 100644 ltximg/org-ltximg_c8110cbc92e7c6401dba8b38185aaa1d97011b52.png create mode 100644 ltximg/org-ltximg_c91b4d45bde34f58aaec819408c75071c356821b.png create mode 100644 ltximg/org-ltximg_c9200c4e7dce25a1e27e01e1ae86f4105c2fa2dc.png create mode 100644 ltximg/org-ltximg_c92b1f9a19d301ad86f57d82beb069e849b679fd.png create mode 100644 ltximg/org-ltximg_cb453e7c12347acad1700f56cd2cb7a7438e0c11.png create mode 100644 ltximg/org-ltximg_cbbbbd9603cb09800c1ce9bd9e87995d7c609b1d.png create mode 100644 ltximg/org-ltximg_cbf166f42dcd147a8e21383c5aed428f30ca0144.png create mode 100644 ltximg/org-ltximg_cc02e6245b6185abae501586409d2f30fc5fa61b.png create mode 100644 ltximg/org-ltximg_cc9ee8e3dc18ceac67ab9b63fe21ea4ed4c0e563.png create mode 100644 ltximg/org-ltximg_cfec4e7d4520ebfff12e08231870330d66e166cc.png create mode 100644 ltximg/org-ltximg_d856e3330a950cdef271d8c83a94b334a11a8837.png create mode 100644 ltximg/org-ltximg_df2f698fcba37b4bb5ca9e15873f9f205ca53b99.png create mode 100644 ltximg/org-ltximg_e4d27eaf08385a5653d47c5353e882fec619834d.png create mode 100644 ltximg/org-ltximg_e53730ba461b03f192d1c5d7adf2c8ea141ef862.png create mode 100644 ltximg/org-ltximg_eddc76bce6183940e7887fa7869970cce9c992e4.png create mode 100644 ltximg/org-ltximg_f341743fe73d4f222f6c40f99ee4bb426882a0db.png diff --git a/#20251122223053-keyboard.org# b/#20251122223053-keyboard.org# new file mode 100644 index 0000000..00dc4c1 --- /dev/null +++ b/#20251122223053-keyboard.org# @@ -0,0 +1,166 @@ +:PROPERTIES: +:ID: 0217f537-442a-4593-8c69-d481f0d1f2a8 +:END: +#+title: keyboard +#+filetags: :hardware:linux: + +This all comes from the fact that a “key press” isn’t one thing — it’s a stack of specs and translations from **keyboard hardware → USB/HID → Linux kernel → userspace (XKB/Wayland) → Hyprland binds**. + +Here are some structured notes you can keep / refer back to 👇 + +--- + +## 1. Big picture: what happens when you press a key? + +When you hit a key (like your “lock” key), roughly this happens: + +```text +Physical switch on keyboard + ↓ +Keyboard firmware → USB HID "usage" (e.g. 0x07:0xE3 = Left GUI) + ↓ +Linux kernel input subsystem (evdev) → KEY_LEFTMETA (code 125) + ↓ +libinput / xkbcommon → keysyms (like Super_L, L, etc.) + ↓ +Hyprland → your `bind = SUPER, L, exec, ...` +``` + +The “topic” we’ve been poking at is basically **understanding each layer in that stack**. + +--- + +## 2. USB HID: where `700e3` comes from + +Modern USB keyboards follow the **USB HID (Human Interface Device) specification**. +This spec defines **Usage Tables**: numerical codes for things like keys, buttons, axes, etc. + +* The keyboard page is **Usage Page 0x07 (Keyboard/Keypad)**. +* In your `evtest` output, `MSC_SCAN value 700e3` means: + + * `0x07` (Keyboard page) + * `0xE3` (Left GUI / “Windows/Super” key) + +You can see the official tables here (PDF): + +* **HID Usage Tables (includes Keyboard/Keypad page 0x07)** + [https://usb.org/sites/default/files/hut1_21.pdf](https://usb.org/sites/default/files/hut1_21.pdf) ([USB Implementers Forum][1]) + +If you scroll to the **Keyboard/Keypad Page (0x07)** section, it lists all the key usages: A, B, C, modifiers, function keys, etc. There’s also a standalone Keyboard/Keypad-page extract people mirror, like this PDF snippet: ([d1.amobbs.com][2]) + +So: + +* `700e3` = Page `0x07`, Usage `0xE3` → *Keyboard Left GUI* +* `7000f` = Page `0x07`, Usage `0x0F` → *Keyboard L* key + +That’s how we knew your lock key was sending **Super + L**. + +--- + +## 3. Linux input subsystem: `EV_MSC`, `EV_KEY`, `KEY_LEFTMETA` + +Linux has a dedicated **input subsystem** in the kernel (`drivers/input`, `drivers/hid` etc.) that takes those HID usages and turns them into a unified stream of **input events**. ([Linux Kernel Documentation][3]) + +Key ideas: + +* Devices expose `/dev/input/eventX` nodes. +* Each event is a struct with: + + * `type` (e.g. `EV_KEY`, `EV_MSC`, `EV_REL`, `EV_SYN`) + * `code` (e.g. `KEY_L`, `KEY_LEFTMETA`) + * `value` (pressed = 1, released = 0, repeat = 2) + +Docs worth bookmarking: + +* **Linux input subsystem overview** + [https://docs.kernel.org/input/input.html](https://docs.kernel.org/input/input.html) ([Linux Kernel Documentation][3]) + +* **Input event types and codes (`event-codes.txt`)** + [https://www.kernel.org/doc/Documentation/input/event-codes.txt](https://www.kernel.org/doc/Documentation/input/event-codes.txt) ([Kernel.org][4]) + +The **keycode definitions** (`KEY_L`, `KEY_LEFTMETA`, etc.) live in: + +* `include/uapi/linux/input-event-codes.h` in the kernel source + Example mirror: + [https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/input-event-codes.h](https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/input-event-codes.h) ([GitHub][5]) + +When `evtest` prints: + +```text +type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e3 +type 1 (EV_KEY), code 125 (KEY_LEFTMETA), value 0 +``` + +that means: + +* `EV_MSC / MSC_SCAN` → “Here is the raw hardware scancode” (from USB HID). +* `EV_KEY / KEY_LEFTMETA` → “Linux mapped that scancode to logical key LEFTMETA”. + + +## 4. XKB / xkbcommon: mapping to actual characters & modifiers + +Above the kernel, you’ve got an extra mapping layer that says: + +> For keycode N, with this layout, when Shift is held, produce this character/symbol. + +On X11 this is handled by **XKB (X Keyboard Extension)**; on Wayland compositors (including Hyprland) the same ideas are implemented via **xkbcommon**. + +Docs: + +* **X Keyboard Extension (XKB) protocol spec** + [https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html](https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html) ([X.Org][6]) + +* **Arch Wiki: X keyboard extension** (good high-level intro) + [https://wiki.archlinux.org/title/X_keyboard_extension](https://wiki.archlinux.org/title/X_keyboard_extension) ([ArchWiki][7]) + +* A nice “practical” walkthrough of XKB concepts: + [https://medium.com/@damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450](https://medium.com/@damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450) ([Medium][8]) + +Hyprland, Sway, etc. all use libinput + xkbcommon under the hood to interpret those keycodes and translate them into keysyms and modifiers. + +--- + +## 5. Hyprland / your config: where the bindings fit in + +Hyprland sits at the top of this stack: + +* It listens to the input events (via libinput). +* It sees keysyms/modifiers (e.g. `Super`, `L`). +* It matches them against your config: + +```ini +bind = SUPER, L, exec, hyprlock +``` + +So your keyboard’s “lock” key: + +1. Firmware sends HID usages `0xE3` (Left GUI) and `0x0F` (L). +2. Linux maps them to `KEY_LEFTMETA` (125) and `KEY_L` (38). +3. xkbcommon maps that to `Super` + `L`. +4. Hyprland says: “Ah, SUPER+L → run `hyprlock`”. + +The “topic” you stumbled into is just **peeling back each abstraction layer**. + +## 6. Handy tools & libraries if you want to go deeper + +* `evtest`, `libinput debug-events`, `showkey` + → To watch what your keyboard is actually sending. + +* **Python-evdev** – Python bindings to read `/dev/input/event*` yourself: + [https://python-evdev.readthedocs.io/](https://python-evdev.readthedocs.io/) ([python-evdev.readthedocs.io][9]) + +* Linux input subsystem docs again: + [https://docs.kernel.org/driver-api/input.html](https://docs.kernel.org/driver-api/input.html) ([Linux Kernel Documentation][10]) + +--- + +[1]: https://usb.org/sites/default/files/hut1_21.pdf?utm_source=chatgpt.com "HID Usage Tables" +[2]: https://d1.amobbs.com/bbs_upload782111/files_47/ourdev_692986N5FAHU.pdf?utm_source=chatgpt.com "10 Keyboard/Keypad Page (0x07)" +[3]: https://docs.kernel.org/input/input.html?utm_source=chatgpt.com "1. Introduction — The Linux Kernel documentation" +[4]: https://www.kernel.org/doc/Documentation/input/event-codes.txt?utm_source=chatgpt.com "event-codes.txt" +[5]: https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/input-event-codes.h?utm_source=chatgpt.com "Input event codes - GitHub" +[6]: https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html?utm_source=chatgpt.com "The X Keyboard Extension: Protocol Specification" +[7]: https://wiki.archlinux.org/title/X_keyboard_extension?utm_source=chatgpt.com "X keyboard extension" +[8]: https://medium.com/%40damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450?utm_source=chatgpt.com "A simple, humble but comprehensive guide to XKB for linux" +[9]: https://python-evdev.readthedocs.io/?utm_source=chatgpt.com "Introduction — Python-evdev - Read the Docs" +[10]: https://docs.kernel.org/driver-api/input.html?utm_source=chatgpt.com "Input Subsystem" diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..4b874585bec4c5c2bc345a1840cf283f8cf45a53 GIT binary patch literal 24580 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 literal 0 HcmV?d00001 diff --git a/.markdown-preview.html b/.markdown-preview.html new file mode 100644 index 0000000..b2c4760 --- /dev/null +++ b/.markdown-preview.html @@ -0,0 +1,43 @@ + + + + + + Markdown preview + + + + + + +
+

Markdown preview

+
+ + diff --git a/20241210001045-technical.org b/20241210001045-technical.org new file mode 100644 index 0000000..5ac1d0c --- /dev/null +++ b/20241210001045-technical.org @@ -0,0 +1,20 @@ +:PROPERTIES: +:ID: 2f285f04-fcf4-4ade-a1ac-2c50b43d529a +:END: +#+title: technical_moc +#+filetags: :moc: + +In this file I want to include technical information (things related to programming, coding and networking etc): + +- [[id:e7f2302b-16eb-476d-a7b9-be12f077819d][AOC Notes]] +- [[id:348df473-6443-4f4a-b366-95397b574989][web-port-notes]] +- [[id:710f65e5-0bd4-42be-b5d1-69dbe79b745e][github-notes]] +- [[id:bdb493df-db92-4c93-9558-0b10fdff3048][linux_moc]] +- [[id:e448cd99-afee-4702-947f-644bb34dc1aa][database_moc]] +- [[id:8fa3f476-6152-45f4-b618-50f1e4bce46c][emacs_moc]] +- [[id:0880f089-a5ad-49cd-8ce3-f020a5941313][networking-moc]] +- [[id:9d1cfccc-8da7-41a3-b435-9857f0abe441][leetcode_notes]] +- [[id:347d2663-515b-4d9a-9ee9-7706ee86a845][haskell_notes]] +- [[id:5a207a1c-6f02-40d5-b42e-38daaa0aec10][c_notes]] +- [[id:ae343652-96fe-4341-8a36-ec3a1abd0dc6][java_moc]] +- [[id:f09cb4ed-1407-4187-9002-de2c5db13a8f][server_moc]] diff --git a/20241210001045-technical.org~ b/20241210001045-technical.org~ new file mode 100644 index 0000000..d5bd542 --- /dev/null +++ b/20241210001045-technical.org~ @@ -0,0 +1,19 @@ +:PROPERTIES: +:ID: 2f285f04-fcf4-4ade-a1ac-2c50b43d529a +:END: +#+title: technical_moc +#+filetags: :moc: + +In this file I want to include technical information (things related to programming, coding and networking etc): + +- [[id:e7f2302b-16eb-476d-a7b9-be12f077819d][AOC Notes]] +- [[id:348df473-6443-4f4a-b366-95397b574989][web-port-notes]] +- [[id:710f65e5-0bd4-42be-b5d1-69dbe79b745e][github-notes]] +- [[id:bdb493df-db92-4c93-9558-0b10fdff3048][linux_moc]] +- [[id:e448cd99-afee-4702-947f-644bb34dc1aa][database_moc]] +- [[id:8fa3f476-6152-45f4-b618-50f1e4bce46c][emacs_moc]] +- [[id:0880f089-a5ad-49cd-8ce3-f020a5941313][networking-moc]] +- [[id:9d1cfccc-8da7-41a3-b435-9857f0abe441][leetcode_notes]] +- [[id:347d2663-515b-4d9a-9ee9-7706ee86a845][haskell_notes]] +- [[id:5a207a1c-6f02-40d5-b42e-38daaa0aec10][c_notes]] +- [[id:ae343652-96fe-4341-8a36-ec3a1abd0dc6][java_moc]] diff --git a/20241210001045-technical_coding.org~ b/20241210001045-technical_coding.org~ new file mode 100755 index 0000000..382be7d --- /dev/null +++ b/20241210001045-technical_coding.org~ @@ -0,0 +1,15 @@ +:PROPERTIES: +:ID: 2f285f04-fcf4-4ade-a1ac-2c50b43d529a +:END: +#+title: Technical Coding +#+filetags: :coding:notes:technical:index: + +In this file I want to include technical coding information. This will include things I've learnt from solving: +- [[id:9d1cfccc-8da7-41a3-b435-9857f0abe441][Leetcode Notes]] +- [[id:e7f2302b-16eb-476d-a7b9-be12f077819d][AOC Notes]] +- [[id:347d2663-515b-4d9a-9ee9-7706ee86a845][Haskell Notes]] +- [[id:5a207a1c-6f02-40d5-b42e-38daaa0aec10][C Notes]] +- [[id:348df473-6443-4f4a-b366-95397b574989][web-port-notes]] +- [[id:710f65e5-0bd4-42be-b5d1-69dbe79b745e][github-notes]] +- [[id:ae343652-96fe-4341-8a36-ec3a1abd0dc6][technical-java-notes]] +- diff --git a/20241210001045-technical_moc.org b/20241210001045-technical_moc.org new file mode 100755 index 0000000..0a69046 --- /dev/null +++ b/20241210001045-technical_moc.org @@ -0,0 +1,16 @@ +:PROPERTIES: +:ID: 2f285f04-fcf4-4ade-a1ac-2c50b43d529a +:END: +#+title: technical_moc +#+filetags: :coding:notes:technical:index: + +In this file I want to include technical coding information. This will include things I've learnt from solving: +- [[id:9d1cfccc-8da7-41a3-b435-9857f0abe441][Leetcode Notes]] +- [[id:e7f2302b-16eb-476d-a7b9-be12f077819d][AOC Notes]] +- [[id:347d2663-515b-4d9a-9ee9-7706ee86a845][Haskell Notes]] +- [[id:5a207a1c-6f02-40d5-b42e-38daaa0aec10][C Notes]] +- [[id:348df473-6443-4f4a-b366-95397b574989][web-port-notes]] +- [[id:710f65e5-0bd4-42be-b5d1-69dbe79b745e][github-notes]] +- [[id:ae343652-96fe-4341-8a36-ec3a1abd0dc6][technical-java-notes]] +- [[id:bdb493df-db92-4c93-9558-0b10fdff3048][linux_moc]] +- [[id:e448cd99-afee-4702-947f-644bb34dc1aa][database_moc]] diff --git a/20241210001150-aoc_notes.org b/20241210001150-aoc_notes.org new file mode 100755 index 0000000..68d9bbc --- /dev/null +++ b/20241210001150-aoc_notes.org @@ -0,0 +1,1086 @@ +:PROPERTIES: +:ID: e7f2302b-16eb-476d-a7b9-be12f077819d +:END: +#+title: AOC Notes +#+filetags: :notes:aoc:technical: +#+STARTUP: overview + +Here are the notes for the AOC (Advent Of Code) for the year 2024. +Workspace: +#+BEGIN_SRC haskell +import System.Process (callCommand) +main :: IO () +main = do + putStrLn "Launching IntelliJ in gnome-terminal with zsh..." + _ <- callCommand "gnome-terminal -- zsh -c 'idea /home/zaine/Documents/projects/advent_of_code'" + putStrLn "Terminal launched." +#+END_SRC + +#+RESULTS: + +* Day 3 +** point 1 +A lot of basic string and numeric manipulation was tested. +When you have a input string, and want to test weather there contains a substring, you can use + +#+BEGIN_SRC java[[id:8fa3f476-6152-45f4-b618-50f1e4bce46c][Emacs Stuff]] +// input is the string +if (input.startsWith("mul(", i)) { + int endIndex = input.indexOf(")", i); + if (endIndex != -1) { + String candidate = input.substring(i, endIndex + 1); +} +} +#+END_SRC + +Here we can see that through the loop, an if check is being done to check if the string starts with "mul(", if so, it gets the endIndex of it too. Then it stores that "candidate" value into a String, using the substring method. +** point 2 +some regex below: this checks if the input is of the correct format. + +#+BEGIN_SRC java + public static boolean isValidMul(String input) { + // Regex to validate mul(X,Y) where X and Y are 1-3 digit numbers + return input.matches("mul\\(\\d{1,3},\\d{1,3}\\)"); + } +#+END_SRC +* Day 4 +** part 1 +was extremely difficult. i had to load the input as a 2d array, +#+BEGIN_SRC java +int cols = lines.get(0).length(); //where lines is var +int cols = grid[0].length; // where grid is a 2d array +#+END_SRC +this allows you to get the vertical length of the 2d array. + +*** countWordOccurrences Method +Iterates through the grid to check for occurrences of the word "XMAS" in all possible directions (horizontal, vertical, and diagonal). +Directions: Defined by the directions array, which contains 8 possible ways to traverse: + {0, 1}: Right + {0, -1}: Left + {1, 0}: Down + {-1, 0}: Up + {1, 1}: Diagonal down-right + {1, -1}: Diagonal down-left + {-1, 1}: Diagonal up-right + {-1, -1}: Diagonal up-left + +For each starting position (row, col) in the grid: + +The program checks each direction by calling isWordFound. + +*** Checking for the Word +isWordFound Method Validates if the word exists starting from a specific position (row, col) in the grid, moving in the specified direction (dx, dy). +For each character in the word: +- compute the new position (newRow, newCol) based on the direction. +- Check bounds to ensure the position is valid (not out of the grid). +- Compare the character at the position with the corresponding character in the word. +- If any check fails, return false. + +If all characters match, the word is found, and the method returns true. + +*** Counting Matches +For each occurrence of the word found by isWordFound, increment the count variable. +After scanning all positions and directions in the grid, the total count is returned. + +** part 2 +was alot easier, i looped through the whole grid, and wherever there is the letter 'A', i want to check around it, it can be in the form: +#+BEGIN_SRC +M.S +.A. +M.S +#+END_SRC +and this would count as one, as there is MAS twice (diagonally in the shape of an X) +* Day 5 +** Part One: Identifying Correctly Ordered Updates +*** Splitting Input into Rules and Updates +Parsing the input file into two distinct sections (rules and updates) required identifying the empty line separator. + #+BEGIN_SRC java + for (String line : lines) { + if (line.trim().isEmpty()) { + emptyLineFound = true; + continue; // Skip the empty line itself + } + if (!emptyLineFound) { + firstList.add(line); + } else { + secondList.add(line); + } + } + #+END_SRC + +*** Dependency Graph Representation +Representing the rules as a directed graph with each rule defining an edge (X|Y as X -> Y). This graph maps each page to a list of pages that must follow it. + #+BEGIN_SRC java + Map> graph = new HashMap<>(); + graph.putIfAbsent(from, new ArrayList<>()); + graph.get(from).add(to); + #+END_SRC + +*** Checking Update Validity +Verifying if an update follows the rules using a map of page positions for quick lookup. + #+BEGIN_SRC java + for (Map.Entry> entry : graph.entrySet()) { + int from = entry.getKey(); + for (int to : entry.getValue()) { + if (positions.get(from) >= positions.get(to)) { + return false; // Rule violated + } + } + } + #+END_SRC + +*** Finding the Middle Page +Calculating the middle page for each correctly ordered update using list indexing. + #+BEGIN_SRC java + int middlePage = pages.get(pages.size() / 2); + #+END_SRC + +** Part Two: Reordering Incorrect Updates +*** Topological Sorting +Reordering pages required implementing a topological sort, which ensures all dependencies (rules) are respected. + #+BEGIN_SRC java + visiting.add(node); + for (int neighbor : graph.getOrDefault(node, Collections.emptyList())) { + if (!dfs(neighbor, graph, visited, visiting, sorted)) { + return false; // Cycle detected + } + } + visiting.remove(node); + visited.add(node); + sorted.add(node); + #+END_SRC + +*** Subgraph Creation +Only rules involving pages in the current update were considered. This required dynamically building a subgraph for each update. + #+BEGIN_SRC java + for (int page : pages) { + if (graph.containsKey(page)) { + for (int dependent : graph.get(page)) { + if (pages.contains(dependent)) { + subGraph.get(page).add(dependent); + } + } + } + } + #+END_SRC + +*** Cycle Detection + Ensuring no cycles existed in the dependency graph was critical for valid sorting. + #+BEGIN_SRC java + if (visiting.contains(node)) { + return false; // Cycle detected + } + #+END_SRC + +*** Finding Middle Page After Reordering + Same approach as in Part One but applied after sorting. + #+BEGIN_SRC java + int correctedMiddlePage = reorderedPages.get(reorderedPages.size() / 2); + #+END_SRC + +* Day 6 +** Part 1 +*** Input Parsing +#+BEGIN_SRC java +List input = Files.readAllLines(Paths.get("aoc_24/src/day_6/input")); +int rows = input.size(); +int cols = input.get(0).length(); +char[][] map = new char[rows][cols]; +#+END_SRC + +*** Guard Initialization + #+BEGIN_SRC java + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + if ("^v<>".indexOf(map[r][c]) != -1) { + guardRow = r; + guardCol = c; + guardFacing = map[r][c]; + map[r][c] = '.'; // Clear the guard's position + } + } + } + #+END_SRC + +*** Movement Directions + #+BEGIN_SRC java + Map directions = Map.of( + '^', new int[] {-1, 0}, + 'v', new int[] {1, 0}, + '<', new int[] {0, -1}, + '>', new int[] {0, 1} + ); + #+END_SRC + +*** Turning Logic + #+BEGIN_SRC java + Map turnRight = Map.of( + '^', '>', + '>', 'v', + 'v', '<', + '<', '^' + ); + #+END_SRC + +*** Visited Positions Tracking + #+BEGIN_SRC java + Set visited = new HashSet<>(); + visited.add(guardRow + "," + guardCol); + #+END_SRC + +*** Movement and Termination Logic + #+BEGIN_SRC java + while (true) { + int[] move = directions.get(guardFacing); + int nextRow = guardRow + move[0]; + int nextCol = guardCol + move[1]; + + if (nextRow < 0 || nextRow >= rows || nextCol < 0 || nextCol >= cols) { + break; // Guard leaves the map + } + + if (map[nextRow][nextCol] == '#') { + guardFacing = turnRight.get(guardFacing); // Turn right + } else { + guardRow = nextRow; + guardCol = nextCol; + visited.add(guardRow + "," + guardCol); + } + } + #+END_SRC +** Part 2 +*** Input Parsing + #+BEGIN_SRC java + List input = Files.readAllLines(Paths.get("aoc_24/src/day_6/input")); + int rows = input.size(); + int cols = input.get(0).length(); + char[][] map = new char[rows][cols]; + #+END_SRC + +*** Guard Initialization + #+BEGIN_SRC java + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + if ("^v<>".indexOf(map[r][c]) != -1) { + guardRow = r; + guardCol = c; + guardFacing = map[r][c]; + map[r][c] = '.'; // Clear the guard's position + } + } + } + #+END_SRC + +*** Movement Directions + #+BEGIN_SRC java + Map directions = Map.of( + '^', new int[] {-1, 0}, + 'v', new int[] {1, 0}, + '<', new int[] {0, -1}, + '>', new int[] {0, 1} + ); + #+END_SRC + +*** Turning Logic + #+BEGIN_SRC java + Map turnRight = Map.of( + '^', '>', + '>', 'v', + 'v', '<', + '<', '^' + ); + #+END_SRC + +*** Valid Obstruction Positions + #+BEGIN_SRC java + Set validObstructions = new HashSet<>(); + + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + if (map[r][c] == '.' && !(r == guardRow && c == guardCol)) { + map[r][c] = '#'; // Temporarily place obstruction + + if (causesLoop(map, guardRow, guardCol, guardFacing, directions, turnRight)) { + validObstructions.add(r + "," + c); + } + + map[r][c] = '.'; // Remove obstruction + } + } + } + System.out.println("Number of valid obstruction positions: " + validObstructions.size()); + #+END_SRC + +*** Loop Detection Helper Function + #+BEGIN_SRC java + private static boolean causesLoop(char[][] map, int guardRow, int guardCol, char guardFacing, + Map directions, Map turnRight) { + Set seenStates = new HashSet<>(); + int rows = map.length; + int cols = map[0].length; + + while (true) { + String state = guardRow + "," + guardCol + "," + guardFacing; + if (seenStates.contains(state)) { + return true; // Loop detected + } + seenStates.add(state); + + int[] move = directions.get(guardFacing); + int nextRow = guardRow + move[0]; + int nextCol = guardCol + move[1]; + + if (nextRow < 0 || nextRow >= rows || nextCol < 0 || nextCol >= cols) { + return false; // Guard leaves the map + } + + if (map[nextRow][nextCol] == '#') { + guardFacing = turnRight.get(guardFacing); // Turn right + } else { + guardRow = nextRow; + guardCol = nextCol; + } + } + } + #+END_SRC + +* Day 7 +** Part 1 +*** Input Parsing + - Parse the input file, where each line is in the format `: ...` + - `testValue` is a target number, and we determine if it can be computed by combining the given numbers with `+` or `*`. + #+BEGIN_SRC java + List input = Files.readAllLines(Paths.get("aoc_24/src/day_7/input")); + long totalCalibrationResult = 0; + + for (String line : input) { + String[] parts = line.split(": "); + long testValue = Long.parseLong(parts[0]); // Target value + String[] numbers = parts[1].split(" "); + } + #+END_SRC + +*** Validation Logic + - The `isValidEquation` function checks if any combination of operators (`+` or `*`) between the numbers matches the `testValue`. + - Evaluation is performed left-to-right. + #+BEGIN_SRC java + private static boolean isValidEquation(long testValue, String[] numbers) { + List operators = Arrays.asList("+", "*"); + List operatorCombinations = generateOperatorCombinations(numbers.length - 1, operators); + + for (String[] operatorCombination : operatorCombinations) { + long result = Long.parseLong(numbers[0]); + for (int i = 1; i < numbers.length; i++) { + String operator = operatorCombination[i - 1]; + long num = Long.parseLong(numbers[i]); + + if (operator.equals("+")) { + result += num; + } else if (operator.equals("*")) { + result *= num; + } + } + + if (result == testValue) { + return true; // Equation is valid + } + } + return false; // No valid equation found + } + #+END_SRC + +*** Operator Combination Generator + - Generate all possible combinations of `+` and `*` for `n-1` positions (where `n` is the number of numbers). + #+BEGIN_SRC java + private static List generateOperatorCombinations(int numOperators, List operators) { + List combinations = new ArrayList<>(); + generateOperatorCombinationsRecursive(new String[numOperators], 0, operators, combinations); + return combinations; + } + + private static void generateOperatorCombinationsRecursive(String[] current, int index, List operators, List combinations) { + if (index == current.length) { + combinations.add(current.clone()); + return; + } + + for (String operator : operators) { + current[index] = operator; + generateOperatorCombinationsRecursive(current, index + 1, operators, combinations); + } + } + #+END_SRC + +*** Main Logic + - Iterate over each line of input. + - Parse `testValue` and numbers. + - If a valid equation exists for the line, add the `testValue` to the total calibration result. + #+BEGIN_SRC java + for (String line : input) { + String[] parts = line.split(": "); + long testValue = Long.parseLong(parts[0]); + String[] numbers = parts[1].split(" "); + + if (isValidEquation(testValue, numbers)) { + totalCalibrationResult += testValue; + } + } + System.out.println("Total Calibration Result: " + totalCalibrationResult); + #+END_SRC + +** Part 2 +*** Input Parsing + - Reads an input file where each line is formatted as `: ...`. + - Parses `testValue` and the numbers to evaluate equations that could result in `testValue`. + #+BEGIN_SRC java + List input = Files.readAllLines(Paths.get("aoc_24/src/day_7/input")); + long totalCalibrationResult = 0; + + for (String line : input) { + String[] parts = line.split(": "); + long testValue = Long.parseLong(parts[0]); // Target value + String[] numbers = parts[1].split(" "); + } + #+END_SRC + +*** Validation Logic + - The `isValidEquation` function checks if any combination of operators (`+`, `*`, or `||`) between numbers can match the `testValue`. + - Includes support for a new operator `||`: + - Concatenates the current `result` and the next number as strings. + - Converts the concatenated string back to `long` to update the result. + - Evaluation is performed left-to-right. + #+BEGIN_SRC java + private static boolean isValidEquation(long testValue, String[] numbers) { + List operators = Arrays.asList("+", "*", "||"); + List operatorCombinations = generateOperatorCombinations(numbers.length - 1, operators); + + for (String[] operatorCombination : operatorCombinations) { + long result = Long.parseLong(numbers[0]); + for (int i = 1; i < numbers.length; i++) { + String operator = operatorCombination[i - 1]; + long num = Long.parseLong(numbers[i]); + + if (operator.equals("+")) { + result += num; + } else if (operator.equals("*")) { + result *= num; + } else if (operator.equals("||")) { + result = Long.parseLong(Long.toString(result) + Long.toString(num)); + } + } + + if (result == testValue) { + return true; + } + } + return false; + } + #+END_SRC + +*** Operator Combination Generator + - Generates all possible combinations of `+`, `*`, and `||` operators for `n-1` positions (where `n` is the number of numbers). + - Recursively builds the combinations. + #+BEGIN_SRC java + private static List generateOperatorCombinations(int numOperators, List operators) { + List combinations = new ArrayList<>(); + generateOperatorCombinationsRecursive(new String[numOperators], 0, operators, combinations); + return combinations; + } + + private static void generateOperatorCombinationsRecursive(String[] current, int index, List operators, List combinations) { + if (index == current.length) { + combinations.add(current.clone()); + return; + } + + for (String operator : operators) { + current[index] = operator; + generateOperatorCombinationsRecursive(current, index + 1, operators, combinations); + } + } + #+END_SRC + +*** Main Logic + - Iterates over each line of input. + - Parses `testValue` and numbers. + - Adds `testValue` to the total if a valid equation exists for the line. + #+BEGIN_SRC java + for (String line : input) { + String[] parts = line.split(": "); + long testValue = Long.parseLong(parts[0]); + String[] numbers = parts[1].split(" "); + + if (isValidEquation(testValue, numbers)) { + totalCalibrationResult += testValue; + } + } + System.out.println("Total Calibration Result: " + totalCalibrationResult); + #+END_SRC + +* Day 8 +Resonant Collinearity + +** Part One +- Objective: Identify unique antinode locations within a map, considering two antennas of the same frequency in a specific configuration. +- Key Condition: Antinode occurs if two antennas of the same frequency are aligned such that one is twice as far from the antinode as the other. +- Steps: + 1. Parse the input map to locate antennas grouped by their frequency. + 2. For each frequency group, iterate through all antenna pairs. + 3. Calculate potential antinode positions based on the defined condition. + 4. Use a Set to store unique antinode positions. + 5. Return the size of the Set as the total unique antinode count. + +- Code Snippet: +#+BEGIN_SRC java +for (int i = 0; i < locations.size(); i++) { + for (int j = i + 1; j < locations.size(); j++) { + int[] a = locations.get(i); + int[] b = locations.get(j); + + // Calculate midpoints and validate conditions + if ((b[0] - a[0]) % 2 == 0 && (b[1] - a[1]) % 2 == 0) { + int midRow = (a[0] + b[0]) / 2; + int midCol = (a[1] + b[1]) / 2; + antinodes.add(midRow + "," + midCol); + } + } +} +#+END_SRC + +** Part Two +- Objective: Update the model to include all positions perfectly aligned with at least two antennas of the same frequency. +- Key Changes: + - Antinodes occur at all positions along the straight line between antennas of the same frequency. + - Antennas themselves are also antinodes unless they are the only instance of their frequency. +- Steps: + 1. Parse the input map and group antennas by frequency. + 2. For each pair of antennas of the same frequency: + - Calculate direction vectors (reduced using GCD). + - Traverse along the direction vector in both forward and backward directions, marking all valid positions as antinodes. + 3. Add each antenna location directly to the set of antinodes. + 4. Return the size of the unique antinode set. + +- Code Snippet: +#+BEGIN_SRC java +int dr = b[0] - a[0]; +int dc = b[1] - a[1]; +int gcd = gcd(Math.abs(dr), Math.abs(dc)); +dr /= gcd; +dc /= gcd; + +// Traverse along the line +int row = a[0], col = a[1]; +while (isWithinBounds(row, col, rows, cols)) { + antinodes.add(row + "," + col); + row += dr; + col += dc; +} +#+END_SRC + +** Notes on Implementation +- Data Structures: + - Map>: Stores antenna positions by frequency. + - Set: Tracks unique antinode positions. +- Utility Functions: + - isWithinBounds: Ensures coordinates are within map dimensions. + - gcd: Simplifies direction vectors to avoid redundant calculations. + +* Day 9 +** Part 1: Manipulating and Calculating Disk Placement +Concept: Creating and manipulating a disk structure based on input. +Input is split into alternating "id" and "space" values. +Example of creating the disk: + #+BEGIN_SRC java + for (String character : lines.getFirst().split("")) { + int num = Integer.parseInt(character); + if (space) { + for (int i = 0; i < num; i++) disk.add(-1); + } else { + for (int i = 0; i < num; i++) disk.add(id); + id++; + } + space = !space; + } + #+END_SRC + +- Key Learning: Understanding alternating patterns in input and their translation to a data structure. + +- Problem Solving: Adjusting misplaced items. + - Utilize a while loop to locate and correct misplaced "-1" values in the disk. + - Example: + #+BEGIN_SRC java + if (disk.get(i) == -1) { + int val = -1; + while (val == -1) { + val = disk.removeLast(); + } + disk.add(i, val); + } + #+END_SRC + +- Final Calculation: Using BigInteger for large numbers. + - Formula: index * value for each position in the disk. + - Example: + #+BEGIN_SRC java + BigInteger count = BigInteger.ZERO; + for (int i = 0; i < disk.size(); i++) { + count = count.add(BigInteger.valueOf(i).multiply(BigInteger.valueOf(disk.get(i)))); + } + #+END_SRC + +** Part 2: Advanced Disk Rearrangement with Blocks + +- Concept: Representing disk as a list of Block objects. + - Block stores size and id. + - Example: + #+BEGIN_SRC java + public static class Block { + private int size; + private int id; + public Block(int size, int id) { + this.size = size; + this.id = id; + } + } + #+END_SRC + +- Key Learning: Encapsulating logic into objects improves clarity and scalability. + +- Space Management: Finding and fitting blocks into available spaces. + - Utilize a fit method to split or match blocks. + - Example: + #+BEGIN_SRC java + public List fit(Block work) { + if (work.size > this.size) return null; + List newList = new ArrayList<>(); + newList.add(work); + if (work.size < this.size) { + newList.add(new Block(this.size - work.size, -1)); + } + return newList; + } + #+END_SRC + +- Problem Solving: Iterating backward through the disk to find and rearrange blocks into spaces. + - Restart loop when a fit is found to ensure proper placement. + - Example: + #+BEGIN_SRC java + for (int i = 0; i < diskPlace; i++) { + Block possibleSpace = disk.get(i); + if (possibleSpace.getId() == -1) { + List blocks = possibleSpace.fit(work); + if (blocks != null) { + disk.remove(diskPlace); + disk.add(diskPlace, new Block(work.getSize(), -1)); + for (int j = blocks.size() - 1; j >= 0; j--) { + disk.add(i, blocks.get(j)); + } + break; + } + } + } + #+END_SRC + +- Final Calculation: Summing placements using block properties. + - Ensure large calculations are done efficiently with BigInteger. + - Example: + #+BEGIN_SRC java + BigInteger count = BigInteger.ZERO; + int placement = 0; + for (Block block : disk) { + if (block.getId() != -1) { + for (int j = 0; j < block.getSize(); j++) { + count = count.add(BigInteger.valueOf(placement).multiply(BigInteger.valueOf(block.getId()))); + placement++; + } + } else { + placement += block.getSize(); + } + } + #+END_SRC + +* Day 10 +** Part 1: Counting Trails in a 2D Grid + +- Concept: Navigating and processing a 2D grid based on specific rules. + - Input is parsed into a 2D map from a list of strings. + - Conversion logic for parsing: + #+BEGIN_SRC java + int[] map = new int[width * height]; + int i = 0; + for (String line : lines) { + if (line.isBlank()) continue; + for (String character : line.trim().split("")) { + map[i] = Integer.parseInt(character); + i++; + } + } + #+END_SRC + +- Recursive Approach: Traversing paths with a helper function countTrails. + - Recursion halts on boundaries, invalid values, or when a sequence completes. + - Example: + #+BEGIN_SRC java + private static Set countTrails(int[] map, int x, int y, int width, int height, int val) { + if (x >= width || y >= height || x < 0 || y < 0 || map[y * width + x] != val) return new HashSet<>(); + if (val == 9) return Set.of(new Point(9, x, y)); + + Set result = new HashSet<>(); + result.addAll(countTrails(map, x + 1, y, width, height, val + 1)); + result.addAll(countTrails(map, x - 1, y, width, height, val + 1)); + result.addAll(countTrails(map, x, y + 1, width, height, val + 1)); + result.addAll(countTrails(map, x, y - 1, width, height, val + 1)); + return result; + } + #+END_SRC + +- Key Learning: Recursive exploration of a grid with stateful logic for trail validity. + +- Result Calculation: Sum the size of all unique trail sets. + - Example: + #+BEGIN_SRC java + long count = 0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + Set set = countTrails(map, x, y, width, height, 0); + count += set.size(); + } + } + #+END_SRC + +** Part 2: Enhanced Trail Counting with Weighted Points + +- Concept: Counting trails with weights using a Map for aggregation. + - Modified helper function countTrails2 tracks weights for each point. + - Example: + + #+BEGIN_SRC java + private static Map countTrails2(int[] map, int x, int y, int width, int height, int val) { + if (x >= width || y >= height || x < 0 || y < 0 || map[y * width + x] != val) return new HashMap<>(); + if (val == 9) return Map.of(new Point(1, x, y), 1); + + Map result = new HashMap<>(); + checkDirection(map, x + 1, y, width, height, val, result); + checkDirection(map, x - 1, y, width, height, val, result); + checkDirection(map, x, y + 1, width, height, val, result); + checkDirection(map, x, y - 1, width, height, val, result); + return result; + } + #+END_SRC + +- Helper Method: checkDirection facilitates merging results for trail continuity. + - Example: + #+BEGIN_SRC java + private static void checkDirection(int[] map, int x, int y, int width, int height, int val, Map result) { + Map res = countTrails2(map, x, y, width, height, val + 1); + for (Point p : res.keySet()) { + result.merge(p, res.get(p), Integer::sum); + } + } + #+END_SRC + +- Key Learning: Using a Map to manage complex trail state and weights for precise calculations. + +- Result Calculation: Sum weighted trail counts. + - Example: + #+BEGIN_SRC java + long count = 0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + Map res = countTrails2(map, x, y, width, height, 0); + for (int value : res.values()) { + count += value; + } + } + } + #+END_SRC + +- Encapsulation of grid points as objects (Point) simplifies hash-based operations and improves code clarity. +- Using collections like Set and Map effectively is crucial for aggregating results in a structured way. + + +Would you like to make any adjustments or add further examples? +* Day 12 +** Core Logic and Functionality + +1. Coordinates Mapping: + - A map (coords) stores coordinates of each character from the input. For each character, all the coordinates where it appears are stored as Point objects. + + #+BEGIN_SRC java + for (int i = 0; i < in.size(); i++) { + for (int j = 0; j < in.get(i).length(); j++) { + coords.putIfAbsent(in.get(i).charAt(j), new ArrayList<>()); + coords.get(in.get(i).charAt(j)).add(new Point(i, j)); + } + } + #+END_SRC + +2. Flood Fill Algorithm with Stack: + - A flood-fill algorithm is used to explore areas connected by the same character. The algorithm uses a stack to explore adjacent points recursively. + + #+BEGIN_SRC java + ArrayDeque stack = new ArrayDeque<>(); + stack.push(co); + while (!stack.isEmpty()) { + var cur = stack.pop(); + // explore neighbors + } + #+END_SRC + +3. Fence Counting: + - For each region, the number of "fences" (edges where the character changes) is counted. The algorithm checks for boundaries or differing characters adjacent to each point. + + #+BEGIN_SRC java + if (nd.x < 0 || nd.y < 0 || nd.x >= in.size() || nd.y >= in.get(0).length()) { + fence++; + } else if (in.get(nd.x).charAt(nd.y) != ch) { + fence++; + } + #+END_SRC + +4. Side Fetching Logic: + - The fetchSides() method computes the number of "sides" based on the placement of fences, counting how the fences are arranged along rows and columns. + + #+BEGIN_SRC java + for (var xx : cols.keySet()) { + var xl = cols.get(xx); + Collections.sort(xl); + // logic for sorting and counting sides + } + #+END_SRC + +5. Area and Fence Calculations: + - For each character, the area (number of connected points) and the number of fences are calculated. The result is a product of area and fence count. + + #+BEGIN_SRC java + ret += area * fence; + p2 += area * fetchSides(fences); + #+END_SRC + + +*** Core Logic and Functionality + - Coordinates mapping using a Map> to track character positions. + - Flood-fill algorithm using a stack to explore regions of connected characters. + - Fence counting logic to identify boundaries and different characters. + - Side fetching logic to count the number of fences arranged along rows and columns. + - Area and fence calculations for each region to compute the final result. + + + +* Day 13 +** Part 1: Parsing Input and Solving Simultaneous Equations + - Goal: Parse input, extract button coefficients and prize values, solve simultaneous equations to find valid token costs. + - Key Concepts: + - Input parsing using BufferedReader. + - Using determinants to solve simultaneous equations. + - Validating solutions for constraints (non-negative integers, valid m/n). + - Code Snippets: + - Parsing Input: + + #+BEGIN_SRC java + if (line.startsWith("Button A:")) { + String[] parts = line.split(":")[1].split(","); + current = new ButtonPrize(); + current.buttonAX = Integer.parseInt(parts[0].trim().split("\\+")[1]); + current.buttonAY = Integer.parseInt(parts[1].trim().split("\\+")[1]); + } + #+END_SRC + + - Solving Simultaneous Equations: + + #+BEGIN_SRC java + int determinant = buttonAX * buttonBY - buttonBX * buttonAY; + if (determinant == 0) return 0; // No solution + + long mNumerator = prizeX * buttonBY - prizeY * buttonBX; + long nNumerator = prizeY * buttonAX - prizeX * buttonAY; + + if (mNumerator % determinant != 0 || nNumerator % determinant != 0) return 0; + long m = mNumerator / determinant; + long n = nNumerator / determinant; + return (m < 0 || n < 0) ? 0 : m * 3 + n; // Calculate token costs + #+END_SRC + + - Challenges Faced: + - Edge cases with determinant = 0 or invalid input format. + - Ensuring no negative values for m/n. + +** Part 2: Transforming Input Data + - Goal: Modify prize values with a fixed offset before calculations. + - Key Concepts: + - Transforming input data programmatically. + - Reusing the existing calculation logic after transformation. + - Code Snippets: + - Prepending Offset to Prize Values: + + #+BEGIN_SRC java + private void prependZeroes(ButtonPrize bp) { + bp.setPrizeX(bp.getPrizeX() + 10000000000000L); + bp.setPrizeY(bp.getPrizeY() + 10000000000000L); + } + #+END_SRC + + - Reusing Logic: + + #+BEGIN_SRC java + for (ButtonPrize bp : data) { + prependZeroes(bp); + count_part2 += calculateSimultaneousEquations(bp.getButtonAX(), bp.getButtonAY(), + bp.getButtonBX(), bp.getButtonBY(), + bp.getPrizeX(), bp.getPrizeY()); + } + #+END_SRC + + - Challenges Faced: + - Avoiding modification of original input logic while adding transformations. + - Maintaining readability and modularity. + +* Day 14 +** Part 1: Simulating Robot Movement + +- Concept: Simulating the movement of robots on a grid, wrapping their positions around the edges. + - The grid has dimensions 101x103, and the robot positions wrap around when they move out of bounds. + - Wrapping is implemented using a helper method: + + #+BEGIN_SRC java + public static int wrap(int value, int max) { + return ((value % max) + max) % max; + } + #+END_SRC + +- Key Learning: Efficiently handling movement on a toroidal grid (wrap-around behavior). + +- Quadrant Assignment: + - Robots are excluded from the middle row and column (x=50, y=51). + - Quadrant assignments are based on the x and y positions: + + #+BEGIN_SRC java + if (x < 50 && y < 51) { + quadrantCounts[0]++; // Top-left + } else if (x >= 50 && y < 51) { + quadrantCounts[1]++; // Top-right + } else if (x < 50 && y >= 51) { + quadrantCounts[2]++; // Bottom-left + } else if (x >= 50 && y >= 51) { + quadrantCounts[3]++; // Bottom-right + } + #+END_SRC + +- Safety Factor Calculation: + - The safety factor is the product of the number of robots in each quadrant: + + #+BEGIN_SRC java + int safetyFactor = 1; + for (int count : quadrantCounts) { + safetyFactor *= count; + } + #+END_SRC + +** Part 2: Identifying Patterns in Robot Positions + +- Concept: Simulating grid states to find a specific pattern of robot alignment. + - Robots move based on their initial velocity, and their positions are updated iteratively. + - A grid is used to track robot positions, and columns are checked for specific patterns. + +- Key Learning: Efficiently detecting consecutive robot positions in a grid column. + +- Grid Initialization: + - A helper method initializes a 2D grid with given dimensions: + + #+BEGIN_SRC java + private int[][] initializeGrid(int rows, int cols) { + return new int[rows][cols]; + } + #+END_SRC + +- Position Calculation: + - New positions are computed using the robot's velocity and current step, with wrapping: + + #+BEGIN_SRC java + private int[] calculateNewPosition(int[] position, int[] velocity, int step, int[] tileDimensions) { + return new int[] { + (position[0] + step * (tileDimensions[0] + velocity[0])) % tileDimensions[0], + (position[1] + step * (tileDimensions[1] + velocity[1])) % tileDimensions[1] + }; + } + #+END_SRC + +- Pattern Detection: + - A helper method checks for consecutive robots in a column: + + #+BEGIN_SRC java + private boolean hasConsecutiveInRow(List positions, int requiredConsecutive) { + Collections.sort(positions); + int consecutiveCount = 0; + + for (int i = 1; i < positions.size(); i++) { + if (positions.get(i) - positions.get(i - 1) == 1) { + consecutiveCount++; + if (consecutiveCount >= requiredConsecutive) { + return true; + } + } else { + consecutiveCount = 0; + } + } + return false; + } + #+END_SRC + +- Stopping Condition: + - Simulation stops when a column has at least requiredConsecutive robots aligned. + +--- + +### Supporting Components + +- Data Representation: + - PointAndVelocity encapsulates robot data, including position (PX, PY) and velocity (VX, VY): + + #+BEGIN_SRC java + public static class PointAndVelocity { + private int PX; + private int PY; + private int VX; + private int VY; + + // Getters and setters + public int getVX() { return VX; } + public void setVX(int vX) { VX = vX; } + public int getVY() { return VY; } + public void setVY(int vY) { VY = vY; } + public int getPX() { return PX; } + public void setPX(int pX) { PX = pX; } + public int getPY() { return PY; } + public void setPY(int pY) { PY = pY; } + } + #+END_SRC + +- Input Parsing: + - Robot data is parsed from a file or input list. Each robot's position and velocity are extracted: + + #+BEGIN_SRC java + private List getPointAndVelocities() { + List pvs = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader(new FileReader(fetchFilePath()))) { + String line; + while ((line = reader.readLine()) != null) { + String[] parts = line.split(" "); + PointAndVelocity pav = new PointAndVelocity(); + pav.setPX(Integer.parseInt(parts[0].split(",")[0].replace("p=", ""))); + pav.setPY(Integer.parseInt(parts[0].split(",")[1].replace("p=", ""))); + pav.setVX(Integer.parseInt(parts[1].split(",")[0].replace("v=", ""))); + pav.setVY(Integer.parseInt(parts[1].split(",")[1].replace("v=", ""))); + pvs.add(pav); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return pvs; + } + #+END_SRC + +- Simulation Control: + - Part 1 iterates for 100 steps, while Part 2 continues until a pattern is found or the maximum steps are reached. + +* diff --git a/20241210001150-aoc_notes.org~ b/20241210001150-aoc_notes.org~ new file mode 100755 index 0000000..1139b1d --- /dev/null +++ b/20241210001150-aoc_notes.org~ @@ -0,0 +1,1085 @@ +:PROPERTIES: +:ID: e7f2302b-16eb-476d-a7b9-be12f077819d +:END: +#+title: AOC Notes +#+STARTUP: overview + +Here are the notes for the AOC (Advent Of Code) for the year 2024. +Workspace: +#+BEGIN_SRC haskell +import System.Process (callCommand) +main :: IO () +main = do + putStrLn "Launching IntelliJ in gnome-terminal with zsh..." + _ <- callCommand "gnome-terminal -- zsh -c 'idea /home/zaine/Documents/projects/advent_of_code'" + putStrLn "Terminal launched." +#+END_SRC + +#+RESULTS: + +* Day 3 +** point 1 +A lot of basic string and numeric manipulation was tested. +When you have a input string, and want to test weather there contains a substring, you can use + +#+BEGIN_SRC java[[id:8fa3f476-6152-45f4-b618-50f1e4bce46c][Emacs Stuff]] +// input is the string +if (input.startsWith("mul(", i)) { + int endIndex = input.indexOf(")", i); + if (endIndex != -1) { + String candidate = input.substring(i, endIndex + 1); +} +} +#+END_SRC + +Here we can see that through the loop, an if check is being done to check if the string starts with "mul(", if so, it gets the endIndex of it too. Then it stores that "candidate" value into a String, using the substring method. +** point 2 +some regex below: this checks if the input is of the correct format. + +#+BEGIN_SRC java + public static boolean isValidMul(String input) { + // Regex to validate mul(X,Y) where X and Y are 1-3 digit numbers + return input.matches("mul\\(\\d{1,3},\\d{1,3}\\)"); + } +#+END_SRC +* Day 4 +** part 1 +was extremely difficult. i had to load the input as a 2d array, +#+BEGIN_SRC java +int cols = lines.get(0).length(); //where lines is var +int cols = grid[0].length; // where grid is a 2d array +#+END_SRC +this allows you to get the vertical length of the 2d array. + +*** countWordOccurrences Method +Iterates through the grid to check for occurrences of the word "XMAS" in all possible directions (horizontal, vertical, and diagonal). +Directions: Defined by the directions array, which contains 8 possible ways to traverse: + {0, 1}: Right + {0, -1}: Left + {1, 0}: Down + {-1, 0}: Up + {1, 1}: Diagonal down-right + {1, -1}: Diagonal down-left + {-1, 1}: Diagonal up-right + {-1, -1}: Diagonal up-left + +For each starting position (row, col) in the grid: + +The program checks each direction by calling isWordFound. + +*** Checking for the Word +isWordFound Method Validates if the word exists starting from a specific position (row, col) in the grid, moving in the specified direction (dx, dy). +For each character in the word: +- compute the new position (newRow, newCol) based on the direction. +- Check bounds to ensure the position is valid (not out of the grid). +- Compare the character at the position with the corresponding character in the word. +- If any check fails, return false. + +If all characters match, the word is found, and the method returns true. + +*** Counting Matches +For each occurrence of the word found by isWordFound, increment the count variable. +After scanning all positions and directions in the grid, the total count is returned. + +** part 2 +was alot easier, i looped through the whole grid, and wherever there is the letter 'A', i want to check around it, it can be in the form: +#+BEGIN_SRC +M.S +.A. +M.S +#+END_SRC +and this would count as one, as there is MAS twice (diagonally in the shape of an X) +* Day 5 +** Part One: Identifying Correctly Ordered Updates +*** Splitting Input into Rules and Updates +Parsing the input file into two distinct sections (rules and updates) required identifying the empty line separator. + #+BEGIN_SRC java + for (String line : lines) { + if (line.trim().isEmpty()) { + emptyLineFound = true; + continue; // Skip the empty line itself + } + if (!emptyLineFound) { + firstList.add(line); + } else { + secondList.add(line); + } + } + #+END_SRC + +*** Dependency Graph Representation +Representing the rules as a directed graph with each rule defining an edge (X|Y as X -> Y). This graph maps each page to a list of pages that must follow it. + #+BEGIN_SRC java + Map> graph = new HashMap<>(); + graph.putIfAbsent(from, new ArrayList<>()); + graph.get(from).add(to); + #+END_SRC + +*** Checking Update Validity +Verifying if an update follows the rules using a map of page positions for quick lookup. + #+BEGIN_SRC java + for (Map.Entry> entry : graph.entrySet()) { + int from = entry.getKey(); + for (int to : entry.getValue()) { + if (positions.get(from) >= positions.get(to)) { + return false; // Rule violated + } + } + } + #+END_SRC + +*** Finding the Middle Page +Calculating the middle page for each correctly ordered update using list indexing. + #+BEGIN_SRC java + int middlePage = pages.get(pages.size() / 2); + #+END_SRC + +** Part Two: Reordering Incorrect Updates +*** Topological Sorting +Reordering pages required implementing a topological sort, which ensures all dependencies (rules) are respected. + #+BEGIN_SRC java + visiting.add(node); + for (int neighbor : graph.getOrDefault(node, Collections.emptyList())) { + if (!dfs(neighbor, graph, visited, visiting, sorted)) { + return false; // Cycle detected + } + } + visiting.remove(node); + visited.add(node); + sorted.add(node); + #+END_SRC + +*** Subgraph Creation +Only rules involving pages in the current update were considered. This required dynamically building a subgraph for each update. + #+BEGIN_SRC java + for (int page : pages) { + if (graph.containsKey(page)) { + for (int dependent : graph.get(page)) { + if (pages.contains(dependent)) { + subGraph.get(page).add(dependent); + } + } + } + } + #+END_SRC + +*** Cycle Detection + Ensuring no cycles existed in the dependency graph was critical for valid sorting. + #+BEGIN_SRC java + if (visiting.contains(node)) { + return false; // Cycle detected + } + #+END_SRC + +*** Finding Middle Page After Reordering + Same approach as in Part One but applied after sorting. + #+BEGIN_SRC java + int correctedMiddlePage = reorderedPages.get(reorderedPages.size() / 2); + #+END_SRC + +* Day 6 +** Part 1 +*** Input Parsing +#+BEGIN_SRC java +List input = Files.readAllLines(Paths.get("aoc_24/src/day_6/input")); +int rows = input.size(); +int cols = input.get(0).length(); +char[][] map = new char[rows][cols]; +#+END_SRC + +*** Guard Initialization + #+BEGIN_SRC java + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + if ("^v<>".indexOf(map[r][c]) != -1) { + guardRow = r; + guardCol = c; + guardFacing = map[r][c]; + map[r][c] = '.'; // Clear the guard's position + } + } + } + #+END_SRC + +*** Movement Directions + #+BEGIN_SRC java + Map directions = Map.of( + '^', new int[] {-1, 0}, + 'v', new int[] {1, 0}, + '<', new int[] {0, -1}, + '>', new int[] {0, 1} + ); + #+END_SRC + +*** Turning Logic + #+BEGIN_SRC java + Map turnRight = Map.of( + '^', '>', + '>', 'v', + 'v', '<', + '<', '^' + ); + #+END_SRC + +*** Visited Positions Tracking + #+BEGIN_SRC java + Set visited = new HashSet<>(); + visited.add(guardRow + "," + guardCol); + #+END_SRC + +*** Movement and Termination Logic + #+BEGIN_SRC java + while (true) { + int[] move = directions.get(guardFacing); + int nextRow = guardRow + move[0]; + int nextCol = guardCol + move[1]; + + if (nextRow < 0 || nextRow >= rows || nextCol < 0 || nextCol >= cols) { + break; // Guard leaves the map + } + + if (map[nextRow][nextCol] == '#') { + guardFacing = turnRight.get(guardFacing); // Turn right + } else { + guardRow = nextRow; + guardCol = nextCol; + visited.add(guardRow + "," + guardCol); + } + } + #+END_SRC +** Part 2 +*** Input Parsing + #+BEGIN_SRC java + List input = Files.readAllLines(Paths.get("aoc_24/src/day_6/input")); + int rows = input.size(); + int cols = input.get(0).length(); + char[][] map = new char[rows][cols]; + #+END_SRC + +*** Guard Initialization + #+BEGIN_SRC java + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + if ("^v<>".indexOf(map[r][c]) != -1) { + guardRow = r; + guardCol = c; + guardFacing = map[r][c]; + map[r][c] = '.'; // Clear the guard's position + } + } + } + #+END_SRC + +*** Movement Directions + #+BEGIN_SRC java + Map directions = Map.of( + '^', new int[] {-1, 0}, + 'v', new int[] {1, 0}, + '<', new int[] {0, -1}, + '>', new int[] {0, 1} + ); + #+END_SRC + +*** Turning Logic + #+BEGIN_SRC java + Map turnRight = Map.of( + '^', '>', + '>', 'v', + 'v', '<', + '<', '^' + ); + #+END_SRC + +*** Valid Obstruction Positions + #+BEGIN_SRC java + Set validObstructions = new HashSet<>(); + + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + if (map[r][c] == '.' && !(r == guardRow && c == guardCol)) { + map[r][c] = '#'; // Temporarily place obstruction + + if (causesLoop(map, guardRow, guardCol, guardFacing, directions, turnRight)) { + validObstructions.add(r + "," + c); + } + + map[r][c] = '.'; // Remove obstruction + } + } + } + System.out.println("Number of valid obstruction positions: " + validObstructions.size()); + #+END_SRC + +*** Loop Detection Helper Function + #+BEGIN_SRC java + private static boolean causesLoop(char[][] map, int guardRow, int guardCol, char guardFacing, + Map directions, Map turnRight) { + Set seenStates = new HashSet<>(); + int rows = map.length; + int cols = map[0].length; + + while (true) { + String state = guardRow + "," + guardCol + "," + guardFacing; + if (seenStates.contains(state)) { + return true; // Loop detected + } + seenStates.add(state); + + int[] move = directions.get(guardFacing); + int nextRow = guardRow + move[0]; + int nextCol = guardCol + move[1]; + + if (nextRow < 0 || nextRow >= rows || nextCol < 0 || nextCol >= cols) { + return false; // Guard leaves the map + } + + if (map[nextRow][nextCol] == '#') { + guardFacing = turnRight.get(guardFacing); // Turn right + } else { + guardRow = nextRow; + guardCol = nextCol; + } + } + } + #+END_SRC + +* Day 7 +** Part 1 +*** Input Parsing + - Parse the input file, where each line is in the format `: ...` + - `testValue` is a target number, and we determine if it can be computed by combining the given numbers with `+` or `*`. + #+BEGIN_SRC java + List input = Files.readAllLines(Paths.get("aoc_24/src/day_7/input")); + long totalCalibrationResult = 0; + + for (String line : input) { + String[] parts = line.split(": "); + long testValue = Long.parseLong(parts[0]); // Target value + String[] numbers = parts[1].split(" "); + } + #+END_SRC + +*** Validation Logic + - The `isValidEquation` function checks if any combination of operators (`+` or `*`) between the numbers matches the `testValue`. + - Evaluation is performed left-to-right. + #+BEGIN_SRC java + private static boolean isValidEquation(long testValue, String[] numbers) { + List operators = Arrays.asList("+", "*"); + List operatorCombinations = generateOperatorCombinations(numbers.length - 1, operators); + + for (String[] operatorCombination : operatorCombinations) { + long result = Long.parseLong(numbers[0]); + for (int i = 1; i < numbers.length; i++) { + String operator = operatorCombination[i - 1]; + long num = Long.parseLong(numbers[i]); + + if (operator.equals("+")) { + result += num; + } else if (operator.equals("*")) { + result *= num; + } + } + + if (result == testValue) { + return true; // Equation is valid + } + } + return false; // No valid equation found + } + #+END_SRC + +*** Operator Combination Generator + - Generate all possible combinations of `+` and `*` for `n-1` positions (where `n` is the number of numbers). + #+BEGIN_SRC java + private static List generateOperatorCombinations(int numOperators, List operators) { + List combinations = new ArrayList<>(); + generateOperatorCombinationsRecursive(new String[numOperators], 0, operators, combinations); + return combinations; + } + + private static void generateOperatorCombinationsRecursive(String[] current, int index, List operators, List combinations) { + if (index == current.length) { + combinations.add(current.clone()); + return; + } + + for (String operator : operators) { + current[index] = operator; + generateOperatorCombinationsRecursive(current, index + 1, operators, combinations); + } + } + #+END_SRC + +*** Main Logic + - Iterate over each line of input. + - Parse `testValue` and numbers. + - If a valid equation exists for the line, add the `testValue` to the total calibration result. + #+BEGIN_SRC java + for (String line : input) { + String[] parts = line.split(": "); + long testValue = Long.parseLong(parts[0]); + String[] numbers = parts[1].split(" "); + + if (isValidEquation(testValue, numbers)) { + totalCalibrationResult += testValue; + } + } + System.out.println("Total Calibration Result: " + totalCalibrationResult); + #+END_SRC + +** Part 2 +*** Input Parsing + - Reads an input file where each line is formatted as `: ...`. + - Parses `testValue` and the numbers to evaluate equations that could result in `testValue`. + #+BEGIN_SRC java + List input = Files.readAllLines(Paths.get("aoc_24/src/day_7/input")); + long totalCalibrationResult = 0; + + for (String line : input) { + String[] parts = line.split(": "); + long testValue = Long.parseLong(parts[0]); // Target value + String[] numbers = parts[1].split(" "); + } + #+END_SRC + +*** Validation Logic + - The `isValidEquation` function checks if any combination of operators (`+`, `*`, or `||`) between numbers can match the `testValue`. + - Includes support for a new operator `||`: + - Concatenates the current `result` and the next number as strings. + - Converts the concatenated string back to `long` to update the result. + - Evaluation is performed left-to-right. + #+BEGIN_SRC java + private static boolean isValidEquation(long testValue, String[] numbers) { + List operators = Arrays.asList("+", "*", "||"); + List operatorCombinations = generateOperatorCombinations(numbers.length - 1, operators); + + for (String[] operatorCombination : operatorCombinations) { + long result = Long.parseLong(numbers[0]); + for (int i = 1; i < numbers.length; i++) { + String operator = operatorCombination[i - 1]; + long num = Long.parseLong(numbers[i]); + + if (operator.equals("+")) { + result += num; + } else if (operator.equals("*")) { + result *= num; + } else if (operator.equals("||")) { + result = Long.parseLong(Long.toString(result) + Long.toString(num)); + } + } + + if (result == testValue) { + return true; + } + } + return false; + } + #+END_SRC + +*** Operator Combination Generator + - Generates all possible combinations of `+`, `*`, and `||` operators for `n-1` positions (where `n` is the number of numbers). + - Recursively builds the combinations. + #+BEGIN_SRC java + private static List generateOperatorCombinations(int numOperators, List operators) { + List combinations = new ArrayList<>(); + generateOperatorCombinationsRecursive(new String[numOperators], 0, operators, combinations); + return combinations; + } + + private static void generateOperatorCombinationsRecursive(String[] current, int index, List operators, List combinations) { + if (index == current.length) { + combinations.add(current.clone()); + return; + } + + for (String operator : operators) { + current[index] = operator; + generateOperatorCombinationsRecursive(current, index + 1, operators, combinations); + } + } + #+END_SRC + +*** Main Logic + - Iterates over each line of input. + - Parses `testValue` and numbers. + - Adds `testValue` to the total if a valid equation exists for the line. + #+BEGIN_SRC java + for (String line : input) { + String[] parts = line.split(": "); + long testValue = Long.parseLong(parts[0]); + String[] numbers = parts[1].split(" "); + + if (isValidEquation(testValue, numbers)) { + totalCalibrationResult += testValue; + } + } + System.out.println("Total Calibration Result: " + totalCalibrationResult); + #+END_SRC + +* Day 8 +Resonant Collinearity + +** Part One +- Objective: Identify unique antinode locations within a map, considering two antennas of the same frequency in a specific configuration. +- Key Condition: Antinode occurs if two antennas of the same frequency are aligned such that one is twice as far from the antinode as the other. +- Steps: + 1. Parse the input map to locate antennas grouped by their frequency. + 2. For each frequency group, iterate through all antenna pairs. + 3. Calculate potential antinode positions based on the defined condition. + 4. Use a Set to store unique antinode positions. + 5. Return the size of the Set as the total unique antinode count. + +- Code Snippet: +#+BEGIN_SRC java +for (int i = 0; i < locations.size(); i++) { + for (int j = i + 1; j < locations.size(); j++) { + int[] a = locations.get(i); + int[] b = locations.get(j); + + // Calculate midpoints and validate conditions + if ((b[0] - a[0]) % 2 == 0 && (b[1] - a[1]) % 2 == 0) { + int midRow = (a[0] + b[0]) / 2; + int midCol = (a[1] + b[1]) / 2; + antinodes.add(midRow + "," + midCol); + } + } +} +#+END_SRC + +** Part Two +- Objective: Update the model to include all positions perfectly aligned with at least two antennas of the same frequency. +- Key Changes: + - Antinodes occur at all positions along the straight line between antennas of the same frequency. + - Antennas themselves are also antinodes unless they are the only instance of their frequency. +- Steps: + 1. Parse the input map and group antennas by frequency. + 2. For each pair of antennas of the same frequency: + - Calculate direction vectors (reduced using GCD). + - Traverse along the direction vector in both forward and backward directions, marking all valid positions as antinodes. + 3. Add each antenna location directly to the set of antinodes. + 4. Return the size of the unique antinode set. + +- Code Snippet: +#+BEGIN_SRC java +int dr = b[0] - a[0]; +int dc = b[1] - a[1]; +int gcd = gcd(Math.abs(dr), Math.abs(dc)); +dr /= gcd; +dc /= gcd; + +// Traverse along the line +int row = a[0], col = a[1]; +while (isWithinBounds(row, col, rows, cols)) { + antinodes.add(row + "," + col); + row += dr; + col += dc; +} +#+END_SRC + +** Notes on Implementation +- Data Structures: + - Map>: Stores antenna positions by frequency. + - Set: Tracks unique antinode positions. +- Utility Functions: + - isWithinBounds: Ensures coordinates are within map dimensions. + - gcd: Simplifies direction vectors to avoid redundant calculations. + +* Day 9 +** Part 1: Manipulating and Calculating Disk Placement +Concept: Creating and manipulating a disk structure based on input. +Input is split into alternating "id" and "space" values. +Example of creating the disk: + #+BEGIN_SRC java + for (String character : lines.getFirst().split("")) { + int num = Integer.parseInt(character); + if (space) { + for (int i = 0; i < num; i++) disk.add(-1); + } else { + for (int i = 0; i < num; i++) disk.add(id); + id++; + } + space = !space; + } + #+END_SRC + +- Key Learning: Understanding alternating patterns in input and their translation to a data structure. + +- Problem Solving: Adjusting misplaced items. + - Utilize a while loop to locate and correct misplaced "-1" values in the disk. + - Example: + #+BEGIN_SRC java + if (disk.get(i) == -1) { + int val = -1; + while (val == -1) { + val = disk.removeLast(); + } + disk.add(i, val); + } + #+END_SRC + +- Final Calculation: Using BigInteger for large numbers. + - Formula: index * value for each position in the disk. + - Example: + #+BEGIN_SRC java + BigInteger count = BigInteger.ZERO; + for (int i = 0; i < disk.size(); i++) { + count = count.add(BigInteger.valueOf(i).multiply(BigInteger.valueOf(disk.get(i)))); + } + #+END_SRC + +** Part 2: Advanced Disk Rearrangement with Blocks + +- Concept: Representing disk as a list of Block objects. + - Block stores size and id. + - Example: + #+BEGIN_SRC java + public static class Block { + private int size; + private int id; + public Block(int size, int id) { + this.size = size; + this.id = id; + } + } + #+END_SRC + +- Key Learning: Encapsulating logic into objects improves clarity and scalability. + +- Space Management: Finding and fitting blocks into available spaces. + - Utilize a fit method to split or match blocks. + - Example: + #+BEGIN_SRC java + public List fit(Block work) { + if (work.size > this.size) return null; + List newList = new ArrayList<>(); + newList.add(work); + if (work.size < this.size) { + newList.add(new Block(this.size - work.size, -1)); + } + return newList; + } + #+END_SRC + +- Problem Solving: Iterating backward through the disk to find and rearrange blocks into spaces. + - Restart loop when a fit is found to ensure proper placement. + - Example: + #+BEGIN_SRC java + for (int i = 0; i < diskPlace; i++) { + Block possibleSpace = disk.get(i); + if (possibleSpace.getId() == -1) { + List blocks = possibleSpace.fit(work); + if (blocks != null) { + disk.remove(diskPlace); + disk.add(diskPlace, new Block(work.getSize(), -1)); + for (int j = blocks.size() - 1; j >= 0; j--) { + disk.add(i, blocks.get(j)); + } + break; + } + } + } + #+END_SRC + +- Final Calculation: Summing placements using block properties. + - Ensure large calculations are done efficiently with BigInteger. + - Example: + #+BEGIN_SRC java + BigInteger count = BigInteger.ZERO; + int placement = 0; + for (Block block : disk) { + if (block.getId() != -1) { + for (int j = 0; j < block.getSize(); j++) { + count = count.add(BigInteger.valueOf(placement).multiply(BigInteger.valueOf(block.getId()))); + placement++; + } + } else { + placement += block.getSize(); + } + } + #+END_SRC + +* Day 10 +** Part 1: Counting Trails in a 2D Grid + +- Concept: Navigating and processing a 2D grid based on specific rules. + - Input is parsed into a 2D map from a list of strings. + - Conversion logic for parsing: + #+BEGIN_SRC java + int[] map = new int[width * height]; + int i = 0; + for (String line : lines) { + if (line.isBlank()) continue; + for (String character : line.trim().split("")) { + map[i] = Integer.parseInt(character); + i++; + } + } + #+END_SRC + +- Recursive Approach: Traversing paths with a helper function countTrails. + - Recursion halts on boundaries, invalid values, or when a sequence completes. + - Example: + #+BEGIN_SRC java + private static Set countTrails(int[] map, int x, int y, int width, int height, int val) { + if (x >= width || y >= height || x < 0 || y < 0 || map[y * width + x] != val) return new HashSet<>(); + if (val == 9) return Set.of(new Point(9, x, y)); + + Set result = new HashSet<>(); + result.addAll(countTrails(map, x + 1, y, width, height, val + 1)); + result.addAll(countTrails(map, x - 1, y, width, height, val + 1)); + result.addAll(countTrails(map, x, y + 1, width, height, val + 1)); + result.addAll(countTrails(map, x, y - 1, width, height, val + 1)); + return result; + } + #+END_SRC + +- Key Learning: Recursive exploration of a grid with stateful logic for trail validity. + +- Result Calculation: Sum the size of all unique trail sets. + - Example: + #+BEGIN_SRC java + long count = 0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + Set set = countTrails(map, x, y, width, height, 0); + count += set.size(); + } + } + #+END_SRC + +** Part 2: Enhanced Trail Counting with Weighted Points + +- Concept: Counting trails with weights using a Map for aggregation. + - Modified helper function countTrails2 tracks weights for each point. + - Example: + + #+BEGIN_SRC java + private static Map countTrails2(int[] map, int x, int y, int width, int height, int val) { + if (x >= width || y >= height || x < 0 || y < 0 || map[y * width + x] != val) return new HashMap<>(); + if (val == 9) return Map.of(new Point(1, x, y), 1); + + Map result = new HashMap<>(); + checkDirection(map, x + 1, y, width, height, val, result); + checkDirection(map, x - 1, y, width, height, val, result); + checkDirection(map, x, y + 1, width, height, val, result); + checkDirection(map, x, y - 1, width, height, val, result); + return result; + } + #+END_SRC + +- Helper Method: checkDirection facilitates merging results for trail continuity. + - Example: + #+BEGIN_SRC java + private static void checkDirection(int[] map, int x, int y, int width, int height, int val, Map result) { + Map res = countTrails2(map, x, y, width, height, val + 1); + for (Point p : res.keySet()) { + result.merge(p, res.get(p), Integer::sum); + } + } + #+END_SRC + +- Key Learning: Using a Map to manage complex trail state and weights for precise calculations. + +- Result Calculation: Sum weighted trail counts. + - Example: + #+BEGIN_SRC java + long count = 0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + Map res = countTrails2(map, x, y, width, height, 0); + for (int value : res.values()) { + count += value; + } + } + } + #+END_SRC + +- Encapsulation of grid points as objects (Point) simplifies hash-based operations and improves code clarity. +- Using collections like Set and Map effectively is crucial for aggregating results in a structured way. + + +Would you like to make any adjustments or add further examples? +* Day 12 +** Core Logic and Functionality + +1. Coordinates Mapping: + - A map (coords) stores coordinates of each character from the input. For each character, all the coordinates where it appears are stored as Point objects. + + #+BEGIN_SRC java + for (int i = 0; i < in.size(); i++) { + for (int j = 0; j < in.get(i).length(); j++) { + coords.putIfAbsent(in.get(i).charAt(j), new ArrayList<>()); + coords.get(in.get(i).charAt(j)).add(new Point(i, j)); + } + } + #+END_SRC + +2. Flood Fill Algorithm with Stack: + - A flood-fill algorithm is used to explore areas connected by the same character. The algorithm uses a stack to explore adjacent points recursively. + + #+BEGIN_SRC java + ArrayDeque stack = new ArrayDeque<>(); + stack.push(co); + while (!stack.isEmpty()) { + var cur = stack.pop(); + // explore neighbors + } + #+END_SRC + +3. Fence Counting: + - For each region, the number of "fences" (edges where the character changes) is counted. The algorithm checks for boundaries or differing characters adjacent to each point. + + #+BEGIN_SRC java + if (nd.x < 0 || nd.y < 0 || nd.x >= in.size() || nd.y >= in.get(0).length()) { + fence++; + } else if (in.get(nd.x).charAt(nd.y) != ch) { + fence++; + } + #+END_SRC + +4. Side Fetching Logic: + - The fetchSides() method computes the number of "sides" based on the placement of fences, counting how the fences are arranged along rows and columns. + + #+BEGIN_SRC java + for (var xx : cols.keySet()) { + var xl = cols.get(xx); + Collections.sort(xl); + // logic for sorting and counting sides + } + #+END_SRC + +5. Area and Fence Calculations: + - For each character, the area (number of connected points) and the number of fences are calculated. The result is a product of area and fence count. + + #+BEGIN_SRC java + ret += area * fence; + p2 += area * fetchSides(fences); + #+END_SRC + + +*** Core Logic and Functionality + - Coordinates mapping using a Map> to track character positions. + - Flood-fill algorithm using a stack to explore regions of connected characters. + - Fence counting logic to identify boundaries and different characters. + - Side fetching logic to count the number of fences arranged along rows and columns. + - Area and fence calculations for each region to compute the final result. + + + +* Day 13 +** Part 1: Parsing Input and Solving Simultaneous Equations + - Goal: Parse input, extract button coefficients and prize values, solve simultaneous equations to find valid token costs. + - Key Concepts: + - Input parsing using BufferedReader. + - Using determinants to solve simultaneous equations. + - Validating solutions for constraints (non-negative integers, valid m/n). + - Code Snippets: + - Parsing Input: + + #+BEGIN_SRC java + if (line.startsWith("Button A:")) { + String[] parts = line.split(":")[1].split(","); + current = new ButtonPrize(); + current.buttonAX = Integer.parseInt(parts[0].trim().split("\\+")[1]); + current.buttonAY = Integer.parseInt(parts[1].trim().split("\\+")[1]); + } + #+END_SRC + + - Solving Simultaneous Equations: + + #+BEGIN_SRC java + int determinant = buttonAX * buttonBY - buttonBX * buttonAY; + if (determinant == 0) return 0; // No solution + + long mNumerator = prizeX * buttonBY - prizeY * buttonBX; + long nNumerator = prizeY * buttonAX - prizeX * buttonAY; + + if (mNumerator % determinant != 0 || nNumerator % determinant != 0) return 0; + long m = mNumerator / determinant; + long n = nNumerator / determinant; + return (m < 0 || n < 0) ? 0 : m * 3 + n; // Calculate token costs + #+END_SRC + + - Challenges Faced: + - Edge cases with determinant = 0 or invalid input format. + - Ensuring no negative values for m/n. + +** Part 2: Transforming Input Data + - Goal: Modify prize values with a fixed offset before calculations. + - Key Concepts: + - Transforming input data programmatically. + - Reusing the existing calculation logic after transformation. + - Code Snippets: + - Prepending Offset to Prize Values: + + #+BEGIN_SRC java + private void prependZeroes(ButtonPrize bp) { + bp.setPrizeX(bp.getPrizeX() + 10000000000000L); + bp.setPrizeY(bp.getPrizeY() + 10000000000000L); + } + #+END_SRC + + - Reusing Logic: + + #+BEGIN_SRC java + for (ButtonPrize bp : data) { + prependZeroes(bp); + count_part2 += calculateSimultaneousEquations(bp.getButtonAX(), bp.getButtonAY(), + bp.getButtonBX(), bp.getButtonBY(), + bp.getPrizeX(), bp.getPrizeY()); + } + #+END_SRC + + - Challenges Faced: + - Avoiding modification of original input logic while adding transformations. + - Maintaining readability and modularity. + +* Day 14 +** Part 1: Simulating Robot Movement + +- Concept: Simulating the movement of robots on a grid, wrapping their positions around the edges. + - The grid has dimensions 101x103, and the robot positions wrap around when they move out of bounds. + - Wrapping is implemented using a helper method: + + #+BEGIN_SRC java + public static int wrap(int value, int max) { + return ((value % max) + max) % max; + } + #+END_SRC + +- Key Learning: Efficiently handling movement on a toroidal grid (wrap-around behavior). + +- Quadrant Assignment: + - Robots are excluded from the middle row and column (x=50, y=51). + - Quadrant assignments are based on the x and y positions: + + #+BEGIN_SRC java + if (x < 50 && y < 51) { + quadrantCounts[0]++; // Top-left + } else if (x >= 50 && y < 51) { + quadrantCounts[1]++; // Top-right + } else if (x < 50 && y >= 51) { + quadrantCounts[2]++; // Bottom-left + } else if (x >= 50 && y >= 51) { + quadrantCounts[3]++; // Bottom-right + } + #+END_SRC + +- Safety Factor Calculation: + - The safety factor is the product of the number of robots in each quadrant: + + #+BEGIN_SRC java + int safetyFactor = 1; + for (int count : quadrantCounts) { + safetyFactor *= count; + } + #+END_SRC + +** Part 2: Identifying Patterns in Robot Positions + +- Concept: Simulating grid states to find a specific pattern of robot alignment. + - Robots move based on their initial velocity, and their positions are updated iteratively. + - A grid is used to track robot positions, and columns are checked for specific patterns. + +- Key Learning: Efficiently detecting consecutive robot positions in a grid column. + +- Grid Initialization: + - A helper method initializes a 2D grid with given dimensions: + + #+BEGIN_SRC java + private int[][] initializeGrid(int rows, int cols) { + return new int[rows][cols]; + } + #+END_SRC + +- Position Calculation: + - New positions are computed using the robot's velocity and current step, with wrapping: + + #+BEGIN_SRC java + private int[] calculateNewPosition(int[] position, int[] velocity, int step, int[] tileDimensions) { + return new int[] { + (position[0] + step * (tileDimensions[0] + velocity[0])) % tileDimensions[0], + (position[1] + step * (tileDimensions[1] + velocity[1])) % tileDimensions[1] + }; + } + #+END_SRC + +- Pattern Detection: + - A helper method checks for consecutive robots in a column: + + #+BEGIN_SRC java + private boolean hasConsecutiveInRow(List positions, int requiredConsecutive) { + Collections.sort(positions); + int consecutiveCount = 0; + + for (int i = 1; i < positions.size(); i++) { + if (positions.get(i) - positions.get(i - 1) == 1) { + consecutiveCount++; + if (consecutiveCount >= requiredConsecutive) { + return true; + } + } else { + consecutiveCount = 0; + } + } + return false; + } + #+END_SRC + +- Stopping Condition: + - Simulation stops when a column has at least requiredConsecutive robots aligned. + +--- + +### Supporting Components + +- Data Representation: + - PointAndVelocity encapsulates robot data, including position (PX, PY) and velocity (VX, VY): + + #+BEGIN_SRC java + public static class PointAndVelocity { + private int PX; + private int PY; + private int VX; + private int VY; + + // Getters and setters + public int getVX() { return VX; } + public void setVX(int vX) { VX = vX; } + public int getVY() { return VY; } + public void setVY(int vY) { VY = vY; } + public int getPX() { return PX; } + public void setPX(int pX) { PX = pX; } + public int getPY() { return PY; } + public void setPY(int pY) { PY = pY; } + } + #+END_SRC + +- Input Parsing: + - Robot data is parsed from a file or input list. Each robot's position and velocity are extracted: + + #+BEGIN_SRC java + private List getPointAndVelocities() { + List pvs = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader(new FileReader(fetchFilePath()))) { + String line; + while ((line = reader.readLine()) != null) { + String[] parts = line.split(" "); + PointAndVelocity pav = new PointAndVelocity(); + pav.setPX(Integer.parseInt(parts[0].split(",")[0].replace("p=", ""))); + pav.setPY(Integer.parseInt(parts[0].split(",")[1].replace("p=", ""))); + pav.setVX(Integer.parseInt(parts[1].split(",")[0].replace("v=", ""))); + pav.setVY(Integer.parseInt(parts[1].split(",")[1].replace("v=", ""))); + pvs.add(pav); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return pvs; + } + #+END_SRC + +- Simulation Control: + - Part 1 iterates for 100 steps, while Part 2 continues until a pattern is found or the maximum steps are reached. + +* diff --git a/20241210001206-leetcode_notes.org b/20241210001206-leetcode_notes.org new file mode 100755 index 0000000..2e05b49 --- /dev/null +++ b/20241210001206-leetcode_notes.org @@ -0,0 +1,17 @@ +:PROPERTIES: +:ID: 9d1cfccc-8da7-41a3-b435-9857f0abe441 +:END: +#+title: leetcode_notes +#+filetags: :index:notes:leetcode:coding: + +* Resources: +To work through: + +- https://www.youtube.com/watch?v=lvO88XxNAzs&list=LL&index=1&ab_channel=stoneycodes + +* Start +[[id:275988a8-59d8-40c8-a8b4-47118d6eb834][big-o-complexity]] + +[[id:086ca3ca-39ec-4d37-b56d-b6d9f51e6873][how-to-solve-leetcode]] + +[[id:93a43a24-6861-40c4-b45b-581977bb55cf][leetcode-arrays]] diff --git a/20241210001206-leetcode_notes.org~ b/20241210001206-leetcode_notes.org~ new file mode 100755 index 0000000..02a3224 --- /dev/null +++ b/20241210001206-leetcode_notes.org~ @@ -0,0 +1,17 @@ +:PROPERTIES: +:ID: 9d1cfccc-8da7-41a3-b435-9857f0abe441 +:END: +#+title: Leetcode Notes +#+filetags: :notes:leetcode:coding:technical: + +* Resources: +To work through: + +- https://www.youtube.com/watch?v=lvO88XxNAzs&list=LL&index=1&ab_channel=stoneycodes + +* Start +[[id:275988a8-59d8-40c8-a8b4-47118d6eb834][big-o-complexity]] + +[[id:086ca3ca-39ec-4d37-b56d-b6d9f51e6873][how-to-solve-leetcode]] + +[[id:93a43a24-6861-40c4-b45b-581977bb55cf][leetcode-arrays]] diff --git a/20241210004247-emacs_moc.org b/20241210004247-emacs_moc.org new file mode 100755 index 0000000..6b39992 --- /dev/null +++ b/20241210004247-emacs_moc.org @@ -0,0 +1,26 @@ +:PROPERTIES: +:ID: 8fa3f476-6152-45f4-b618-50f1e4bce46c +:END: +#+title: emacs_moc +#+filetags: :resources:index:docs:emacs: + +The purpose of this file is to store things related to emacs (that being packages, or community projects that i stumble across). +- [[id:034abe27-ca14-4dc0-9a3f-b8d0e1f26342][emacs-stuff-org-roam]] for roam related things +- [[id:8e5e9498-ff3c-48e7-aab5-6e94b2e41ccb][emacs-stuff-gtd]] +- [[id:966175d4-3b58-4abc-9b41-08cbf328dd87][emacs-stuff-keybindings]] +- [[id:7e79e4c5-383d-450f-882c-33d4f87ba1b5][emacs-stuff-elisp]] +- [[id:2ab0fa3f-8ac6-4af2-8cd4-1dd490fb19c3][emacs-stuff-magit]] +- [[id:45CC3AF5-5E20-4B03-A36C-8D4BDD5CBB13][emacs-stuff-evil]] + + +- A link that contains all the key bindings for emacs: [[http://xahlee.info/emacs/emacs/emacs_keybinding_list.html][Keybindings list]] +- the theme 'ef-dream' repository: [[https://github.com/protesilaos/ef-themes][ef-themes]] +- something to look into: [[https://github.com/mickeynp/combobulate][combobulate]] +- the use package git hub: [[https://github.com/jwiegley/use-package][use-package]] +- hamacs (someones emacs config) [[https://www.howardabrams.com/hamacs/][hamacs]] +- projectile doc [[https://docs.projectile.mx/projectile/configuration.html][proj doc]] +- doom style dashboard [[https://gist.github.com/DevelopmentCool2449/ffc91d1d9b7b16e0f48402b698386f3d#file-dashboard-doom-style-el][doom dash]] +- soft charcoal theme [[https://github.com/mswift42/soft-charcoal-theme?tab=readme-ov-file][sc]] +- the theme im currently using: [[https://github.com/ogdenwebb/emacs-kaolin-themes?tab=readme-ov-file][kaolin]] +- config: [[https://gitlab.com/dwt1/configuring-emacs][config-dwt]] +- simplenote to self hosted: [[https://ru2saig.github.io/posts/switching-from-simplenote-to-a-self-hosted-approach-nextcloud-orgzly-and-emacs/][Link]] diff --git a/20241210004247-emacs_stuff.org b/20241210004247-emacs_stuff.org new file mode 100644 index 0000000..8db62c3 --- /dev/null +++ b/20241210004247-emacs_stuff.org @@ -0,0 +1,26 @@ +:PROPERTIES: +:ID: 8fa3f476-6152-45f4-b618-50f1e4bce46c +:END: +#+title: emacs_moc +#+filetags: :emacs:moc: + +The purpose of this file is to store things related to emacs (that being packages, or community projects that i stumble across). +- [[id:034abe27-ca14-4dc0-9a3f-b8d0e1f26342][emacs-stuff-org-roam]] for roam related things +- [[id:8e5e9498-ff3c-48e7-aab5-6e94b2e41ccb][emacs-stuff-gtd]] +- [[id:966175d4-3b58-4abc-9b41-08cbf328dd87][emacs-stuff-keybindings]] +- [[id:7e79e4c5-383d-450f-882c-33d4f87ba1b5][emacs-stuff-elisp]] +- [[id:2ab0fa3f-8ac6-4af2-8cd4-1dd490fb19c3][emacs-stuff-magit]] +- [[id:45CC3AF5-5E20-4B03-A36C-8D4BDD5CBB13][emacs-stuff-evil]] +[[id:7d2e867e-f091-4362-a583-453f732207fe][emacs-stuff-org-publish]] + +- A link that contains all the key bindings for emacs: [[http://xahlee.info/emacs/emacs/emacs_keybinding_list.html][Keybindings list]] +- the theme 'ef-dream' repository: [[https://github.com/protesilaos/ef-themes][ef-themes]] +- something to look into: [[https://github.com/mickeynp/combobulate][combobulate]] +- the use package git hub: [[https://github.com/jwiegley/use-package][use-package]] +- hamacs (someones emacs config) [[https://www.howardabrams.com/hamacs/][hamacs]] +- projectile doc [[https://docs.projectile.mx/projectile/configuration.html][proj doc]] +- doom style dashboard [[https://gist.github.com/DevelopmentCool2449/ffc91d1d9b7b16e0f48402b698386f3d#file-dashboard-doom-style-el][doom dash]] +- soft charcoal theme [[https://github.com/mswift42/soft-charcoal-theme?tab=readme-ov-file][sc]] +- the theme im currently using: [[https://github.com/ogdenwebb/emacs-kaolin-themes?tab=readme-ov-file][kaolin]] +- config: [[https://gitlab.com/dwt1/configuring-emacs][config-dwt]] +- simplenote to self hosted: [[https://ru2saig.github.io/posts/switching-from-simplenote-to-a-self-hosted-approach-nextcloud-orgzly-and-emacs/][Link]] diff --git a/20241210004247-emacs_stuff.org~ b/20241210004247-emacs_stuff.org~ new file mode 100644 index 0000000..8fbebe2 --- /dev/null +++ b/20241210004247-emacs_stuff.org~ @@ -0,0 +1,26 @@ +:PROPERTIES: +:ID: 8fa3f476-6152-45f4-b618-50f1e4bce46c +:END: +#+title: emacs_moc +#+filetags: :emacs:moc: + +The purpose of this file is to store things related to emacs (that being packages, or community projects that i stumble across). +- [[id:034abe27-ca14-4dc0-9a3f-b8d0e1f26342][emacs-stuff-org-roam]] for roam related things +- [[id:8e5e9498-ff3c-48e7-aab5-6e94b2e41ccb][emacs-stuff-gtd]] +- [[id:966175d4-3b58-4abc-9b41-08cbf328dd87][emacs-stuff-keybindings]] +- [[id:7e79e4c5-383d-450f-882c-33d4f87ba1b5][emacs-stuff-elisp]] +- [[id:2ab0fa3f-8ac6-4af2-8cd4-1dd490fb19c3][emacs-stuff-magit]] +- [[id:45CC3AF5-5E20-4B03-A36C-8D4BDD5CBB13][emacs-stuff-evil]] + + +- A link that contains all the key bindings for emacs: [[http://xahlee.info/emacs/emacs/emacs_keybinding_list.html][Keybindings list]] +- the theme 'ef-dream' repository: [[https://github.com/protesilaos/ef-themes][ef-themes]] +- something to look into: [[https://github.com/mickeynp/combobulate][combobulate]] +- the use package git hub: [[https://github.com/jwiegley/use-package][use-package]] +- hamacs (someones emacs config) [[https://www.howardabrams.com/hamacs/][hamacs]] +- projectile doc [[https://docs.projectile.mx/projectile/configuration.html][proj doc]] +- doom style dashboard [[https://gist.github.com/DevelopmentCool2449/ffc91d1d9b7b16e0f48402b698386f3d#file-dashboard-doom-style-el][doom dash]] +- soft charcoal theme [[https://github.com/mswift42/soft-charcoal-theme?tab=readme-ov-file][sc]] +- the theme im currently using: [[https://github.com/ogdenwebb/emacs-kaolin-themes?tab=readme-ov-file][kaolin]] +- config: [[https://gitlab.com/dwt1/configuring-emacs][config-dwt]] +- simplenote to self hosted: [[https://ru2saig.github.io/posts/switching-from-simplenote-to-a-self-hosted-approach-nextcloud-orgzly-and-emacs/][Link]] diff --git a/20241210004329-org_roam.org b/20241210004329-org_roam.org new file mode 100755 index 0000000..12459d8 --- /dev/null +++ b/20241210004329-org_roam.org @@ -0,0 +1,31 @@ +:PROPERTIES: +:ID: 034abe27-ca14-4dc0-9a3f-b8d0e1f26342 +:END: +#+title: emacs-stuff-org-roam +#+filetags: :emacs:roam:org:docs:resources: +This base will contain information on org roam. Although its closely linked to the [[id:8e5e9498-ff3c-48e7-aab5-6e94b2e41ccb][emacs-stuff-gtd]] node, that one will contain articles, notes and videos related to how to get things done. + +[[https://www.orgroam.com/manual.html][User Manual]] + +Here is the current config in my init.el +#+BEGIN_SRC elisp + ;;roam config + (use-package org-roam + :ensure t + :custom + (org-roam-directory "~/master-folder/org_files/org_roam") + :bind (("C-c n l" . org-roam-buffer-toggle) + ("C-c n f" . org-roam-node-find) + ("C-c n i" . org-roam-node-insert)) + :config + (org-roam-setup)) +#+END_SRC + + +- for the org-roam-ui (the graphical interface for nodes): [[https://github.com/org-roam/org-roam-ui][org-roam-ui]] +- an article: [[https://gist.github.com/nickanderson/00005b5b03e323a65ada98c5fa5ebb11][example-org-roam-workflow.org]] +- An article to read: [[https://cmdln.org/2023/03/25/how-i-org-in-2023/][How i use org in 2023]] +- An article: [[https://jethrokuan.github.io/org-roam-guide/][org-roam-guide]] +- An article: [[https://ianjones.info/own-your-second-brain][Own your second brain]] +- article: [[https://honnef.co/articles/my-org-roam-workflows-for-taking-notes-and-writing-articles/][my-org-roam-workflows-for-taking-notes-and-writing-articles]] +- article: [[https://michaelneuper.com/posts/how-i-use-org-roam-to-takes-notes-for-cs/][how-i-use-org-roam-to-takes-notes-for-cs]] diff --git a/20241210004329-org_roam.org~ b/20241210004329-org_roam.org~ new file mode 100755 index 0000000..044c0c8 --- /dev/null +++ b/20241210004329-org_roam.org~ @@ -0,0 +1,29 @@ +:PROPERTIES: +:ID: 034abe27-ca14-4dc0-9a3f-b8d0e1f26342 +:END: +#+title: emacs-stuff-org-roam +This base will contain information on org roam. Although its closely linked to the [[id:8e5e9498-ff3c-48e7-aab5-6e94b2e41ccb][emacs-stuff-gtd]] node, that one will contain articles, notes and videos related to how to get things done. + + +Here is the current config in my init.el +#+BEGIN_SRC elisp + ;;roam config + (use-package org-roam + :ensure t + :custom + (org-roam-directory "~/master-folder/org_files/org_roam") + :bind (("C-c n l" . org-roam-buffer-toggle) + ("C-c n f" . org-roam-node-find) + ("C-c n i" . org-roam-node-insert)) + :config + (org-roam-setup)) +#+END_SRC + + +- for the org-roam-ui (the graphical interface for nodes): [[https://github.com/org-roam/org-roam-ui][org-roam-ui]] +- an article: [[https://gist.github.com/nickanderson/00005b5b03e323a65ada98c5fa5ebb11][example-org-roam-workflow.org]] +- An article to read: [[https://cmdln.org/2023/03/25/how-i-org-in-2023/][How i use org in 2023]] +- An article: [[https://jethrokuan.github.io/org-roam-guide/][org-roam-guide]] +- An article: [[https://ianjones.info/own-your-second-brain][Own your second brain]] +- article: [[https://honnef.co/articles/my-org-roam-workflows-for-taking-notes-and-writing-articles/][my-org-roam-workflows-for-taking-notes-and-writing-articles]] +- article: [[https://michaelneuper.com/posts/how-i-use-org-roam-to-takes-notes-for-cs/][how-i-use-org-roam-to-takes-notes-for-cs]] diff --git a/20241210004453-gtd.org b/20241210004453-gtd.org new file mode 100755 index 0000000..39d2aa1 --- /dev/null +++ b/20241210004453-gtd.org @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: 8e5e9498-ff3c-48e7-aab5-6e94b2e41ccb +:END: +#+title: emacs-stuff-gtd +#+filetags: :emacs:resources: + +- article: [[https://hamberg.no/gtd][gtd]] diff --git a/20241210004453-gtd.org~ b/20241210004453-gtd.org~ new file mode 100755 index 0000000..17f3a1c --- /dev/null +++ b/20241210004453-gtd.org~ @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: 8e5e9498-ff3c-48e7-aab5-6e94b2e41ccb +:END: +#+title: emacs-stuff-gtd +#+filetags: :emacs:gtd:resources: + +- article: [[https://hamberg.no/gtd][gtd]] diff --git a/20241210012703-fyp.org b/20241210012703-fyp.org new file mode 100755 index 0000000..f566ee7 --- /dev/null +++ b/20241210012703-fyp.org @@ -0,0 +1,27 @@ +:PROPERTIES: +:ID: 7d199fbe-b0e7-48fd-b8a1-793044dbea01 +:END: +#+title: fyp +#+filetags: :index:uni: + +In this file i will include things related to my final year *project*. + +- The idea: +*A web platform for users to take notes with an ai assistant* + +- Migrating to cloud databse. +I was originally intending to use AWS RDS with an e2c instance, but realised that the learning curve was too great, and that i needed a simpler solution. +On the <2024-12-09 Mon> I decided to try this: exporting the current vm i had running and run in on oracle cloud. +The results for this: + +The UML for this project: [[id:4a8edaed-9ebd-402b-9c5f-7a0cb4399102][uml_fyp]] +@startuml +Alice -> Bob: Authentication Request +Bob --> Alice: Authentication Response + +Alice -> Bob: Another authentication Request +Alice <-- Bob: Another authentication Response +@enduml + + +[[id:26b2ed9a-cb81-4c43-bc63-6b3c8ffa3bf1][fyp-report-planning]] diff --git a/20241210012703-fyp.org~ b/20241210012703-fyp.org~ new file mode 100755 index 0000000..5fae555 --- /dev/null +++ b/20241210012703-fyp.org~ @@ -0,0 +1,27 @@ +:PROPERTIES: +:ID: 7d199fbe-b0e7-48fd-b8a1-793044dbea01 +:END: +#+title: FYP +#+filetags: :index:uni:fyp: + +In this file i will include things related to my final year *project*. + +- The idea: +*A web platform for users to take notes with an ai assistant* + +- Migrating to cloud databse. +I was originally intending to use AWS RDS with an e2c instance, but realised that the learning curve was too great, and that i needed a simpler solution. +On the <2024-12-09 Mon> I decided to try this: exporting the current vm i had running and run in on oracle cloud. +The results for this: + +The UML for this project: [[id:4a8edaed-9ebd-402b-9c5f-7a0cb4399102][UML_FYP]] +@startuml +Alice -> Bob: Authentication Request +Bob --> Alice: Authentication Response + +Alice -> Bob: Another authentication Request +Alice <-- Bob: Another authentication Response +@enduml + + +[[id:26b2ed9a-cb81-4c43-bc63-6b3c8ffa3bf1][fyp-report-planning]] diff --git a/20241210152650-uni.org b/20241210152650-uni.org new file mode 100644 index 0000000..7987481 --- /dev/null +++ b/20241210152650-uni.org @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: 797d6e3e-98eb-4bc7-88b6-e096ef7306ad +:END: +#+title: uni_moc +#+filetags: :uni:moc: +* Modules: +- [[id:5443ed1c-bb7f-4eb4-9c96-d12648dd2291][tpis]] +- [[id:556d10d1-1c74-4d9f-a398-39cb3bd5d935][afp]] +- [[id:c69e4c4d-2fb4-4cf1-a835-a235cf6db8e9][ise]] +- [[id:3acffb66-bc1a-4661-904f-c5447b3c3488][advanced-networking]] +* Final Year Project +- [[id:7d199fbe-b0e7-48fd-b8a1-793044dbea01][fyp]] Final Year Project diff --git a/20241210152650-uni.org~ b/20241210152650-uni.org~ new file mode 100644 index 0000000..929991a --- /dev/null +++ b/20241210152650-uni.org~ @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: 797d6e3e-98eb-4bc7-88b6-e096ef7306ad +:END: +#+title: uni_moc +#+filetags: :uni:index: +* Modules: +- [[id:5443ed1c-bb7f-4eb4-9c96-d12648dd2291][tpis]] +- [[id:556d10d1-1c74-4d9f-a398-39cb3bd5d935][afp]] +- [[id:c69e4c4d-2fb4-4cf1-a835-a235cf6db8e9][ise]] +- [[id:3acffb66-bc1a-4661-904f-c5447b3c3488][advanced-networking]] +* Final Year Project +- [[id:7d199fbe-b0e7-48fd-b8a1-793044dbea01][fyp]] Final Year Project diff --git a/20241210152650-uni_moc.org b/20241210152650-uni_moc.org new file mode 100755 index 0000000..547a9f2 --- /dev/null +++ b/20241210152650-uni_moc.org @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: 797d6e3e-98eb-4bc7-88b6-e096ef7306ad +:END: +#+title: uni_moc +#+filetags: :uni:index: +* Modules: +- [[id:5443ed1c-bb7f-4eb4-9c96-d12648dd2291][TPIS]] +- [[id:556d10d1-1c74-4d9f-a398-39cb3bd5d935][AFP]] +- [[id:c69e4c4d-2fb4-4cf1-a835-a235cf6db8e9][ISE]] +- [[id:3acffb66-bc1a-4661-904f-c5447b3c3488][advanced-networking]] +* Final Year Project +- [[id:7d199fbe-b0e7-48fd-b8a1-793044dbea01][FYP]] Final Year Project diff --git a/20241210152713-tpis.org b/20241210152713-tpis.org new file mode 100755 index 0000000..afefa78 --- /dev/null +++ b/20241210152713-tpis.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 5443ed1c-bb7f-4eb4-9c96-d12648dd2291 +:END: +#+title: tpis +#+filetags: :uni: + +Teaching Programming In School +- Proposal: [[file:~/master-folder/misc/proposal.pdf][Proposal for the module]] +- <2024-12-10 Tue> - Presentation diff --git a/20241210152713-tpis.org~ b/20241210152713-tpis.org~ new file mode 100755 index 0000000..1815e16 --- /dev/null +++ b/20241210152713-tpis.org~ @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 5443ed1c-bb7f-4eb4-9c96-d12648dd2291 +:END: +#+title: TPIS +#+filetags: :uni:tpis: + +Teaching Programming In School +- Proposal: [[file:~/master-folder/misc/proposal.pdf][Proposal for the module]] +- <2024-12-10 Tue> - Presentation diff --git a/20241210232054-uml_fyp.org b/20241210232054-uml_fyp.org new file mode 100755 index 0000000..46e9151 --- /dev/null +++ b/20241210232054-uml_fyp.org @@ -0,0 +1,708 @@ +:PROPERTIES: +:ID: 4a8edaed-9ebd-402b-9c5f-7a0cb4399102 +:END: +#+title: uml_fyp +#+filetags: :uni: + + +* Class diagram +** class 2: +@startuml +skinparam classAttributeIconSize 0 +skinparam packageStyle rectangle +skinparam linetype ortho +left to right direction + +' Entity Layer +rectangle "Entity Layer" as EntityLayer #E3F2FD { + class User { + +id: Long + +roles: Set + +firstName: String + +lastName: String + +username: String + +password: String + +confirmPassword: String + +email: String + +phoneNumber: String + +picture: byte[] + } + + class Workspace { + +id: Long + +name: String + +description: String + +fileCount: int + +noteCount: int + +lastAccessed: LocalDateTime + +dateCreated: LocalDateTime + } + + class Library { + +id: Long + +name: String + +description: String + +dateCreated: LocalDateTime + +lastAccessed: LocalDateTime + } + + class Page { + +id: Long + +name: String + +workspaceId: Long + +content: Text + +height: int + +width: int + } + + class FileMetadata { + +id: Long + +fileUrl: String + +userId: String + +description: String + +fileData: byte[] + +fileName: String + +fileType: String + } + + class AiChat { + +id: Long + +name: String + +workspaceId: Long + +createdAt: LocalDateTime + +messages: List + } +} + +' Repository Layer +rectangle "Repository Layer" as RepositoryLayer #E8F5E9 { + class AiChatRepository + class FileMetadataRepository + class LibraryRepository + class PageRepository + class UserRepository + class WorkspaceRepository + class RegisterRepository + class AuthRepository +} + +' Service Layer +rectangle "Service Layer" as ServiceLayer #FFF3E0 { + class AiChatService + class AuthService + class FileMetadataService + class LibraryService + class PageService + class RegisterService + class UserService + class WorkspaceService +} + +' Controller Layer +rectangle "Controller Layer" as ControllerLayer #F3E5F5 { + class AiChatController + class AiChatWebSocketController + class AuthController + class FileMetadataController + class LibraryController + class PageController + class RegisterController + class UserController + class WorkspaceController +} + +' External Python Microservice +rectangle "External NLP Module (Python FastAPI)" as ExternalNLP #FCE4EC { + class FastAPINLPServer { + +/extract_text + +/keywords + +/tfidf_keywords + +/summarize + +/ner + } +} + + + + rectangle "Frontend Core" as FrontendCore { + class AboutComponent + class AccessibilityComponent + class ContactComponent + class ForgotPasswordComponent + class LoginComponent + class LoginService + class PrivacyComponent + class RegisterComponent + class RegisterService + class SecurityComponent + class TermsComponent + + LoginComponent --> LoginService + RegisterComponent --> RegisterService + + LoginService ..> AuthController : REST + RegisterService ..> RegisterController : REST + } + + rectangle "Frontend Entities" as FrontendEntities { + class AiChatComponent + class DashboardComponent + class DefaultLayoutComponent + class HomeComponent + class LibraryComponent + class ProfileComponent + class WorkspacePageComponent + class WorkspacesComponent + + class AiChatServiceFE + class DashboardServiceFE + class LayoutServiceFE + class HomeServiceFE + class LibraryServiceFE + class ProfileServiceFE + class WorkspacePageServiceFE + class WorkspacesServiceFE + + AiChatComponent --> AiChatServiceFE + DashboardComponent --> DashboardServiceFE + DefaultLayoutComponent --> LayoutServiceFE + DefaultLayoutComponent --> LoginComponent + DefaultLayoutComponent --> RegisterComponent + HomeComponent --> HomeServiceFE + LibraryComponent --> LibraryServiceFE + ProfileComponent --> ProfileServiceFE + WorkspacePageComponent --> WorkspacePageServiceFE + WorkspacesComponent --> WorkspacesServiceFE + + ForgotPasswordComponent ..> UserController : REST + AiChatServiceFE ..> AiChatController : REST + AiChatServiceFE ..> AiChatWebSocketController : WebSocket + + DashboardServiceFE ..> WorkspaceController : REST + DashboardServiceFE ..> PageController : REST + DashboardServiceFE ..> AiChatController : REST + + LayoutServiceFE ..> UserController : REST + + HomeServiceFE ..> AuthController : REST + + LibraryServiceFE ..> LibraryController : REST + LibraryServiceFE ..> FileMetadataController : REST + + ProfileServiceFE ..> UserController : REST + + WorkspacePageServiceFE ..> PageController : REST + WorkspacePageServiceFE ..> FileMetadataController : REST + WorkspacePageServiceFE ..> AiChatController : REST + + WorkspacesServiceFE ..> WorkspaceController : REST + AboutComponent --> ContactComponent + AboutComponent --> TermsComponent + AboutComponent --> PrivacyComponent + } + + class AngularClient + AngularClient --> FrontendCore + AngularClient --> FrontendEntities + AngularClient ..> FastAPINLPServer : REST + + +' Entity Relationships +User "1" --> "many" Library +User "1" --> "many" Workspace +Library "1" --> "many" Workspace +Library "1" --> "many" FileMetadata +Workspace "1" --> "many" Page +Workspace "1" --> "many" FileMetadata +Workspace "1" --> "many" AiChat + +' Controller → Service +AiChatController --> AiChatService +AiChatWebSocketController --> AiChatService +AuthController --> AuthService +FileMetadataController --> FileMetadataService +LibraryController --> LibraryService +PageController --> PageService +RegisterController --> RegisterService +UserController --> UserService +WorkspaceController --> WorkspaceService + +' Service → Repository +AiChatService --> AiChatRepository +AuthService --> AuthRepository +FileMetadataService --> FileMetadataRepository +LibraryService --> LibraryRepository +PageService --> PageRepository +RegisterService --> RegisterRepository +UserService --> UserRepository +WorkspaceService --> WorkspaceRepository + +' Repository → Entity +AiChatRepository --> AiChat +FileMetadataRepository --> FileMetadata +LibraryRepository --> Library +PageRepository --> Page +UserRepository --> User +WorkspaceRepository --> Workspace +RegisterRepository --> User +AuthRepository --> User + +@enduml + +** authentication sequence diagram: +@startuml +title Full Authentication Flow - Registration to Secured Access + +skinparam shadowing true +skinparam packageStyle rectangle +skinparam handwritten false +skinparam linetype polyline +skinparam ParticipantPadding 20 +skinparam maxMessageSize 150 + +actor User + +== Registration Process == + +box "Client" #E3F2FD + participant UserClient as "User" +end box + +box "Backend - Registration" #E8F5E9 + participant RegisterController + participant UserService +end box + +UserClient -> RegisterController : POST /register\n(username, password, confirmPassword) +RegisterController -> RegisterController : Check if passwords match +alt Passwords do not match + RegisterController --> UserClient : 400 Bad Request (Passwords mismatch) + return +end +RegisterController -> RegisterController : Hash password (BCrypt) +RegisterController -> RegisterController : Load default profile image +RegisterController -> UserService : createUser(user) +RegisterController --> UserClient : 200 OK (User Created) + +== Authentication Process == + +box "Backend - Authentication" #FFF3E0 + participant AuthController + participant AuthenticationManager + participant JwtUtil +end box + +UserClient -> AuthController : POST /auth/login\n(username, password) +AuthController -> AuthenticationManager : Authenticate credentials +alt Valid credentials + AuthController -> JwtUtil : generateToken(userDetails, userId) + AuthController --> UserClient : 200 OK + JWT +else Invalid credentials + AuthController --> UserClient : 401 Unauthorized + return +end + +== Accessing a Protected API == + +box "Security Filter Chain" #F3E5F5 + participant JwtRequestFilter + participant UserDetailsService + participant JwtUtilFilter as "JwtUtil" +end box + +UserClient -> JwtRequestFilter : Request with Authorization header +JwtRequestFilter -> JwtUtilFilter : extractUsername(jwt) +JwtRequestFilter -> UserDetailsService : loadUserByUsername +JwtRequestFilter -> JwtUtilFilter : validateToken(jwt, userDetails) +alt Valid token + JwtRequestFilter -> SecurityContext : Set authentication +else Invalid token + JwtRequestFilter -> JwtRequestFilter : Log and skip authentication +end +JwtRequestFilter --> UserClient : Continue filter chain + +== @JwtRequired Secured Method Access == + +box "AOP - Method Security" #E1F5FE + participant JwtAspect + participant JwtUtilAspect as "JwtUtil" +end box + +UserClient -> JwtAspect : Call method annotated with @JwtRequired +JwtAspect -> JwtAspect : Extract JWT from header +JwtAspect -> JwtUtilAspect : extractUsername(jwt) +JwtAspect -> SecurityContext : Get UserDetails +JwtAspect -> JwtUtilAspect : validateToken(jwt, userDetails) +alt Token valid and user matches + JwtAspect --> UserClient : Proceed to method execution +else Invalid/mismatched token + JwtAspect --> UserClient : Unauthorized exception + return +end + +@enduml + +** class +@startuml +skinparam classAttributeIconSize 0 +skinparam packageStyle rectangle + +package "High-Level Overview" { + + ' Controller Layer + package "Controller Layer" { + class AiChatController + class AiChatWebSocketController + class AuthController + class FileMetadataController + class LibraryController + class PageController + class RegisterController + class UserController + class WorkspaceController + } + + ' Service Layer + package "Service Layer" { + class AiChatService + class AuthService + class FileMetadataService + class LibraryService + class PageService + class RegisterService + class UserService + class WorkspaceService + } + + ' Repository Layer + package "Repository Layer" { + class AiChatRepository + class FileMetadataRepository + class LibraryRepository + class PageRepository + class UserRepository + class WorkspaceRepository + class RegisterRepository + class AuthRepository + } + + ' Entity Layer + package "Entity Layer" { + + class User { + +id: Long + +roles: Set + +firstName: String + +lastName: String + +username: String + +password: String + +confirmPassword: String + +email: String + +phoneNumber: String + +picture: byte[] + } + + class Workspace { + +id: Long + +name: String + +description: String + +fileCount: int + +noteCount: int + +lastAccessed: LocalDateTime + +dateCreated: LocalDateTime + } + + class Library { + +id: Long + +name: String + +description: String + +dateCreated: LocalDateTime + +lastAccessed: LocalDateTime + } + + class Page { + +id: Long + +name: String + +workspaceId: Long + +content: Text + +height: int + +width: int + } + + class FileMetadata { + +id: Long + +fileUrl: String + +userId: String + +description: String + +fileData: byte[] + +fileName: String + +fileType: String + } + + class AiChat { + +id: Long + +name: String + +workspaceId: Long + +createdAt: LocalDateTime + +messages: List + } + } + + ' Python NLP Microservice + package "External NLP Module (Python FastAPI)" { + class FastAPINLPServer { + +/extract_text + +/keywords + +/tfidf_keywords + +/summarize + +/ner + } + } + + ' Entity Relationships + User "1" --> "many" Library + User "1" --> "many" Workspace + Library "1" --> "many" Workspace + Library "1" --> "many" FileMetadata + Workspace "1" --> "many" Page + Workspace "1" --> "many" FileMetadata + Workspace "1" --> "many" AiChat + + ' Controller → Service + AiChatController --> AiChatService + AiChatWebSocketController --> AiChatService + AuthController --> AuthService + FileMetadataController --> FileMetadataService + LibraryController --> LibraryService + PageController --> PageService + RegisterController --> RegisterService + UserController --> UserService + WorkspaceController --> WorkspaceService + + ' Service → Repository + AiChatService --> AiChatRepository + AuthService --> AuthRepository + FileMetadataService --> FileMetadataRepository + LibraryService --> LibraryRepository + PageService --> PageRepository + RegisterService --> RegisterRepository + UserService --> UserRepository + WorkspaceService --> WorkspaceRepository + + ' Repository → Entity + AiChatRepository --> AiChat + FileMetadataRepository --> FileMetadata + LibraryRepository --> Library + PageRepository --> Page + UserRepository --> User + WorkspaceRepository --> Workspace + RegisterRepository --> User + AuthRepository --> User + + ' Frontend → NLP Server + +} + +' Frontend Component +package "Frontend" { + class AngularClient +} + +' Angular communicates with both backends +AngularClient ..> AiChatController : REST +AngularClient ..> AiChatWebSocketController : WebSocket +AngularClient ..> AuthController : REST +AngularClient ..> PageController : REST +AngularClient ..> FileMetadataController : REST +AngularClient ..> WorkspaceController : REST +AngularClient ..> LibraryController : REST +AngularClient ..> RegisterController : REST +AngularClient ..> UserController : REST +AngularClient ..> FastAPINLPServer : REST + +@enduml +** client-server +@startuml +!pragma layout smetana + +actor User + +package "Client Side (Angular)" { + [Angular App] as Frontend +} + +package "Spring Boot Backend" { + [Auth Controller] + [Note Controller] + [NLP Proxy Service] + [Spring Boot App] as Backend +} + +package "Database Layer" { + database "PostgreSQL Database" as DB +} + +package "FastAPI NLP Server (Port 9010)" { + [FastAPI NLP Service] as NLP + [Summarisation Endpoint] as SumEndpoint + [Keyword Extraction] as KeywordEndpoint + [NER Endpoint] as NEREndpoint +} + +package "External API" { + [OpenAI API] +} + +' Interactions +User --> Frontend : Uses Web Interface +Frontend --> Backend : REST API Calls +Backend --> [Auth Controller] : Handles Auth +Backend --> [Note Controller] : Handles Notes +Backend --> [NLP Proxy Service] : Handles NLP Requests +[Auth Controller] --> DB : Access users table +[Note Controller] --> DB : Access notes table +[NLP Proxy Service] --> NLP : HTTP (port 9010) +NLP --> SumEndpoint : /summarise +NLP --> KeywordEndpoint : /keywords +NLP --> NEREndpoint : /ner +SumEndpoint --> [OpenAI API] : API call for contextual help + +note right of Frontend + Angular app includes: + - Note Editor + - Summary View + - Keyword Panel +end note + +note right of Backend + Spring Boot includes: + - Auth Controller + - Note Controller + - NLP Proxy Service (calls FastAPI) +end note + +note right of NLP + FastAPI exposes endpoints for: + - Summarisation (Pegasus) + - Keyword Extraction (TF-IDF, YAKE) + - NER (spaCy) +end note +@enduml +** high level: +@startuml +skinparam componentStyle uml2 +skinparam packageStyle rectangle + +package "Client (Frontend)" { + [Angular UI] +} + +package "Java Backend (Spring Boot)" { + [REST API Controller Layer] + [WebSocket Controller] + [Service Layer] + [Repository Layer] + [JPA Entities] +} + +package "Python NLP Service" { + [FastAPI Server] + [Summarizer (Pegasus)] + [Keyword Extractor (YAKE / TF-IDF)] + [NER (spaCy)] + [Extract Text (Canvas Object)] +} + +package "External Services" { + [OpenAI API] + [PostgreSQL DB] +} + +' Communication Arrows +[Angular UI] --> [REST API Controller Layer] : REST API (JSON) +[Angular UI] --> [WebSocket Controller] : WebSocket + +[REST API Controller Layer] --> [Service Layer] +[WebSocket Controller] --> [Service Layer] +[Service Layer] --> [Repository Layer] +[Repository Layer] ..> [JPA Entities] : uses +[Service Layer] --> [OpenAI API] : API calls + +[Service Layer] --> [FastAPI Server] : REST (NLP Requests) +[FastAPI Server] --> [Summarizer (Pegasus)] +[FastAPI Server] --> [Keyword Extractor (YAKE / TF-IDF)] +[FastAPI Server] --> [NER (spaCy)] +[FastAPI Server] --> [Extract Text (Canvas Object)] + +[Repository Layer] --> [PostgreSQL DB] : Hibernate ORM +@enduml + +** title AI Chat + Workspace Workflow +@startuml +title AI Chat + Workspace Workflow + +skinparam shadowing true +skinparam packageStyle rectangle +skinparam handwritten false +skinparam linetype polyline +skinparam ParticipantPadding 20 +skinparam maxMessageSize 150 + +actor User + +== AI Chat Session Creation == + +box "Client" #E3F2FD + participant AngularClient as "User" +end box + +box "Backend - AI Chat" #E8F5E9 + participant AiChatController + participant AiChatService + participant AiChatRepository +end box + +box "External NLP Service" #FCE4EC + participant FastAPINLPServer as "FastAPI NLP" +end box + +User -> AngularClient : Open AI Chat page +AngularClient -> AiChatController : POST /ai-chat\n(chat metadata) +AiChatController -> AiChatService : createChat(chatDto) +AiChatService -> AiChatRepository : save(chat) +AiChatService --> AiChatController : chatId +AiChatController --> AngularClient : 200 OK + chatId + +User -> AngularClient : Send message via WebSocket +AngularClient -> AiChatWebSocketController : message +AiChatWebSocketController -> AiChatService : handleMessage() + +alt Message requires NLP + AiChatService -> FastAPINLPServer : POST /summarize or /ner + FastAPINLPServer --> AiChatService : NLP result +end + +AiChatService -> AiChatRepository : update(chat with message) +AiChatWebSocketController --> AngularClient : Message response + +== Workspace Creation == + +box "Backend - Workspace" #FFF3E0 + participant WorkspaceController + participant WorkspaceService + participant WorkspaceRepository +end box + +User -> AngularClient : Create Workspace +AngularClient -> WorkspaceController : POST /workspace\n(name, description) +WorkspaceController -> WorkspaceService : createWorkspace(dto) +WorkspaceService -> WorkspaceRepository : save(workspace) +WorkspaceService --> WorkspaceController : workspaceId +WorkspaceController --> AngularClient : 200 OK + workspaceId + +@enduml + +* Screenshots: +** Draft 1: +[[file:~/master-folder/FYP/uml/draft1.png]] + diff --git a/20241210232054-uml_fyp.org~ b/20241210232054-uml_fyp.org~ new file mode 100755 index 0000000..5319a19 --- /dev/null +++ b/20241210232054-uml_fyp.org~ @@ -0,0 +1,708 @@ +:PROPERTIES: +:ID: 4a8edaed-9ebd-402b-9c5f-7a0cb4399102 +:END: +#+title: UML_FYP +#+filetags: :uni:fyp: + + +* Class diagram +** class 2: +@startuml +skinparam classAttributeIconSize 0 +skinparam packageStyle rectangle +skinparam linetype ortho +left to right direction + +' Entity Layer +rectangle "Entity Layer" as EntityLayer #E3F2FD { + class User { + +id: Long + +roles: Set + +firstName: String + +lastName: String + +username: String + +password: String + +confirmPassword: String + +email: String + +phoneNumber: String + +picture: byte[] + } + + class Workspace { + +id: Long + +name: String + +description: String + +fileCount: int + +noteCount: int + +lastAccessed: LocalDateTime + +dateCreated: LocalDateTime + } + + class Library { + +id: Long + +name: String + +description: String + +dateCreated: LocalDateTime + +lastAccessed: LocalDateTime + } + + class Page { + +id: Long + +name: String + +workspaceId: Long + +content: Text + +height: int + +width: int + } + + class FileMetadata { + +id: Long + +fileUrl: String + +userId: String + +description: String + +fileData: byte[] + +fileName: String + +fileType: String + } + + class AiChat { + +id: Long + +name: String + +workspaceId: Long + +createdAt: LocalDateTime + +messages: List + } +} + +' Repository Layer +rectangle "Repository Layer" as RepositoryLayer #E8F5E9 { + class AiChatRepository + class FileMetadataRepository + class LibraryRepository + class PageRepository + class UserRepository + class WorkspaceRepository + class RegisterRepository + class AuthRepository +} + +' Service Layer +rectangle "Service Layer" as ServiceLayer #FFF3E0 { + class AiChatService + class AuthService + class FileMetadataService + class LibraryService + class PageService + class RegisterService + class UserService + class WorkspaceService +} + +' Controller Layer +rectangle "Controller Layer" as ControllerLayer #F3E5F5 { + class AiChatController + class AiChatWebSocketController + class AuthController + class FileMetadataController + class LibraryController + class PageController + class RegisterController + class UserController + class WorkspaceController +} + +' External Python Microservice +rectangle "External NLP Module (Python FastAPI)" as ExternalNLP #FCE4EC { + class FastAPINLPServer { + +/extract_text + +/keywords + +/tfidf_keywords + +/summarize + +/ner + } +} + + + + rectangle "Frontend Core" as FrontendCore { + class AboutComponent + class AccessibilityComponent + class ContactComponent + class ForgotPasswordComponent + class LoginComponent + class LoginService + class PrivacyComponent + class RegisterComponent + class RegisterService + class SecurityComponent + class TermsComponent + + LoginComponent --> LoginService + RegisterComponent --> RegisterService + + LoginService ..> AuthController : REST + RegisterService ..> RegisterController : REST + } + + rectangle "Frontend Entities" as FrontendEntities { + class AiChatComponent + class DashboardComponent + class DefaultLayoutComponent + class HomeComponent + class LibraryComponent + class ProfileComponent + class WorkspacePageComponent + class WorkspacesComponent + + class AiChatServiceFE + class DashboardServiceFE + class LayoutServiceFE + class HomeServiceFE + class LibraryServiceFE + class ProfileServiceFE + class WorkspacePageServiceFE + class WorkspacesServiceFE + + AiChatComponent --> AiChatServiceFE + DashboardComponent --> DashboardServiceFE + DefaultLayoutComponent --> LayoutServiceFE + DefaultLayoutComponent --> LoginComponent + DefaultLayoutComponent --> RegisterComponent + HomeComponent --> HomeServiceFE + LibraryComponent --> LibraryServiceFE + ProfileComponent --> ProfileServiceFE + WorkspacePageComponent --> WorkspacePageServiceFE + WorkspacesComponent --> WorkspacesServiceFE + + ForgotPasswordComponent ..> UserController : REST + AiChatServiceFE ..> AiChatController : REST + AiChatServiceFE ..> AiChatWebSocketController : WebSocket + + DashboardServiceFE ..> WorkspaceController : REST + DashboardServiceFE ..> PageController : REST + DashboardServiceFE ..> AiChatController : REST + + LayoutServiceFE ..> UserController : REST + + HomeServiceFE ..> AuthController : REST + + LibraryServiceFE ..> LibraryController : REST + LibraryServiceFE ..> FileMetadataController : REST + + ProfileServiceFE ..> UserController : REST + + WorkspacePageServiceFE ..> PageController : REST + WorkspacePageServiceFE ..> FileMetadataController : REST + WorkspacePageServiceFE ..> AiChatController : REST + + WorkspacesServiceFE ..> WorkspaceController : REST + AboutComponent --> ContactComponent + AboutComponent --> TermsComponent + AboutComponent --> PrivacyComponent + } + + class AngularClient + AngularClient --> FrontendCore + AngularClient --> FrontendEntities + AngularClient ..> FastAPINLPServer : REST + + +' Entity Relationships +User "1" --> "many" Library +User "1" --> "many" Workspace +Library "1" --> "many" Workspace +Library "1" --> "many" FileMetadata +Workspace "1" --> "many" Page +Workspace "1" --> "many" FileMetadata +Workspace "1" --> "many" AiChat + +' Controller → Service +AiChatController --> AiChatService +AiChatWebSocketController --> AiChatService +AuthController --> AuthService +FileMetadataController --> FileMetadataService +LibraryController --> LibraryService +PageController --> PageService +RegisterController --> RegisterService +UserController --> UserService +WorkspaceController --> WorkspaceService + +' Service → Repository +AiChatService --> AiChatRepository +AuthService --> AuthRepository +FileMetadataService --> FileMetadataRepository +LibraryService --> LibraryRepository +PageService --> PageRepository +RegisterService --> RegisterRepository +UserService --> UserRepository +WorkspaceService --> WorkspaceRepository + +' Repository → Entity +AiChatRepository --> AiChat +FileMetadataRepository --> FileMetadata +LibraryRepository --> Library +PageRepository --> Page +UserRepository --> User +WorkspaceRepository --> Workspace +RegisterRepository --> User +AuthRepository --> User + +@enduml + +** authentication sequence diagram: +@startuml +title Full Authentication Flow - Registration to Secured Access + +skinparam shadowing true +skinparam packageStyle rectangle +skinparam handwritten false +skinparam linetype polyline +skinparam ParticipantPadding 20 +skinparam maxMessageSize 150 + +actor User + +== Registration Process == + +box "Client" #E3F2FD + participant UserClient as "User" +end box + +box "Backend - Registration" #E8F5E9 + participant RegisterController + participant UserService +end box + +UserClient -> RegisterController : POST /register\n(username, password, confirmPassword) +RegisterController -> RegisterController : Check if passwords match +alt Passwords do not match + RegisterController --> UserClient : 400 Bad Request (Passwords mismatch) + return +end +RegisterController -> RegisterController : Hash password (BCrypt) +RegisterController -> RegisterController : Load default profile image +RegisterController -> UserService : createUser(user) +RegisterController --> UserClient : 200 OK (User Created) + +== Authentication Process == + +box "Backend - Authentication" #FFF3E0 + participant AuthController + participant AuthenticationManager + participant JwtUtil +end box + +UserClient -> AuthController : POST /auth/login\n(username, password) +AuthController -> AuthenticationManager : Authenticate credentials +alt Valid credentials + AuthController -> JwtUtil : generateToken(userDetails, userId) + AuthController --> UserClient : 200 OK + JWT +else Invalid credentials + AuthController --> UserClient : 401 Unauthorized + return +end + +== Accessing a Protected API == + +box "Security Filter Chain" #F3E5F5 + participant JwtRequestFilter + participant UserDetailsService + participant JwtUtilFilter as "JwtUtil" +end box + +UserClient -> JwtRequestFilter : Request with Authorization header +JwtRequestFilter -> JwtUtilFilter : extractUsername(jwt) +JwtRequestFilter -> UserDetailsService : loadUserByUsername +JwtRequestFilter -> JwtUtilFilter : validateToken(jwt, userDetails) +alt Valid token + JwtRequestFilter -> SecurityContext : Set authentication +else Invalid token + JwtRequestFilter -> JwtRequestFilter : Log and skip authentication +end +JwtRequestFilter --> UserClient : Continue filter chain + +== @JwtRequired Secured Method Access == + +box "AOP - Method Security" #E1F5FE + participant JwtAspect + participant JwtUtilAspect as "JwtUtil" +end box + +UserClient -> JwtAspect : Call method annotated with @JwtRequired +JwtAspect -> JwtAspect : Extract JWT from header +JwtAspect -> JwtUtilAspect : extractUsername(jwt) +JwtAspect -> SecurityContext : Get UserDetails +JwtAspect -> JwtUtilAspect : validateToken(jwt, userDetails) +alt Token valid and user matches + JwtAspect --> UserClient : Proceed to method execution +else Invalid/mismatched token + JwtAspect --> UserClient : Unauthorized exception + return +end + +@enduml + +** class +@startuml +skinparam classAttributeIconSize 0 +skinparam packageStyle rectangle + +package "High-Level Overview" { + + ' Controller Layer + package "Controller Layer" { + class AiChatController + class AiChatWebSocketController + class AuthController + class FileMetadataController + class LibraryController + class PageController + class RegisterController + class UserController + class WorkspaceController + } + + ' Service Layer + package "Service Layer" { + class AiChatService + class AuthService + class FileMetadataService + class LibraryService + class PageService + class RegisterService + class UserService + class WorkspaceService + } + + ' Repository Layer + package "Repository Layer" { + class AiChatRepository + class FileMetadataRepository + class LibraryRepository + class PageRepository + class UserRepository + class WorkspaceRepository + class RegisterRepository + class AuthRepository + } + + ' Entity Layer + package "Entity Layer" { + + class User { + +id: Long + +roles: Set + +firstName: String + +lastName: String + +username: String + +password: String + +confirmPassword: String + +email: String + +phoneNumber: String + +picture: byte[] + } + + class Workspace { + +id: Long + +name: String + +description: String + +fileCount: int + +noteCount: int + +lastAccessed: LocalDateTime + +dateCreated: LocalDateTime + } + + class Library { + +id: Long + +name: String + +description: String + +dateCreated: LocalDateTime + +lastAccessed: LocalDateTime + } + + class Page { + +id: Long + +name: String + +workspaceId: Long + +content: Text + +height: int + +width: int + } + + class FileMetadata { + +id: Long + +fileUrl: String + +userId: String + +description: String + +fileData: byte[] + +fileName: String + +fileType: String + } + + class AiChat { + +id: Long + +name: String + +workspaceId: Long + +createdAt: LocalDateTime + +messages: List + } + } + + ' Python NLP Microservice + package "External NLP Module (Python FastAPI)" { + class FastAPINLPServer { + +/extract_text + +/keywords + +/tfidf_keywords + +/summarize + +/ner + } + } + + ' Entity Relationships + User "1" --> "many" Library + User "1" --> "many" Workspace + Library "1" --> "many" Workspace + Library "1" --> "many" FileMetadata + Workspace "1" --> "many" Page + Workspace "1" --> "many" FileMetadata + Workspace "1" --> "many" AiChat + + ' Controller → Service + AiChatController --> AiChatService + AiChatWebSocketController --> AiChatService + AuthController --> AuthService + FileMetadataController --> FileMetadataService + LibraryController --> LibraryService + PageController --> PageService + RegisterController --> RegisterService + UserController --> UserService + WorkspaceController --> WorkspaceService + + ' Service → Repository + AiChatService --> AiChatRepository + AuthService --> AuthRepository + FileMetadataService --> FileMetadataRepository + LibraryService --> LibraryRepository + PageService --> PageRepository + RegisterService --> RegisterRepository + UserService --> UserRepository + WorkspaceService --> WorkspaceRepository + + ' Repository → Entity + AiChatRepository --> AiChat + FileMetadataRepository --> FileMetadata + LibraryRepository --> Library + PageRepository --> Page + UserRepository --> User + WorkspaceRepository --> Workspace + RegisterRepository --> User + AuthRepository --> User + + ' Frontend → NLP Server + +} + +' Frontend Component +package "Frontend" { + class AngularClient +} + +' Angular communicates with both backends +AngularClient ..> AiChatController : REST +AngularClient ..> AiChatWebSocketController : WebSocket +AngularClient ..> AuthController : REST +AngularClient ..> PageController : REST +AngularClient ..> FileMetadataController : REST +AngularClient ..> WorkspaceController : REST +AngularClient ..> LibraryController : REST +AngularClient ..> RegisterController : REST +AngularClient ..> UserController : REST +AngularClient ..> FastAPINLPServer : REST + +@enduml +** client-server +@startuml +!pragma layout smetana + +actor User + +package "Client Side (Angular)" { + [Angular App] as Frontend +} + +package "Spring Boot Backend" { + [Auth Controller] + [Note Controller] + [NLP Proxy Service] + [Spring Boot App] as Backend +} + +package "Database Layer" { + database "PostgreSQL Database" as DB +} + +package "FastAPI NLP Server (Port 9010)" { + [FastAPI NLP Service] as NLP + [Summarisation Endpoint] as SumEndpoint + [Keyword Extraction] as KeywordEndpoint + [NER Endpoint] as NEREndpoint +} + +package "External API" { + [OpenAI API] +} + +' Interactions +User --> Frontend : Uses Web Interface +Frontend --> Backend : REST API Calls +Backend --> [Auth Controller] : Handles Auth +Backend --> [Note Controller] : Handles Notes +Backend --> [NLP Proxy Service] : Handles NLP Requests +[Auth Controller] --> DB : Access users table +[Note Controller] --> DB : Access notes table +[NLP Proxy Service] --> NLP : HTTP (port 9010) +NLP --> SumEndpoint : /summarise +NLP --> KeywordEndpoint : /keywords +NLP --> NEREndpoint : /ner +SumEndpoint --> [OpenAI API] : API call for contextual help + +note right of Frontend + Angular app includes: + - Note Editor + - Summary View + - Keyword Panel +end note + +note right of Backend + Spring Boot includes: + - Auth Controller + - Note Controller + - NLP Proxy Service (calls FastAPI) +end note + +note right of NLP + FastAPI exposes endpoints for: + - Summarisation (Pegasus) + - Keyword Extraction (TF-IDF, YAKE) + - NER (spaCy) +end note +@enduml +** high level: +@startuml +skinparam componentStyle uml2 +skinparam packageStyle rectangle + +package "Client (Frontend)" { + [Angular UI] +} + +package "Java Backend (Spring Boot)" { + [REST API Controller Layer] + [WebSocket Controller] + [Service Layer] + [Repository Layer] + [JPA Entities] +} + +package "Python NLP Service" { + [FastAPI Server] + [Summarizer (Pegasus)] + [Keyword Extractor (YAKE / TF-IDF)] + [NER (spaCy)] + [Extract Text (Canvas Object)] +} + +package "External Services" { + [OpenAI API] + [PostgreSQL DB] +} + +' Communication Arrows +[Angular UI] --> [REST API Controller Layer] : REST API (JSON) +[Angular UI] --> [WebSocket Controller] : WebSocket + +[REST API Controller Layer] --> [Service Layer] +[WebSocket Controller] --> [Service Layer] +[Service Layer] --> [Repository Layer] +[Repository Layer] ..> [JPA Entities] : uses +[Service Layer] --> [OpenAI API] : API calls + +[Service Layer] --> [FastAPI Server] : REST (NLP Requests) +[FastAPI Server] --> [Summarizer (Pegasus)] +[FastAPI Server] --> [Keyword Extractor (YAKE / TF-IDF)] +[FastAPI Server] --> [NER (spaCy)] +[FastAPI Server] --> [Extract Text (Canvas Object)] + +[Repository Layer] --> [PostgreSQL DB] : Hibernate ORM +@enduml + +** title AI Chat + Workspace Workflow +@startuml +title AI Chat + Workspace Workflow + +skinparam shadowing true +skinparam packageStyle rectangle +skinparam handwritten false +skinparam linetype polyline +skinparam ParticipantPadding 20 +skinparam maxMessageSize 150 + +actor User + +== AI Chat Session Creation == + +box "Client" #E3F2FD + participant AngularClient as "User" +end box + +box "Backend - AI Chat" #E8F5E9 + participant AiChatController + participant AiChatService + participant AiChatRepository +end box + +box "External NLP Service" #FCE4EC + participant FastAPINLPServer as "FastAPI NLP" +end box + +User -> AngularClient : Open AI Chat page +AngularClient -> AiChatController : POST /ai-chat\n(chat metadata) +AiChatController -> AiChatService : createChat(chatDto) +AiChatService -> AiChatRepository : save(chat) +AiChatService --> AiChatController : chatId +AiChatController --> AngularClient : 200 OK + chatId + +User -> AngularClient : Send message via WebSocket +AngularClient -> AiChatWebSocketController : message +AiChatWebSocketController -> AiChatService : handleMessage() + +alt Message requires NLP + AiChatService -> FastAPINLPServer : POST /summarize or /ner + FastAPINLPServer --> AiChatService : NLP result +end + +AiChatService -> AiChatRepository : update(chat with message) +AiChatWebSocketController --> AngularClient : Message response + +== Workspace Creation == + +box "Backend - Workspace" #FFF3E0 + participant WorkspaceController + participant WorkspaceService + participant WorkspaceRepository +end box + +User -> AngularClient : Create Workspace +AngularClient -> WorkspaceController : POST /workspace\n(name, description) +WorkspaceController -> WorkspaceService : createWorkspace(dto) +WorkspaceService -> WorkspaceRepository : save(workspace) +WorkspaceService --> WorkspaceController : workspaceId +WorkspaceController --> AngularClient : 200 OK + workspaceId + +@enduml + +* Screenshots: +** Draft 1: +[[file:~/master-folder/FYP/uml/draft1.png]] + diff --git a/20241210233721-brain.org~ b/20241210233721-brain.org~ new file mode 100755 index 0000000..7d73cf8 --- /dev/null +++ b/20241210233721-brain.org~ @@ -0,0 +1,34 @@ +:PROPERTIES: +:ID: b2fb976a-c23c-4275-8a53-da343c223b97 +:END: +#+title: brain +#+filetags: :brain: + +#+BEGIN_SRC elisp +(org-roam-ui-mode) +#+END_SRC + +#+RESULTS: +: t + +* Technical (Computing) +[[id:8fa3f476-6152-45f4-b618-50f1e4bce46c][Emacs Stuff]] +[[id:2f285f04-fcf4-4ade-a1ac-2c50b43d529a][technical]] +* Career +** Work + +*** Index: [[id:dd04d228-fff5-402a-929d-9d113a2ec965][career-index]] + +** Applications - career (pre work) + +The org file: [[file:~/master-folder/org_files/career.org][career]] +The roam file: [[id:fe5086b8-1941-4125-881a-65d01e1e7774][Career roam]] + +* Uni stuff: +[[id:797d6e3e-98eb-4bc7-88b6-e096ef7306ad][Uni]] +* Misc +** Books +[[id:63314cff-3a3f-49b4-9e76-4a359c51f55f][books-main]] +[[id:2706598f-e6aa-4e88-8d24-5f699bd22787][Book Notes]] +** Food +[[id:65F747B1-3CB2-429A-9E26-ED8BC169E689][recipes-main]] diff --git a/20241210233721-brain_moc.org b/20241210233721-brain_moc.org new file mode 100755 index 0000000..017d14d --- /dev/null +++ b/20241210233721-brain_moc.org @@ -0,0 +1,30 @@ +:PROPERTIES: +:ID: b2fb976a-c23c-4275-8a53-da343c223b97 +:END: +#+title: brain_moc +#+filetags: :moc: + +#+BEGIN_SRC elisp +(org-roam-ui-mode) +#+END_SRC + +#+RESULTS: +: t + +* Backlog +[[id:580cc3a5-af8e-4cbe-b5ad-5b06680e6c37][backlog]] + +* Technical (Computing) +[[id:2f285f04-fcf4-4ade-a1ac-2c50b43d529a][technical_moc]] + +* Non Technical +[[id:565eaccd-8cf6-4dbb-bc66-a4b37367ce6b][non_technical_moc]] + +* Uni stuff: +[[id:797d6e3e-98eb-4bc7-88b6-e096ef7306ad][uni_moc]] + +* Career +[[id:dd04d228-fff5-402a-929d-9d113a2ec965][career_moc]] + +* Misc +[[id:08415f5c-986e-45a6-8ea1-f3bedcc996f0][misc_moc]] diff --git a/20241210233721-brain_moc.org~ b/20241210233721-brain_moc.org~ new file mode 100755 index 0000000..659bc10 --- /dev/null +++ b/20241210233721-brain_moc.org~ @@ -0,0 +1,32 @@ +:PROPERTIES: +:ID: b2fb976a-c23c-4275-8a53-da343c223b97 +:END: +#+title: brain_moc +#+filetags: :moc: + +#+BEGIN_SRC elisp +(org-roam-ui-mode) +#+END_SRC + +#+RESULTS: +: t + +* Technical (Computing) +[[id:2f285f04-fcf4-4ade-a1ac-2c50b43d529a][technical_moc]] + +* Non Technical +[[id:565eaccd-8cf6-4dbb-bc66-a4b37367ce6b][non_technical_moc]] + +* Uni stuff: +[[id:797d6e3e-98eb-4bc7-88b6-e096ef7306ad][uni_moc]] + +* Career +[[id:dd04d228-fff5-402a-929d-9d113a2ec965][career_moc]] + +* Misc +[[id:08415f5c-986e-45a6-8ea1-f3bedcc996f0][misc_moc]] + + +* quick notes +** portainer access token: +ptr_KFQqKse9K4Nc9M5jnpc61fpAvGzdTOXTzswz9CwOF74= diff --git a/20241211161232- job_application_cover_letters.org b/20241211161232- job_application_cover_letters.org new file mode 100755 index 0000000..c275811 --- /dev/null +++ b/20241211161232- job_application_cover_letters.org @@ -0,0 +1,269 @@ +:PROPERTIES: +:ID: f9897f8e-2b63-4ad2-a55f-3787c4ac235f +:END: +#+title: job_application_cover_letters +#+filetags: :pre-career:applications: +#+STARTUP: overview + + +* Modules: +1st year +- Data structures and Algorithms +- Object Oriented Programming +- Mathematical and Logical foundations of computer science +- Full stack software development +- Artificial Intelligence 1 +- Theories of computation +2nd year +- Team Project (77%) +- Security and Networks (72%) +- Functional Programming (87%) +- Software Engineering and Professional Practice (81%) +- Artificial Intelligence 2 (75%) +- Operating Systems and Systems Programming (66%) +3rd Year +- Final Year Project +- Advanced Networking +- Advanced Functional Programming +- Intelligent Software Engineering +- Teaching Computer Science in Schools + + +Mathematics A level: A +French A level: B +Business A level: A + +Maths GCSE: 9 +English GCSE: 6 + +* Stantec +** Cover letter: +[[file:/home/zaine/master-folder/CV's/Cover Letter/Santec/Santec.pdf][File]] +*CONTAINS SPELLING MISTAKES - USE BT ONE* +I would firstly like to extend my gratidute for giving me the opportunity to apply for an amazing role. If you are looking for a passionate data analyst and problem solver with experience extending into software development, then I believe I'm the perfect candidate for the role. + +Growing up, I have always been interested in two things: Tech and problem solving. My technical journey began when I joined the University Of Birmingham, wherein I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead, and resulted in a 14% increase in user satisfaction. In addition, I used Python for the visualization of data on a networking module and have been using PostgreSQL throughout my degree. + +Upon inspecting the requirements from the description, I have listed below my top three skills which I believe would make me most suited for this role: +- Data Analysis and Visualisation: I developed a Java based note taking application, where I used JavaFX and a database (PSQL). + +- Database Management: Created and maintained databases using PostgreSQL for various projects, some were hosted locally, some on the cloud and some on virtual machines. + +- Innovative Thinking: Currently integrating machine learning algorithms into a note taking platform tailored for neurodiverse students specifically. + +Stantec has a commitment to two main things which really resonate and encouraged me to apply: sustainability and innovation. The Surface Water Assessor and Flood Prediction Tools are innovations that really inspire a person, and it only encourages me more to use the knowledge I am fortunate to have gained to help and make meaningful impact to society. + +I am enthusiastic about joining the graduate program; it is a core principle of mine that continous learning will propel one to unimaginable heights, and I firmly believe that Santec will be able to provice the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum + + +I am deeply drawn to the water sector because it sits at the intersection of environmental stewardship and technological innovation, offering a unique opportunity to address critical global challenges. With increasing droughts and floods revealing vulnerabilities in water systems, I am inspired by the chance to contribute to solutions that promote water conservation, resilience, and equitable access. Joining this sector allows me to apply my technical expertise in data analysis and machine learning to protect one of our most vital resources, ensuring sustainable and impactful outcomes for communities and future generations. + +** Why are you interested in the sector stated above? + +What draws me to the water sector is the amount of possibilities there are when it comes to creating positive impact to society. I believe in environmental stewardship, and through the use of technology, this offers a unique chance to address critical global issues, and solve them as well! Joining this sector would allow me to grow as an individual, and to apply my technical skills and experience in data analysis and machine learning to ensure that impactful outcomes are achieved. + +* Sinara +** Use this section to describe your technical experience such as programming languages, operating systems, hardware, databases etc. Give some indication of your level of proficiency in each. Include particular reference to your skills in C#/C++ and Java. +Technical Experience + +C: Strong proficiency gained through academic projects focusing on operating systems and systems programming. I created a 3 tier TCP/IP client server CLI service as part of University project. C++: Moderate proficiency, developed through coursework and personal exploration of object oriented and systems programming. Currently learning more about this, I recently developped a c++ pomodorro CLI system (personal project). Java: Advanced expertise through academic projects, such as developing a note taking application (personal) using JavaFX and a database driven book catalog (University). This includes experience in object oriented programming and GUI development. TypeScript/Angular: Proficient in full stack development, notably using Angular for frontend development and integrating with Spring Boot backends. Used this for a web project that is now completed and using Spring boot with Typescript/Angular for a current web project. Databases PostgreSQL: Advanced proficiency demonstrated in team projects and personal development efforts, including a web application for football enthusiastic students (University Project) and a book catalog application. H2 Console: Experience in testing and managing in memory databases within Spring Boot applications. Operating Systems Linux: Competent in scripting and system management, with experience writing bash scripts and using Linux environments for development. I also use Linux as my daily driver, and I am getting more into emacs. + + +What was the purpose of the program. What part did you play in its development? + +Football Finder Web Application Purpose: The program was designed to help users locate and join local football matches based on their preferences, such as location, skill level, and availability. The goal was to increase engagement in local sports communities and make match organisation easier. My Role: As the team leader, I oversaw code commits, pull requests, and task allocations using a Kanban board. I actively contributed to both the frontend and backend, focusing on user interface enhancements and optimising the backend logic for booking pitches Lessons Learned: I improved my ability to lead a team and manage project workflows effectively. I strengthened my skills in user centered design, ensuring the interface met user expectations, this was done through collating feedback. I learned the importance of clear communication and fostering a supportive environment within the team. + + +What steps did you take before starting to write code? + +Before starting the Football Finder Web Application, I liaised with the team to define user requirements, focusing on features like location based match searches and skill level filtering. We researched existing solutions, identified gaps, and selected a tech stack of Angular, Spring Boot, and PostgreSQL. I created user personas, wireframes, and prototypes to visualise the UI and flow, while also designing the database schema (using JDL) and API endpoints. A Kanban board was established for task management, and we broke the project into sprints with clear milestones. Finally, we outlined a testing strategy, including unit, integration, and user acceptance testing, to ensure the application met user needs and functioned seamlessly. + + +How was the software tested? + +The Football Finder Web Application was tested using a strategy to ensure functionality and reliability. Unit tests were written for individual components and backend services to validate isolated functionality. To test API endpoints we used SwaggerUI. User acceptance testing involved gathering feedback from a small group of target users to evaluate the usability and effectiveness of the application. Automated tests were implemented for repetitive checks, and manual testing focused on edge cases, such as invalid input handling and network interruptions. Finally, the application was deployed in a staging environment to simulate real world usage and identify any final issues before production. + + +What problems did you encounter and how did you deal with them? + +During the development of the Football Finder Web Application, we encountered several challenges. One major issue was ensuring accurate location based match recommendations, which we resolved by integrating and testing multiple geolocation APIs to find the most reliable solution. Another problem was maintaining data consistency during simultaneous updates to the match database, which we addressed by implementing transaction management and locking mechanisms in PostgreSQL. Cross browser compatibility issues arose in the frontend, which we fixed by rigorously testing on different browsers and applying appropriate SCSS fixes (alot of global stylings had to be rewritten). Lastly, communication delays within the team occasionally slowed progress, so we introduced more frequent stand ups and better use of task management tools to improve collaboration and streamline workflows. + + +With hindsight, what would you have done differently? + +With hindsight, I would have allocated more time to user research and feedback during the initial planning stages to better align the application's features with user needs. Additionally, I would have implemented our own automated deployment pipelines earlier to streamline the testing and staging process as opposed to using the one the University provided, allowing us to learn more about devops and have more control over the project. Lastly, setting clearer communication protocols from the outset could have minimised delays, ensuring smoother collaboration and faster resolution of blockers. + +What are your personal career goals? +- Develop expertise in full-stack development, machine learning, and cloud computing. - Contribute to open source projects (currently going into emacs and MELPA packages) - Lead impactful projects that give back to the community. - Take on leadership roles to guide teams in delivering applications and solutions. +Please use this space to provide any other information you feel would support your application. For example: Other experience or awards, positions of responsibility, hobbies and interests. +- I love language learning and reading literature in other languages. - I really enjoy reading about other people's experiences with GTD (getting things done) and use these as inspiration for my own system - I am currently getting into embedded programming. - I am a regular gym goer and love cooking. - I also enjoy tinkering with cars and modding them. +* BT +** Cover Letter: +[[file:~/master-folder/CV's/Cover Letter/btgroup/BT_group_cl.pdf][file]] +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at BT group, where challenges are primarily user centric. + +What draws me most to BT group is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. BT group achieves this in various ways, ranging from addressing climate change to enhancing cybersecurity. I would be really ecstatic to apply my skills in various programming languages and tools such as Git, Ansible, and Terraform, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of BT group, which is to develop high performance and well tested code to bring about a greater benefit to the community. + +I am enthusiastic about joining the graduate program; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that BT group will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* Panoptech +** Cover Letter: +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into DevOps, then I believe I'm the perfect candidate for the role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + + +In addition to my technical background, I have experience with DevOps tools, including Ansible, Docker, and Jenkins, gained through self learning and practical application. I am also familiar with bash scripting, which is something I find myself coming back to whenever I want to automate something; this I usually do in bash and python, occasionally, for no particular reason, I would use Haskell to write scripts. I am certain that these skills will allow me to support the development team in managing the DevOps toolchain. + +I also use Linux as my daily drivers, I have dual booted quite a few machines, some running Ubuntu some running Mint. I also have experience in virutalisation software; this was when I needed to host a local database, hence I fired up a virtual machine running minimal Ubuntu and kept a PSQL server on there. + +I am enthusiastic about joining the Panoptech; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Panoptech will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* buro happold +[[file:~/master-folder/CV's/Cover Letter/buro_happald/Buro_Happold_CL.pdf][file]] +** cl - SAME AS BT +Dear Hiring Manager, +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing +role. If you are looking for a passionate Digital Technologist and problem solver with experience +extending into other disciplines, then I believe I'm the perfect candidate for the role. +There are two things I have always been interested in growing up: Technology and Problem +solving. My technical journey began when I joined the University of Birmingham, where I have +developed solid foundations in data analysis, software development and problem solving. One +of the biggest projects I have worked on was a football finding web app which I was entrusted +to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, +Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising +data on a networking module, and for various scripting purposes. +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to +students coming from lower socio-economic backgrounds, and who are neurodiverse. This +experience has taught me many things, two that are notable are communication and +adaptability. These two skills together have taught me the importance of understanding as well +as addressing challenges, which I believe will translate well at Buro Happold, where challenges +are primarily user centric. +What draws me most to Buro Happold is their commitment to using technology to bring good +to the community. This, I would say, is one of the reasons I decided to go into the field of tech, +which was to help others. Buro Happold achieves this in various ways, from designing modular +systems that reduce costs while enhancing the learning experience for institutions like Kuwait +University, to implementing advanced technologies at landmark sites like the Louvre Abu Dhabi, +ensuring seamless visitor experiences and operational efficiency. +I am enthusiastic about joining the company; it is a core principle of mine that continuous +learning will propel one to unimaginable heights, and I firmly believe that Buro Happold will be +able to provide the means to make that happen. Thank you for considering my application, I +look forward to discussing my candidacy further! +Warm regards, +Zaine-Ul-Abideen Qayyum +* Experian +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction, this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at Experian, where challenges are primarily user centric. + +What draws me most to Experian is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. Experian achieves this in various ways, ranging from addressing climate change to enhancing cybersecurity. I would be really ecstatic to apply my skills in various programming languages and tools such as Java, Angular/Typescript and git, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of Experian, which is to develop high performance and well tested code to bring about a greater benefit to the community. + +I am enthusiastic about joining the graduate program, it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Experian will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! +* Cambridge Consultants +Dear Hiring Manager, + + + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate embedded software engineer and problem solver with experience extending into DevOps and low-level programming, then I believe I'm the perfect candidate for the role. + + + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + + + +In addition to my technical background, I have experience with DevOps tools, including Ansible, Docker, and Jenkins, gained through self learning and practical application. I am also familiar with bash scripting, which is something I find myself coming back to whenever I want to automate something; this I usually do in bash and python, occasionally, for the purpose of challenging myself, I would use Haskell to write scripts. In addition, I write scripts that allow me to communicate with hardware connected to a raspberry Pi; whenever I have the free time, I dive into embedded programming as this is a huge interest of mine. I am certain that these skills will allow me to support the team in solving real client problems at Cambridge Consultants. + + + +I also use Linux as my daily drivers, I have dual booted quite a few machines, some running Ubuntu some running Mint. I also have experience in virutalisation software; this was when I needed to host a local database, hence I fired up a virtual machine running minimal Ubuntu and kept a PSQL server on there. + + + +I am enthusiastic about joining the Cambridge Consultants; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Cambridge Consultants will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + + + +Warm regards, + +Zaine-Ul-Abideen Qayyum +* Adelphi Real World +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate problem solver with a strong foundation in data analysis and a drive to deliver precise and efficient solutions, I believe I am the ideal candidate for this role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction, this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at Adelphi, where challenges are primarily user centric. + +What draws me most to Adelphi Real World is their commitment to leveraging real world data to improve healthcare outcomes. The mere prospect of contributing to this mission by using tools like SPSS, Confirmit, and Excel, and supporting fieldwork and data processing, aligns perfectly with my dream of using technology to help others. I would be really ecstatic to apply my analytical skills, programming knowledge, and meticulous attention to detail to bring about a greater benefit to Adelphi, the healthcare sector and the community. + +I am enthusiastic about joining this esteemed organisation, it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Adelphi Real World will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, + +Zaine-Ul-Abideen Qayyum +* Midland Heart +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate problem solver with a strong foundation in data analysis and a drive to deliver precise and efficient solutions, I believe I am the ideal candidate for this role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction, this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at Midland Heart, where challenges are primarily user centric. + +What draws me most to Midland Heart is their commitment to leveraging real world data to improve tenancy outcomes. The mere prospect of contributing to this mission by using tools like Power Bi, Python, and Cloud Services, and supporting fieldwork and data processing, aligns perfectly with my dream of using technology to help others. I would be ecstatic to apply my analytical skills, programming knowledge, and meticulous attention to detail to bring about a greater benefit to Midland Heart, the housing sector and the community. + +I am enthusiastic about joining this esteemed organisation, it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Midland Heart will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* EDW +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate Software Tester and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at EDW Technology, where challenges are primarily user centric. +What draws me most to EDW Technology is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. EDW Technology achieves this in various ways, ranging from creating energy management tools to providing user focused solutions. I would be ecstatic to apply my skills in various programming languages and tools such as Java, Swagger, and Git, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of EDW Technology, which is to develop high performance and well tested code to bring about a greater benefit to the community. +I am enthusiastic about joining the graduate program; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that EDW Technology will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* DCA +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. I have also built a full stack NLP/AI powered note taking web application to address the issue of cognitive overload. +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at DCA, where challenges are primarily user centric. +What draws me most to DCA is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. DCA achieves this in various ways, ranging from addressing novel transport solutions to developing safety-critical medical devices. I would be really ecstatic to apply my skills in various programming languages and tools such as Git, Docker, and Nginx, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of DCA, which is to develop high performance and well tested code to bring about a greater benefit to the community +I am enthusiastic about joining the graduate program; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that DCA will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* emp +Describe something you have done that you are proud of. (Word limit 250 words) +One of the proudest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. However, my proudest work to date was a full stack web application that utilises AI and NLP to reduce cognitive overload faced in students. This was an ongoing long-term project and has taken me 7 months to complete. I used Spring Boot, Angular/Typescript along with Python scripting. + +How can you demonstrate your current curiosity around technology to us? (Word Limit 250 words) +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. I find myself more so immersed in technical related hobbies such as ‘ricing’ a Linux distro, configuration of Emacs, tinkering with embedded programming using Raspberry Pi. + +Can you describe to us a scenario where you have demonstrated either creativity, innovation or originality (Word Limit 250 words) +One of the most innovative projects I have worked on was my AI-assisted note-taking web application, designed to combat cognitive overload in students. The challenge was to create an intuitive system that could process and summarise lecture content efficiently while al-lowing students to interact with it seamlessly. I thus decided on using OpenAI’s API for basic requests (intelligence enhanced which allowed it to see what the user is doing through parsing the canvas object), natural language processing (NLP), integrating it with an Angular TypeScript frontend and a Spring Boot backend. +What made this project particularly creative was my decision to incorporate adaptive sum-marisation, meaning the AI tailors the level of detail in notes based on the user’s prefer-ences and previous study patterns. Unlike traditional note-taking applications, this one con-tinuously learns from user behavior, refining its output over time. Furthermore, I used YAKE and TF-IDF to extract keywords from the notes, as well as NER (named entity recognition). diff --git a/20241211161232-applications.org b/20241211161232-applications.org new file mode 100644 index 0000000..28078aa --- /dev/null +++ b/20241211161232-applications.org @@ -0,0 +1,269 @@ +:PROPERTIES: +:ID: f9897f8e-2b63-4ad2-a55f-3787c4ac235f +:END: +#+title: job_application_cover_letters +#+filetags: +#+STARTUP: overview + + +* Modules: +1st year +- Data structures and Algorithms +- Object Oriented Programming +- Mathematical and Logical foundations of computer science +- Full stack software development +- Artificial Intelligence 1 +- Theories of computation +2nd year +- Team Project (77%) +- Security and Networks (72%) +- Functional Programming (87%) +- Software Engineering and Professional Practice (81%) +- Artificial Intelligence 2 (75%) +- Operating Systems and Systems Programming (66%) +3rd Year +- Final Year Project +- Advanced Networking +- Advanced Functional Programming +- Intelligent Software Engineering +- Teaching Computer Science in Schools + + +Mathematics A level: A +French A level: B +Business A level: A + +Maths GCSE: 9 +English GCSE: 6 + +* Stantec +** Cover letter: +[[file:/home/zaine/master-folder/CV's/Cover Letter/Santec/Santec.pdf][File]] +*CONTAINS SPELLING MISTAKES - USE BT ONE* +I would firstly like to extend my gratidute for giving me the opportunity to apply for an amazing role. If you are looking for a passionate data analyst and problem solver with experience extending into software development, then I believe I'm the perfect candidate for the role. + +Growing up, I have always been interested in two things: Tech and problem solving. My technical journey began when I joined the University Of Birmingham, wherein I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead, and resulted in a 14% increase in user satisfaction. In addition, I used Python for the visualization of data on a networking module and have been using PostgreSQL throughout my degree. + +Upon inspecting the requirements from the description, I have listed below my top three skills which I believe would make me most suited for this role: +- Data Analysis and Visualisation: I developed a Java based note taking application, where I used JavaFX and a database (PSQL). + +- Database Management: Created and maintained databases using PostgreSQL for various projects, some were hosted locally, some on the cloud and some on virtual machines. + +- Innovative Thinking: Currently integrating machine learning algorithms into a note taking platform tailored for neurodiverse students specifically. + +Stantec has a commitment to two main things which really resonate and encouraged me to apply: sustainability and innovation. The Surface Water Assessor and Flood Prediction Tools are innovations that really inspire a person, and it only encourages me more to use the knowledge I am fortunate to have gained to help and make meaningful impact to society. + +I am enthusiastic about joining the graduate program; it is a core principle of mine that continous learning will propel one to unimaginable heights, and I firmly believe that Santec will be able to provice the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum + + +I am deeply drawn to the water sector because it sits at the intersection of environmental stewardship and technological innovation, offering a unique opportunity to address critical global challenges. With increasing droughts and floods revealing vulnerabilities in water systems, I am inspired by the chance to contribute to solutions that promote water conservation, resilience, and equitable access. Joining this sector allows me to apply my technical expertise in data analysis and machine learning to protect one of our most vital resources, ensuring sustainable and impactful outcomes for communities and future generations. + +** Why are you interested in the sector stated above? + +What draws me to the water sector is the amount of possibilities there are when it comes to creating positive impact to society. I believe in environmental stewardship, and through the use of technology, this offers a unique chance to address critical global issues, and solve them as well! Joining this sector would allow me to grow as an individual, and to apply my technical skills and experience in data analysis and machine learning to ensure that impactful outcomes are achieved. + +* Sinara +** Use this section to describe your technical experience such as programming languages, operating systems, hardware, databases etc. Give some indication of your level of proficiency in each. Include particular reference to your skills in C#/C++ and Java. +Technical Experience + +C: Strong proficiency gained through academic projects focusing on operating systems and systems programming. I created a 3 tier TCP/IP client server CLI service as part of University project. C++: Moderate proficiency, developed through coursework and personal exploration of object oriented and systems programming. Currently learning more about this, I recently developped a c++ pomodorro CLI system (personal project). Java: Advanced expertise through academic projects, such as developing a note taking application (personal) using JavaFX and a database driven book catalog (University). This includes experience in object oriented programming and GUI development. TypeScript/Angular: Proficient in full stack development, notably using Angular for frontend development and integrating with Spring Boot backends. Used this for a web project that is now completed and using Spring boot with Typescript/Angular for a current web project. Databases PostgreSQL: Advanced proficiency demonstrated in team projects and personal development efforts, including a web application for football enthusiastic students (University Project) and a book catalog application. H2 Console: Experience in testing and managing in memory databases within Spring Boot applications. Operating Systems Linux: Competent in scripting and system management, with experience writing bash scripts and using Linux environments for development. I also use Linux as my daily driver, and I am getting more into emacs. + + +What was the purpose of the program. What part did you play in its development? + +Football Finder Web Application Purpose: The program was designed to help users locate and join local football matches based on their preferences, such as location, skill level, and availability. The goal was to increase engagement in local sports communities and make match organisation easier. My Role: As the team leader, I oversaw code commits, pull requests, and task allocations using a Kanban board. I actively contributed to both the frontend and backend, focusing on user interface enhancements and optimising the backend logic for booking pitches Lessons Learned: I improved my ability to lead a team and manage project workflows effectively. I strengthened my skills in user centered design, ensuring the interface met user expectations, this was done through collating feedback. I learned the importance of clear communication and fostering a supportive environment within the team. + + +What steps did you take before starting to write code? + +Before starting the Football Finder Web Application, I liaised with the team to define user requirements, focusing on features like location based match searches and skill level filtering. We researched existing solutions, identified gaps, and selected a tech stack of Angular, Spring Boot, and PostgreSQL. I created user personas, wireframes, and prototypes to visualise the UI and flow, while also designing the database schema (using JDL) and API endpoints. A Kanban board was established for task management, and we broke the project into sprints with clear milestones. Finally, we outlined a testing strategy, including unit, integration, and user acceptance testing, to ensure the application met user needs and functioned seamlessly. + + +How was the software tested? + +The Football Finder Web Application was tested using a strategy to ensure functionality and reliability. Unit tests were written for individual components and backend services to validate isolated functionality. To test API endpoints we used SwaggerUI. User acceptance testing involved gathering feedback from a small group of target users to evaluate the usability and effectiveness of the application. Automated tests were implemented for repetitive checks, and manual testing focused on edge cases, such as invalid input handling and network interruptions. Finally, the application was deployed in a staging environment to simulate real world usage and identify any final issues before production. + + +What problems did you encounter and how did you deal with them? + +During the development of the Football Finder Web Application, we encountered several challenges. One major issue was ensuring accurate location based match recommendations, which we resolved by integrating and testing multiple geolocation APIs to find the most reliable solution. Another problem was maintaining data consistency during simultaneous updates to the match database, which we addressed by implementing transaction management and locking mechanisms in PostgreSQL. Cross browser compatibility issues arose in the frontend, which we fixed by rigorously testing on different browsers and applying appropriate SCSS fixes (alot of global stylings had to be rewritten). Lastly, communication delays within the team occasionally slowed progress, so we introduced more frequent stand ups and better use of task management tools to improve collaboration and streamline workflows. + + +With hindsight, what would you have done differently? + +With hindsight, I would have allocated more time to user research and feedback during the initial planning stages to better align the application's features with user needs. Additionally, I would have implemented our own automated deployment pipelines earlier to streamline the testing and staging process as opposed to using the one the University provided, allowing us to learn more about devops and have more control over the project. Lastly, setting clearer communication protocols from the outset could have minimised delays, ensuring smoother collaboration and faster resolution of blockers. + +What are your personal career goals? +- Develop expertise in full-stack development, machine learning, and cloud computing. - Contribute to open source projects (currently going into emacs and MELPA packages) - Lead impactful projects that give back to the community. - Take on leadership roles to guide teams in delivering applications and solutions. +Please use this space to provide any other information you feel would support your application. For example: Other experience or awards, positions of responsibility, hobbies and interests. +- I love language learning and reading literature in other languages. - I really enjoy reading about other people's experiences with GTD (getting things done) and use these as inspiration for my own system - I am currently getting into embedded programming. - I am a regular gym goer and love cooking. - I also enjoy tinkering with cars and modding them. +* BT +** Cover Letter: +[[file:~/master-folder/CV's/Cover Letter/btgroup/BT_group_cl.pdf][file]] +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at BT group, where challenges are primarily user centric. + +What draws me most to BT group is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. BT group achieves this in various ways, ranging from addressing climate change to enhancing cybersecurity. I would be really ecstatic to apply my skills in various programming languages and tools such as Git, Ansible, and Terraform, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of BT group, which is to develop high performance and well tested code to bring about a greater benefit to the community. + +I am enthusiastic about joining the graduate program; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that BT group will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* Panoptech +** Cover Letter: +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into DevOps, then I believe I'm the perfect candidate for the role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + + +In addition to my technical background, I have experience with DevOps tools, including Ansible, Docker, and Jenkins, gained through self learning and practical application. I am also familiar with bash scripting, which is something I find myself coming back to whenever I want to automate something; this I usually do in bash and python, occasionally, for no particular reason, I would use Haskell to write scripts. I am certain that these skills will allow me to support the development team in managing the DevOps toolchain. + +I also use Linux as my daily drivers, I have dual booted quite a few machines, some running Ubuntu some running Mint. I also have experience in virutalisation software; this was when I needed to host a local database, hence I fired up a virtual machine running minimal Ubuntu and kept a PSQL server on there. + +I am enthusiastic about joining the Panoptech; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Panoptech will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* buro happold +[[file:~/master-folder/CV's/Cover Letter/buro_happald/Buro_Happold_CL.pdf][file]] +** cl - SAME AS BT +Dear Hiring Manager, +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing +role. If you are looking for a passionate Digital Technologist and problem solver with experience +extending into other disciplines, then I believe I'm the perfect candidate for the role. +There are two things I have always been interested in growing up: Technology and Problem +solving. My technical journey began when I joined the University of Birmingham, where I have +developed solid foundations in data analysis, software development and problem solving. One +of the biggest projects I have worked on was a football finding web app which I was entrusted +to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, +Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising +data on a networking module, and for various scripting purposes. +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to +students coming from lower socio-economic backgrounds, and who are neurodiverse. This +experience has taught me many things, two that are notable are communication and +adaptability. These two skills together have taught me the importance of understanding as well +as addressing challenges, which I believe will translate well at Buro Happold, where challenges +are primarily user centric. +What draws me most to Buro Happold is their commitment to using technology to bring good +to the community. This, I would say, is one of the reasons I decided to go into the field of tech, +which was to help others. Buro Happold achieves this in various ways, from designing modular +systems that reduce costs while enhancing the learning experience for institutions like Kuwait +University, to implementing advanced technologies at landmark sites like the Louvre Abu Dhabi, +ensuring seamless visitor experiences and operational efficiency. +I am enthusiastic about joining the company; it is a core principle of mine that continuous +learning will propel one to unimaginable heights, and I firmly believe that Buro Happold will be +able to provide the means to make that happen. Thank you for considering my application, I +look forward to discussing my candidacy further! +Warm regards, +Zaine-Ul-Abideen Qayyum +* Experian +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction, this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at Experian, where challenges are primarily user centric. + +What draws me most to Experian is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. Experian achieves this in various ways, ranging from addressing climate change to enhancing cybersecurity. I would be really ecstatic to apply my skills in various programming languages and tools such as Java, Angular/Typescript and git, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of Experian, which is to develop high performance and well tested code to bring about a greater benefit to the community. + +I am enthusiastic about joining the graduate program, it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Experian will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! +* Cambridge Consultants +Dear Hiring Manager, + + + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate embedded software engineer and problem solver with experience extending into DevOps and low-level programming, then I believe I'm the perfect candidate for the role. + + + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + + + +In addition to my technical background, I have experience with DevOps tools, including Ansible, Docker, and Jenkins, gained through self learning and practical application. I am also familiar with bash scripting, which is something I find myself coming back to whenever I want to automate something; this I usually do in bash and python, occasionally, for the purpose of challenging myself, I would use Haskell to write scripts. In addition, I write scripts that allow me to communicate with hardware connected to a raspberry Pi; whenever I have the free time, I dive into embedded programming as this is a huge interest of mine. I am certain that these skills will allow me to support the team in solving real client problems at Cambridge Consultants. + + + +I also use Linux as my daily drivers, I have dual booted quite a few machines, some running Ubuntu some running Mint. I also have experience in virutalisation software; this was when I needed to host a local database, hence I fired up a virtual machine running minimal Ubuntu and kept a PSQL server on there. + + + +I am enthusiastic about joining the Cambridge Consultants; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Cambridge Consultants will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + + + +Warm regards, + +Zaine-Ul-Abideen Qayyum +* Adelphi Real World +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate problem solver with a strong foundation in data analysis and a drive to deliver precise and efficient solutions, I believe I am the ideal candidate for this role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction, this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at Adelphi, where challenges are primarily user centric. + +What draws me most to Adelphi Real World is their commitment to leveraging real world data to improve healthcare outcomes. The mere prospect of contributing to this mission by using tools like SPSS, Confirmit, and Excel, and supporting fieldwork and data processing, aligns perfectly with my dream of using technology to help others. I would be really ecstatic to apply my analytical skills, programming knowledge, and meticulous attention to detail to bring about a greater benefit to Adelphi, the healthcare sector and the community. + +I am enthusiastic about joining this esteemed organisation, it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Adelphi Real World will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, + +Zaine-Ul-Abideen Qayyum +* Midland Heart +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate problem solver with a strong foundation in data analysis and a drive to deliver precise and efficient solutions, I believe I am the ideal candidate for this role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction, this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at Midland Heart, where challenges are primarily user centric. + +What draws me most to Midland Heart is their commitment to leveraging real world data to improve tenancy outcomes. The mere prospect of contributing to this mission by using tools like Power Bi, Python, and Cloud Services, and supporting fieldwork and data processing, aligns perfectly with my dream of using technology to help others. I would be ecstatic to apply my analytical skills, programming knowledge, and meticulous attention to detail to bring about a greater benefit to Midland Heart, the housing sector and the community. + +I am enthusiastic about joining this esteemed organisation, it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Midland Heart will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* EDW +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate Software Tester and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at EDW Technology, where challenges are primarily user centric. +What draws me most to EDW Technology is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. EDW Technology achieves this in various ways, ranging from creating energy management tools to providing user focused solutions. I would be ecstatic to apply my skills in various programming languages and tools such as Java, Swagger, and Git, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of EDW Technology, which is to develop high performance and well tested code to bring about a greater benefit to the community. +I am enthusiastic about joining the graduate program; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that EDW Technology will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* DCA +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. I have also built a full stack NLP/AI powered note taking web application to address the issue of cognitive overload. +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at DCA, where challenges are primarily user centric. +What draws me most to DCA is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. DCA achieves this in various ways, ranging from addressing novel transport solutions to developing safety-critical medical devices. I would be really ecstatic to apply my skills in various programming languages and tools such as Git, Docker, and Nginx, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of DCA, which is to develop high performance and well tested code to bring about a greater benefit to the community +I am enthusiastic about joining the graduate program; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that DCA will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* emp +Describe something you have done that you are proud of. (Word limit 250 words) +One of the proudest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. However, my proudest work to date was a full stack web application that utilises AI and NLP to reduce cognitive overload faced in students. This was an ongoing long-term project and has taken me 7 months to complete. I used Spring Boot, Angular/Typescript along with Python scripting. + +How can you demonstrate your current curiosity around technology to us? (Word Limit 250 words) +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. I find myself more so immersed in technical related hobbies such as ‘ricing’ a Linux distro, configuration of Emacs, tinkering with embedded programming using Raspberry Pi. + +Can you describe to us a scenario where you have demonstrated either creativity, innovation or originality (Word Limit 250 words) +One of the most innovative projects I have worked on was my AI-assisted note-taking web application, designed to combat cognitive overload in students. The challenge was to create an intuitive system that could process and summarise lecture content efficiently while al-lowing students to interact with it seamlessly. I thus decided on using OpenAI’s API for basic requests (intelligence enhanced which allowed it to see what the user is doing through parsing the canvas object), natural language processing (NLP), integrating it with an Angular TypeScript frontend and a Spring Boot backend. +What made this project particularly creative was my decision to incorporate adaptive sum-marisation, meaning the AI tailors the level of detail in notes based on the user’s prefer-ences and previous study patterns. Unlike traditional note-taking applications, this one con-tinuously learns from user behavior, refining its output over time. Furthermore, I used YAKE and TF-IDF to extract keywords from the notes, as well as NER (named entity recognition). diff --git a/20241211161232-applications.org~ b/20241211161232-applications.org~ new file mode 100755 index 0000000..649b5b9 --- /dev/null +++ b/20241211161232-applications.org~ @@ -0,0 +1,269 @@ +:PROPERTIES: +:ID: f9897f8e-2b63-4ad2-a55f-3787c4ac235f +:END: +#+title: Applications +#+filetags: :pre-career:applications: +#+STARTUP: overview + + +* Modules: +1st year +- Data structures and Algorithms +- Object Oriented Programming +- Mathematical and Logical foundations of computer science +- Full stack software development +- Artificial Intelligence 1 +- Theories of computation +2nd year +- Team Project (77%) +- Security and Networks (72%) +- Functional Programming (87%) +- Software Engineering and Professional Practice (81%) +- Artificial Intelligence 2 (75%) +- Operating Systems and Systems Programming (66%) +3rd Year +- Final Year Project +- Advanced Networking +- Advanced Functional Programming +- Intelligent Software Engineering +- Teaching Computer Science in Schools + + +Mathematics A level: A +French A level: B +Business A level: A + +Maths GCSE: 9 +English GCSE: 6 + +* Stantec +** Cover letter: +[[file:/home/zaine/master-folder/CV's/Cover Letter/Santec/Santec.pdf][File]] +*CONTAINS SPELLING MISTAKES - USE BT ONE* +I would firstly like to extend my gratidute for giving me the opportunity to apply for an amazing role. If you are looking for a passionate data analyst and problem solver with experience extending into software development, then I believe I'm the perfect candidate for the role. + +Growing up, I have always been interested in two things: Tech and problem solving. My technical journey began when I joined the University Of Birmingham, wherein I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead, and resulted in a 14% increase in user satisfaction. In addition, I used Python for the visualization of data on a networking module and have been using PostgreSQL throughout my degree. + +Upon inspecting the requirements from the description, I have listed below my top three skills which I believe would make me most suited for this role: +- Data Analysis and Visualisation: I developed a Java based note taking application, where I used JavaFX and a database (PSQL). + +- Database Management: Created and maintained databases using PostgreSQL for various projects, some were hosted locally, some on the cloud and some on virtual machines. + +- Innovative Thinking: Currently integrating machine learning algorithms into a note taking platform tailored for neurodiverse students specifically. + +Stantec has a commitment to two main things which really resonate and encouraged me to apply: sustainability and innovation. The Surface Water Assessor and Flood Prediction Tools are innovations that really inspire a person, and it only encourages me more to use the knowledge I am fortunate to have gained to help and make meaningful impact to society. + +I am enthusiastic about joining the graduate program; it is a core principle of mine that continous learning will propel one to unimaginable heights, and I firmly believe that Santec will be able to provice the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum + + +I am deeply drawn to the water sector because it sits at the intersection of environmental stewardship and technological innovation, offering a unique opportunity to address critical global challenges. With increasing droughts and floods revealing vulnerabilities in water systems, I am inspired by the chance to contribute to solutions that promote water conservation, resilience, and equitable access. Joining this sector allows me to apply my technical expertise in data analysis and machine learning to protect one of our most vital resources, ensuring sustainable and impactful outcomes for communities and future generations. + +** Why are you interested in the sector stated above? + +What draws me to the water sector is the amount of possibilities there are when it comes to creating positive impact to society. I believe in environmental stewardship, and through the use of technology, this offers a unique chance to address critical global issues, and solve them as well! Joining this sector would allow me to grow as an individual, and to apply my technical skills and experience in data analysis and machine learning to ensure that impactful outcomes are achieved. + +* Sinara +** Use this section to describe your technical experience such as programming languages, operating systems, hardware, databases etc. Give some indication of your level of proficiency in each. Include particular reference to your skills in C#/C++ and Java. +Technical Experience + +C: Strong proficiency gained through academic projects focusing on operating systems and systems programming. I created a 3 tier TCP/IP client server CLI service as part of University project. C++: Moderate proficiency, developed through coursework and personal exploration of object oriented and systems programming. Currently learning more about this, I recently developped a c++ pomodorro CLI system (personal project). Java: Advanced expertise through academic projects, such as developing a note taking application (personal) using JavaFX and a database driven book catalog (University). This includes experience in object oriented programming and GUI development. TypeScript/Angular: Proficient in full stack development, notably using Angular for frontend development and integrating with Spring Boot backends. Used this for a web project that is now completed and using Spring boot with Typescript/Angular for a current web project. Databases PostgreSQL: Advanced proficiency demonstrated in team projects and personal development efforts, including a web application for football enthusiastic students (University Project) and a book catalog application. H2 Console: Experience in testing and managing in memory databases within Spring Boot applications. Operating Systems Linux: Competent in scripting and system management, with experience writing bash scripts and using Linux environments for development. I also use Linux as my daily driver, and I am getting more into emacs. + + +What was the purpose of the program. What part did you play in its development? + +Football Finder Web Application Purpose: The program was designed to help users locate and join local football matches based on their preferences, such as location, skill level, and availability. The goal was to increase engagement in local sports communities and make match organisation easier. My Role: As the team leader, I oversaw code commits, pull requests, and task allocations using a Kanban board. I actively contributed to both the frontend and backend, focusing on user interface enhancements and optimising the backend logic for booking pitches Lessons Learned: I improved my ability to lead a team and manage project workflows effectively. I strengthened my skills in user centered design, ensuring the interface met user expectations, this was done through collating feedback. I learned the importance of clear communication and fostering a supportive environment within the team. + + +What steps did you take before starting to write code? + +Before starting the Football Finder Web Application, I liaised with the team to define user requirements, focusing on features like location based match searches and skill level filtering. We researched existing solutions, identified gaps, and selected a tech stack of Angular, Spring Boot, and PostgreSQL. I created user personas, wireframes, and prototypes to visualise the UI and flow, while also designing the database schema (using JDL) and API endpoints. A Kanban board was established for task management, and we broke the project into sprints with clear milestones. Finally, we outlined a testing strategy, including unit, integration, and user acceptance testing, to ensure the application met user needs and functioned seamlessly. + + +How was the software tested? + +The Football Finder Web Application was tested using a strategy to ensure functionality and reliability. Unit tests were written for individual components and backend services to validate isolated functionality. To test API endpoints we used SwaggerUI. User acceptance testing involved gathering feedback from a small group of target users to evaluate the usability and effectiveness of the application. Automated tests were implemented for repetitive checks, and manual testing focused on edge cases, such as invalid input handling and network interruptions. Finally, the application was deployed in a staging environment to simulate real world usage and identify any final issues before production. + + +What problems did you encounter and how did you deal with them? + +During the development of the Football Finder Web Application, we encountered several challenges. One major issue was ensuring accurate location based match recommendations, which we resolved by integrating and testing multiple geolocation APIs to find the most reliable solution. Another problem was maintaining data consistency during simultaneous updates to the match database, which we addressed by implementing transaction management and locking mechanisms in PostgreSQL. Cross browser compatibility issues arose in the frontend, which we fixed by rigorously testing on different browsers and applying appropriate SCSS fixes (alot of global stylings had to be rewritten). Lastly, communication delays within the team occasionally slowed progress, so we introduced more frequent stand ups and better use of task management tools to improve collaboration and streamline workflows. + + +With hindsight, what would you have done differently? + +With hindsight, I would have allocated more time to user research and feedback during the initial planning stages to better align the application's features with user needs. Additionally, I would have implemented our own automated deployment pipelines earlier to streamline the testing and staging process as opposed to using the one the University provided, allowing us to learn more about devops and have more control over the project. Lastly, setting clearer communication protocols from the outset could have minimised delays, ensuring smoother collaboration and faster resolution of blockers. + +What are your personal career goals? +- Develop expertise in full-stack development, machine learning, and cloud computing. - Contribute to open source projects (currently going into emacs and MELPA packages) - Lead impactful projects that give back to the community. - Take on leadership roles to guide teams in delivering applications and solutions. +Please use this space to provide any other information you feel would support your application. For example: Other experience or awards, positions of responsibility, hobbies and interests. +- I love language learning and reading literature in other languages. - I really enjoy reading about other people's experiences with GTD (getting things done) and use these as inspiration for my own system - I am currently getting into embedded programming. - I am a regular gym goer and love cooking. - I also enjoy tinkering with cars and modding them. +* BT +** Cover Letter: +[[file:~/master-folder/CV's/Cover Letter/btgroup/BT_group_cl.pdf][file]] +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at BT group, where challenges are primarily user centric. + +What draws me most to BT group is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. BT group achieves this in various ways, ranging from addressing climate change to enhancing cybersecurity. I would be really ecstatic to apply my skills in various programming languages and tools such as Git, Ansible, and Terraform, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of BT group, which is to develop high performance and well tested code to bring about a greater benefit to the community. + +I am enthusiastic about joining the graduate program; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that BT group will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* Panoptech +** Cover Letter: +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into DevOps, then I believe I'm the perfect candidate for the role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + + +In addition to my technical background, I have experience with DevOps tools, including Ansible, Docker, and Jenkins, gained through self learning and practical application. I am also familiar with bash scripting, which is something I find myself coming back to whenever I want to automate something; this I usually do in bash and python, occasionally, for no particular reason, I would use Haskell to write scripts. I am certain that these skills will allow me to support the development team in managing the DevOps toolchain. + +I also use Linux as my daily drivers, I have dual booted quite a few machines, some running Ubuntu some running Mint. I also have experience in virutalisation software; this was when I needed to host a local database, hence I fired up a virtual machine running minimal Ubuntu and kept a PSQL server on there. + +I am enthusiastic about joining the Panoptech; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Panoptech will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* buro happold +[[file:~/master-folder/CV's/Cover Letter/buro_happald/Buro_Happold_CL.pdf][file]] +** cl - SAME AS BT +Dear Hiring Manager, +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing +role. If you are looking for a passionate Digital Technologist and problem solver with experience +extending into other disciplines, then I believe I'm the perfect candidate for the role. +There are two things I have always been interested in growing up: Technology and Problem +solving. My technical journey began when I joined the University of Birmingham, where I have +developed solid foundations in data analysis, software development and problem solving. One +of the biggest projects I have worked on was a football finding web app which I was entrusted +to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, +Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising +data on a networking module, and for various scripting purposes. +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to +students coming from lower socio-economic backgrounds, and who are neurodiverse. This +experience has taught me many things, two that are notable are communication and +adaptability. These two skills together have taught me the importance of understanding as well +as addressing challenges, which I believe will translate well at Buro Happold, where challenges +are primarily user centric. +What draws me most to Buro Happold is their commitment to using technology to bring good +to the community. This, I would say, is one of the reasons I decided to go into the field of tech, +which was to help others. Buro Happold achieves this in various ways, from designing modular +systems that reduce costs while enhancing the learning experience for institutions like Kuwait +University, to implementing advanced technologies at landmark sites like the Louvre Abu Dhabi, +ensuring seamless visitor experiences and operational efficiency. +I am enthusiastic about joining the company; it is a core principle of mine that continuous +learning will propel one to unimaginable heights, and I firmly believe that Buro Happold will be +able to provide the means to make that happen. Thank you for considering my application, I +look forward to discussing my candidacy further! +Warm regards, +Zaine-Ul-Abideen Qayyum +* Experian +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction, this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at Experian, where challenges are primarily user centric. + +What draws me most to Experian is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. Experian achieves this in various ways, ranging from addressing climate change to enhancing cybersecurity. I would be really ecstatic to apply my skills in various programming languages and tools such as Java, Angular/Typescript and git, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of Experian, which is to develop high performance and well tested code to bring about a greater benefit to the community. + +I am enthusiastic about joining the graduate program, it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Experian will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! +* Cambridge Consultants +Dear Hiring Manager, + + + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate embedded software engineer and problem solver with experience extending into DevOps and low-level programming, then I believe I'm the perfect candidate for the role. + + + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + + + +In addition to my technical background, I have experience with DevOps tools, including Ansible, Docker, and Jenkins, gained through self learning and practical application. I am also familiar with bash scripting, which is something I find myself coming back to whenever I want to automate something; this I usually do in bash and python, occasionally, for the purpose of challenging myself, I would use Haskell to write scripts. In addition, I write scripts that allow me to communicate with hardware connected to a raspberry Pi; whenever I have the free time, I dive into embedded programming as this is a huge interest of mine. I am certain that these skills will allow me to support the team in solving real client problems at Cambridge Consultants. + + + +I also use Linux as my daily drivers, I have dual booted quite a few machines, some running Ubuntu some running Mint. I also have experience in virutalisation software; this was when I needed to host a local database, hence I fired up a virtual machine running minimal Ubuntu and kept a PSQL server on there. + + + +I am enthusiastic about joining the Cambridge Consultants; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Cambridge Consultants will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + + + +Warm regards, + +Zaine-Ul-Abideen Qayyum +* Adelphi Real World +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate problem solver with a strong foundation in data analysis and a drive to deliver precise and efficient solutions, I believe I am the ideal candidate for this role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction, this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at Adelphi, where challenges are primarily user centric. + +What draws me most to Adelphi Real World is their commitment to leveraging real world data to improve healthcare outcomes. The mere prospect of contributing to this mission by using tools like SPSS, Confirmit, and Excel, and supporting fieldwork and data processing, aligns perfectly with my dream of using technology to help others. I would be really ecstatic to apply my analytical skills, programming knowledge, and meticulous attention to detail to bring about a greater benefit to Adelphi, the healthcare sector and the community. + +I am enthusiastic about joining this esteemed organisation, it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Adelphi Real World will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, + +Zaine-Ul-Abideen Qayyum +* Midland Heart +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate problem solver with a strong foundation in data analysis and a drive to deliver precise and efficient solutions, I believe I am the ideal candidate for this role. + +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction, this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. + +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at Midland Heart, where challenges are primarily user centric. + +What draws me most to Midland Heart is their commitment to leveraging real world data to improve tenancy outcomes. The mere prospect of contributing to this mission by using tools like Power Bi, Python, and Cloud Services, and supporting fieldwork and data processing, aligns perfectly with my dream of using technology to help others. I would be ecstatic to apply my analytical skills, programming knowledge, and meticulous attention to detail to bring about a greater benefit to Midland Heart, the housing sector and the community. + +I am enthusiastic about joining this esteemed organisation, it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that Midland Heart will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* EDW +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate Software Tester and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at EDW Technology, where challenges are primarily user centric. +What draws me most to EDW Technology is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. EDW Technology achieves this in various ways, ranging from creating energy management tools to providing user focused solutions. I would be ecstatic to apply my skills in various programming languages and tools such as Java, Swagger, and Git, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of EDW Technology, which is to develop high performance and well tested code to bring about a greater benefit to the community. +I am enthusiastic about joining the graduate program; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that EDW Technology will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* DCA +Dear Hiring Manager, + +I would firstly like to extend my gratitude for giving me the opportunity to apply for an amazing role. If you are looking for a passionate software engineer and problem solver with experience extending into other disciplines, then I believe I'm the perfect candidate for the role. +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. One of the biggest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. In addition, I find myself often using Python for visualising data on a networking module, and for various scripting purposes. I have also built a full stack NLP/AI powered note taking web application to address the issue of cognitive overload. +Beyond this, I also work as a tutor at Tutors United, where I teach Mathematics and English to students coming from lower socio-economic backgrounds, and who are neurodiverse. This experience has taught me many things, two that are notable are communication and adaptability. These two skills together have taught me the importance of understanding as well as addressing challenges, which I believe will translate well at DCA, where challenges are primarily user centric. +What draws me most to DCA is their commitment to using technology to bring good to the community. This, I would say, is one of the reasons I decided to go into the field of tech, which was to help others. DCA achieves this in various ways, ranging from addressing novel transport solutions to developing safety-critical medical devices. I would be really ecstatic to apply my skills in various programming languages and tools such as Git, Docker, and Nginx, coupled with my foundational knowledge of cloud services like AWS and Oracle cloud to the mission of DCA, which is to develop high performance and well tested code to bring about a greater benefit to the community +I am enthusiastic about joining the graduate program; it is a core principle of mine that continuous learning will propel one to unimaginable heights, and I firmly believe that DCA will be able to provide the means to make that happen. Thank you for considering my application, I look forward to discussing my candidacy further! + +Warm regards, +Zaine-Ul-Abideen Qayyum +* emp +Describe something you have done that you are proud of. (Word limit 250 words) +One of the proudest projects I have worked on was a football finding web app which I was entrusted to lead and resulted in a 14% increase in user satisfaction; this was built using Java Spring Boot, Typescript/Angular and PostgreSQL. However, my proudest work to date was a full stack web application that utilises AI and NLP to reduce cognitive overload faced in students. This was an ongoing long-term project and has taken me 7 months to complete. I used Spring Boot, Angular/Typescript along with Python scripting. + +How can you demonstrate your current curiosity around technology to us? (Word Limit 250 words) +There are two things I have always been interested in growing up: Technology and Problem solving. My technical journey began when I joined the University of Birmingham, where I have developed solid foundations in data analysis, software development and problem solving. I find myself more so immersed in technical related hobbies such as ‘ricing’ a Linux distro, configuration of Emacs, tinkering with embedded programming using Raspberry Pi. + +Can you describe to us a scenario where you have demonstrated either creativity, innovation or originality (Word Limit 250 words) +One of the most innovative projects I have worked on was my AI-assisted note-taking web application, designed to combat cognitive overload in students. The challenge was to create an intuitive system that could process and summarise lecture content efficiently while al-lowing students to interact with it seamlessly. I thus decided on using OpenAI’s API for basic requests (intelligence enhanced which allowed it to see what the user is doing through parsing the canvas object), natural language processing (NLP), integrating it with an Angular TypeScript frontend and a Spring Boot backend. +What made this project particularly creative was my decision to incorporate adaptive sum-marisation, meaning the AI tailors the level of detail in notes based on the user’s prefer-ences and previous study patterns. Unlike traditional note-taking applications, this one con-tinuously learns from user behavior, refining its output over time. Furthermore, I used YAKE and TF-IDF to extract keywords from the notes, as well as NER (named entity recognition). diff --git a/20241212011909-career_roam.org~ b/20241212011909-career_roam.org~ new file mode 100755 index 0000000..01178ca --- /dev/null +++ b/20241212011909-career_roam.org~ @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: fe5086b8-1941-4125-881a-65d01e1e7774 +:END: +#+title: Career roam +#+filetags: :pre-career:index: + + + +Microlise Assessment Centre: [[id:f877240e-c2c8-4087-84e5-4b1ca3fcd4ed][microlise-assessment]] diff --git a/20241212013207-haskell_notes.org b/20241212013207-haskell_notes.org new file mode 100755 index 0000000..615a4cf --- /dev/null +++ b/20241212013207-haskell_notes.org @@ -0,0 +1,54 @@ +:PROPERTIES: +:ID: 347d2663-515b-4d9a-9ee9-7706ee86a845 +:END: +#+title: haskell_notes +#+filetags: :index:notes:haskell:coding: + + +* Haskell Notes +** Introduction +Haskell is a purely functional programming language with strong static typing and [[id:63456626-b34e-46d9-b85e-0f1f5724aa83][lazy_evaluation]] . It was named after the logician Haskell Curry. It is widely used in academia and industry for teaching and research as well as for writing industrial applications. + +** Features of Haskell +- Purely Functional: Functions in Haskell are pure, meaning they don't have side effects. +- Strong Static Typing: Types are checked at compile time, reducing runtime errors. +- Lazy Evaluation: Expressions are not evaluated until their values are needed. +- Type Inference: Haskell can automatically infer types, making the code more concise. +- Concise Syntax: Haskell's syntax is clean and concise, making it easy to read and write. + +** Getting Started with Haskell +- Installation: To get started with Haskell, you need to install the Glasgow Haskell Compiler (GHC). You can download it from [[https://www.haskell.org/downloads/][Download]] +- Basic Syntax: + - Comments: Single line comments start with `--`, and multi-line comments are enclosed within `{-` and `-}`. + - Modules: Code is organized into modules, which can be imported using the `import` keyword. + +** Basic Concepts +- Functions: Functions are first-class citizens in Haskell. A function definition looks like this: + #+BEGIN_SRC haskell + add :: Int -> Int -> Int + add x y = x + y + #+END_SRC + This defines a function *add* that takes two integers and returns their sum. + +- Types and Type Classes: Types are a crucial part of Haskell. You define types using the `data` keyword, and type classes using the `class` keyword. + +** Example +Here's a simple example to demonstrate some basic features of Haskell: + #+BEGIN_SRC haskell + -- Define a new data type + data Shape = Circle Float | Rectangle Float Float + + -- Define a function to calculate the area of a shape + area :: Shape -> Float + area (Circle r) = pi * r^2 + area (Rectangle l w) = l * w + + -- Example usage + main = do + let c = Circle 10 + let r = Rectangle 5 7 + print (area c) + print (area r) + #+END_SRC + +This example defines a new data type Shape with two constructors, Circle and Rectangle, and a function area that calculates the area of a shape. diff --git a/20241212013207-haskell_notes.org~ b/20241212013207-haskell_notes.org~ new file mode 100755 index 0000000..df56991 --- /dev/null +++ b/20241212013207-haskell_notes.org~ @@ -0,0 +1,54 @@ +:PROPERTIES: +:ID: 347d2663-515b-4d9a-9ee9-7706ee86a845 +:END: +#+title: Haskell Notes +#+filetags: :technical:notes:haskell:coding: + + +* Haskell Notes +** Introduction +Haskell is a purely functional programming language with strong [[id:729441d1-51d5-4d94-8fe6-ff9ebb3f5739][Static Typing]] and [[id:63456626-b34e-46d9-b85e-0f1f5724aa83][Lazy Evaluation]]. It was named after the logician Haskell Curry. It is widely used in academia and industry for teaching and research as well as for writing industrial applications. + +** Features of Haskell +- Purely Functional: Functions in Haskell are pure, meaning they don't have side effects. +- Strong Static Typing: Types are checked at compile time, reducing runtime errors. +- Lazy Evaluation: Expressions are not evaluated until their values are needed. +- Type Inference: Haskell can automatically infer types, making the code more concise. +- Concise Syntax: Haskell's syntax is clean and concise, making it easy to read and write. + +** Getting Started with Haskell +- Installation: To get started with Haskell, you need to install the Glasgow Haskell Compiler (GHC). You can download it from [[https://www.haskell.org/downloads/][Download]] +- Basic Syntax: + - Comments: Single line comments start with `--`, and multi-line comments are enclosed within `{-` and `-}`. + - Modules: Code is organized into modules, which can be imported using the `import` keyword. + +** Basic Concepts +- Functions: Functions are first-class citizens in Haskell. A function definition looks like this: + #+BEGIN_SRC haskell + add :: Int -> Int -> Int + add x y = x + y + #+END_SRC + This defines a function *add* that takes two integers and returns their sum. + +- Types and Type Classes: Types are a crucial part of Haskell. You define types using the `data` keyword, and type classes using the `class` keyword. + +** Example +Here's a simple example to demonstrate some basic features of Haskell: + #+BEGIN_SRC haskell + -- Define a new data type + data Shape = Circle Float | Rectangle Float Float + + -- Define a function to calculate the area of a shape + area :: Shape -> Float + area (Circle r) = pi * r^2 + area (Rectangle l w) = l * w + + -- Example usage + main = do + let c = Circle 10 + let r = Rectangle 5 7 + print (area c) + print (area r) + #+END_SRC + +This example defines a new data type Shape with two constructors, Circle and Rectangle, and a function area that calculates the area of a shape. diff --git a/20241212013902-lazy_evaluation.org b/20241212013902-lazy_evaluation.org new file mode 100755 index 0000000..37cba5b --- /dev/null +++ b/20241212013902-lazy_evaluation.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 63456626-b34e-46d9-b85e-0f1f5724aa83 +:END: +#+title: lazy_evaluation +#+filetags: :haskell:coding:notes: + +See this article: [[https://medium.com/background-thread/what-is-lazy-evaluation-programming-word-of-the-day-8a6f4410053f][Lazy eval]] + +There are two types of evaluation: strict and lazy diff --git a/20241212013902-lazy_evaluation.org~ b/20241212013902-lazy_evaluation.org~ new file mode 100755 index 0000000..f40e5c3 --- /dev/null +++ b/20241212013902-lazy_evaluation.org~ @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 63456626-b34e-46d9-b85e-0f1f5724aa83 +:END: +#+title: Lazy Evaluation +#+filetags: :haskell:coding:notes: + +See this article: [[https://medium.com/background-thread/what-is-lazy-evaluation-programming-word-of-the-day-8a6f4410053f][Lazy eval]] + +There are two types of evaluation: strict and lazy diff --git a/20241213005125-c_notes.org b/20241213005125-c_notes.org new file mode 100755 index 0000000..e09df76 --- /dev/null +++ b/20241213005125-c_notes.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 5a207a1c-6f02-40d5-b42e-38daaa0aec10 +:END: +#+title: c_notes +#+filetags: :index:coding:notes: + +[[id:efe0360d-8d81-4372-833d-ad58e67d17c6][socket_programming_in_c]] + +[[id:d939e477-d1e9-43ea-960e-8727246d12a3][useful-c-imports]] diff --git a/20241213005125-c_notes.org~ b/20241213005125-c_notes.org~ new file mode 100755 index 0000000..71a2f4e --- /dev/null +++ b/20241213005125-c_notes.org~ @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: 5a207a1c-6f02-40d5-b42e-38daaa0aec10 +:END: +#+title: c_notes +#+filetags: :index:coding:notes: + +[[id:efe0360d-8d81-4372-833d-ad58e67d17c6][socket_programming_in_c]] diff --git a/20241213005156-socket_programming_in_c.org b/20241213005156-socket_programming_in_c.org new file mode 100755 index 0000000..c170527 --- /dev/null +++ b/20241213005156-socket_programming_in_c.org @@ -0,0 +1,31 @@ +:PROPERTIES: +:ID: efe0360d-8d81-4372-833d-ad58e67d17c6 +:END: +#+title: socket_programming_in_c +#+filetags: :networking:coding:notes: + +From: [[https://www.linuxhowtos.org/C_C++/socket.htm][Web Link]] +* Steps: +The steps involved in establishing a socket on the client side are as follows: + +1. Create a socket with the socket() system call +2. Connect the socket to the address of the server using the connect() system call +3. Send and receive data. There are a number of ways to do this, but the simplest is to use the read() and write() system calls. + +The steps involved in establishing a socket on the server side are as follows: + +1. Create a socket with the socket() system call +2. Bind the socket to an address using the bind() system call. For a server socket on the Internet, an address consists of a port number on the host machine. +3. Listen for connections with the listen() system call +4. Accept a connection with the accept() system call. This call typically blocks until a client connects with the server. +5. Send and receive data +* Socket types: +When you create a socket, you must specify the *address domain* and the *socket type*, the client and server can only communicate if they are of the same type and in the same domain. + +The two most common address domains: +- unix domain (they share common file system) +- internet domain + +The two most common socket types: +- stream sockets (continuous stream of characters) - uses tcp +- datagram sockets (reads the entire messages at once) - uses dp diff --git a/20241213005156-socket_programming_in_c.org~ b/20241213005156-socket_programming_in_c.org~ new file mode 100755 index 0000000..e96a4dd --- /dev/null +++ b/20241213005156-socket_programming_in_c.org~ @@ -0,0 +1,31 @@ +:PROPERTIES: +:ID: efe0360d-8d81-4372-833d-ad58e67d17c6 +:END: +#+title: Socket Programming in C +#+filetags: :networking:coding:notes: + +From: [[https://www.linuxhowtos.org/C_C++/socket.htm][Web Link]] +* Steps: +The steps involved in establishing a socket on the client side are as follows: + +1. Create a socket with the socket() system call +2. Connect the socket to the address of the server using the connect() system call +3. Send and receive data. There are a number of ways to do this, but the simplest is to use the read() and write() system calls. + +The steps involved in establishing a socket on the server side are as follows: + +1. Create a socket with the socket() system call +2. Bind the socket to an address using the bind() system call. For a server socket on the Internet, an address consists of a port number on the host machine. +3. Listen for connections with the listen() system call +4. Accept a connection with the accept() system call. This call typically blocks until a client connects with the server. +5. Send and receive data +* Socket types: +When you create a socket, you must specify the *address domain* and the *socket type*, the client and server can only communicate if they are of the same type and in the same domain. + +The two most common address domains: +- unix domain (they share common file system) +- internet domain + +The two most common socket types: +- stream sockets (continuous stream of characters) - uses tcp +- datagram sockets (reads the entire messages at once) - uses dp diff --git a/20241217234535-web_port_notes.org b/20241217234535-web_port_notes.org new file mode 100755 index 0000000..456f4a2 --- /dev/null +++ b/20241217234535-web_port_notes.org @@ -0,0 +1,246 @@ +:PROPERTIES: +:ID: 348df473-6443-4f4a-b366-95397b574989 +:END: +#+title: web-port-notes +#+filetags: :index:docs:zzq: + +* <2025-11-06 Thu> old sitemap for blogs: + +(defun zz/2025-sitemap (title list) + "sitemap that lists 2025 links as bullet points with dates and tags." + (concat + "#+TITLE: " title "\n" + "#+OPTIONS: toc:nil num:nil \n\n" + "See the categories: @@html:Categories@@\n\n" + "* 2025:\n" + (mapconcat + (lambda (entry) + (let* ((link (car entry)) + ;; extract relative file name from the link + (filename (if (string-match "\\[\\[file:\\([^]]+\\)\\]" link) + (match-string 1 link) + link)) + (full-path (expand-file-name filename "~/master-folder/org_files/org_web/blogs/2025/")) + (date-str "no date") + (tags-str "")) + ;; Get publish date + (let ((date (org-publish-find-date full-path org-publish-project-alist))) + (when date + (setq date-str (format-time-string "%d-%m-%Y %H:%M" date)))) + ;; Get FILETAGS from file buffer + (when (file-exists-p full-path) + (with-temp-buffer + (insert-file-contents full-path) + (org-mode) + (let* ((tags (cadr (assoc "FILETAGS" (org-collect-keywords '("FILETAGS")))))) + (when tags + (setq tags-str (mapconcat (lambda (tag) + (format "@@html: %s @@" tag tag)) + (split-string tags ":" t) ;; <- Splits by ":" and removes empty strings + " ")))))) + ;; Final line output + (format "- %s @@html:%s@@ %s" link date-str tags-str))) + (cdr list) + "\n"))) + + + +* Footnotes and sidenotes + +Here is a list of macros: + +#+begin_src emacs-lisp + (setq org-export-global-macros + (append + '( + + ("sidenote" + . "@@html:$2@@") + + ("epigraph" . "@@html:
$1
$2
@@") + + ("epigraph_single" . "@@html:
$1
@@") + + ("epigraph3" . "@@html:
$1
$2, $3
@@") + + ("kbd" . "@@html:$1@@@@latex:\\texttt{$1}@@") + + ("margimg" + . "@@html:@@") + + + org-export-global-macros))) + + +#+end_src + +They are used as follows: + +{{{sidenote(1, The very first iteration of this website used the Angular framework\, only after a while I realised (as every Emacs lover does) that I want to make this an Emacs-centric project)}}} + +Use footnotes as follows: +[fn:1] +then put them at the bottom with the respective information. + +* Blorgz + +** ideas: +### **Personal Growth & Self-Improvement** +1. **The Power of Journaling: How Writing Every Day Can Transform Your Life** + - Exploring the benefits of journaling for mental clarity, goal setting, and emotional processing. + +2. **The Science of Happiness: What Really Makes Us Happy?** + - A deep dive into the psychology and neuroscience of happiness and how to apply it to daily life. + +3. **Building a Growth Mindset: How to Shift from a Fixed to a Growth-Oriented Outlook** + - Practical steps and insights on adopting a growth mindset for personal and professional development. + +4. **How to Set and Achieve Long-Term Goals** + - A structured approach to setting clear, actionable goals and staying motivated over time. + +5. **Embracing Failure: How to Learn and Grow from Setbacks** + - Understanding the importance of failure and how to reframe it as an opportunity for growth. + +### **Mental Health & Well-being** +6. **Dealing with Anxiety: Techniques to Cope and Build Resilience** + - Mindfulness, cognitive-behavioral strategies, and lifestyle changes that help manage anxiety. + +7. **How to Build Emotional Intelligence (EQ) for Better Relationships** + - Tips for recognizing, understanding, and managing your own emotions, and how to navigate others' emotions. + +8. **The Importance of Sleep for Mental and Physical Health** + - Why sleep is crucial for your overall well-being, along with tips for improving your sleep hygiene. + +9. **How to Practice Self-Compassion and Be Kinder to Yourself** + - Exploring the importance of self-compassion and how to stop being your own harshest critic. + +10. **Breaking the Cycle of Negative Self-Talk** + - How to identify, challenge, and reframe the negative thoughts that hold you back. + +### **Lifestyle & Balance** +11. **Minimalism: How Decluttering Your Life Can Lead to More Freedom** + - A guide to adopting a minimalist lifestyle, including decluttering your home, work, and digital space. + +12. **The Importance of Work-Life Balance and How to Achieve It** + - Strategies for maintaining a healthy balance between your career, personal life, and self-care. + +13. **How to Create a Morning Routine That Sets You Up for Success** + - A step-by-step guide to designing a morning routine that boosts your productivity and mindset. + +14. **The Power of Saying 'No': Setting Boundaries to Protect Your Time and Energy** + - How to say no gracefully and why it’s important for your mental health and well-being. + +15. **Building Strong Relationships: The Art of Effective Communication** + - How to communicate more clearly and empathetically in both personal and professional settings. + +### **Life Philosophy & Reflection** +16. **Living with Purpose: How to Find Your Life’s Meaning** + - A philosophical exploration of how to align your actions with your core values and life purpose. + +17. **Stoicism for Modern Life: How Ancient Philosophy Can Help You Thrive Today** + - Applying Stoic principles to improve resilience, clarity, and calm in the face of challenges. + +18. **The Concept of ‘Ikigai’: Finding Joy and Fulfillment in Your Work and Life** + - Exploring the Japanese philosophy of Ikigai and how to apply it for greater fulfillment and balance. + +19. **How to Handle Life Transitions: Moving Forward with Confidence** + - Tips for navigating big life changes, from job shifts to personal transformations. + +20. **The Importance of Gratitude: How to Cultivate a Daily Practice for a More Positive Life** + - The science behind gratitude and how to incorporate it into your daily life to increase happiness. + +### **Productivity in Daily Life** +21. **Time Management for Busy People: How to Get More Done Without Burning Out** + - Techniques like time blocking, prioritization, and task batching to make your day more productive. + +22. **Overcoming Overwhelm: How to Tackle Large Tasks Without Feeling Stressed** + - Breaking down big tasks into manageable chunks to prevent feelings of stress or burnout. + +23. **The Importance of Play and Fun in a Productive Life** + - How leisure and play are just as important for mental health and long-term productivity. + +24. **How to Stay Motivated During Long-Term Projects** + - Strategies for maintaining motivation and momentum over the course of a long, challenging task. + +25. **Creating a Digital Detox: How to Unplug and Recharge** + - The benefits of taking time away from screens and how to implement a healthy digital detox. + + +** my emacs.config +- [[id:b2db0b0b-c179-43ab-9e2b-22bbaac69bcb][wp-emacs-config-blorg]] +** prefrontal-cortex +- [[id:b292f5c6-0c27-439c-8274-2150eb45e20d][wp-prefront-cortex-blorg]] +** new emacs config written on: <2025-02-14 Fri> +[[id:1ee754f9-f30f-4976-850b-d18d01a834d2][wp-new-emacs-config-blorg]] +** urge surfing: <2025-03-14 Fri> +[[id:cfc4ce06-7862-49b7-9a4f-e515d690cd38][wp-urge-surfing-blorg]] +** growth mindset +[[id:CD093B85-BF68-4EAB-AABE-733C7BFC99DE][wp-growth-mindset]] <2025-03-14 Fri> +** emotional intelligence +[[id:D02B89DC-84D0-4211-A902-B9399F4179CA][wp-emotional-intelligence]] <2025-03-16 Sun> +** reflection on week 12 +[[id:8CD2F4C4-22C2-4ECC-8F5F-C4779F8AC0F1][wp-week-12-reflections]] +** sadness +[[id:462F091B-9156-48B3-8665-0BE36C95C182][wp-sadness]] +* Commits +** code: +You can add a commit detail by doing this: +#+begin_src elist +(insert-commit-template) +;; "SPC c i c" +#+end_src +** Commit on <2024-12-17 Tue> +*** Details +This commit was focused on getting the blog section ready. So far ive decided to go for a static approach, whereby the blogs are stored in a .json file and populated in an array. The 'slug' property is found in: +- the title of the file (blog) +- the metadata of the blog +- the metadata of the index.json +These three must be consistent +*** What to work on next: +- the rendering of the content of the blogs +- the github project population: match the blog page stylings. +*** Commit message: +"Worked on the blog page, did stylings and began to populate" +** Commit on <2024-12-18 Wed> +*** Details +Decided to change the way the blog is rendered. Using a json index object to display the list (slug is importnant), then blog detail is displayed as a rendered *HTML* from a markdown file. The scss was changed as well: +#+begin_src js +"node_modules/prismjs/themes/prism-dark.css" +#+end_src +this loads the theme for the code blocks. +*** What to work on next: +- the github project population: match the blog page stylings. +*** Commit message: +"continued work on blog page, stylings are done, the rendering changed from using json to md." +** Commit on <2024-12-20 Fri> +*** Details +Worked on the github project display, kept the same look as the blogs. Also done the about me section in the homepage (added some random ai generated info - need to change). Also done the contacts (set up a smpt gmail server) +*** What to work on next: +- Get rid of all the hardcoded blogs, and begin first blog. +*** Commit message: +"finished contact section - added smtp gmail server" +** Commit on <2025-01-01 Wed> +*** Details +Deployed (changed back to emailjs) +*** What to work on next: +*** Commit message: +** Commit on <2025-01-12 Sun> +*** Details +- added new blog: prefrontal cortex and self discipline +- added a estimated time to read +*** What to work on next: +more blogs +*** Commit message: +"added new blog" +** Commit on <2025-02-15 Sat> +*** Details +- added tags with persistency. Redid the whole UI (theme) +*** What to work on next: +- add a cv section +*** Commit message: +** Commit on <2025-03-14 Fri> +*** Details +- added quizzes and used firebase for storage +*** What to work on next: +- rendering of images , spending more time on blogs and creating quizzes +*** Commit message: diff --git a/20241217234535-web_port_notes.org~ b/20241217234535-web_port_notes.org~ new file mode 100755 index 0000000..565c3ab --- /dev/null +++ b/20241217234535-web_port_notes.org~ @@ -0,0 +1,205 @@ +:PROPERTIES: +:ID: 348df473-6443-4f4a-b366-95397b574989 +:END: +#+title: web-port-notes +#+filetags: :index:docs:zzq: + +* Footnotes and sidenotes + +Here is a list of macros: + +#+begin_src emacs-lisp + (setq org-export-global-macros + (append + '( + + ("sidenote" + . "@@html:$2@@") + + ("epigraph" . "@@html:
$1
$2
@@") + + ("epigraph_single" . "@@html:
$1
@@") + + ("epigraph3" . "@@html:
$1
$2, $3
@@") + + ("kbd" . "@@html:$1@@@@latex:\\texttt{$1}@@") + + ("margimg" + . "@@html:@@") + + + org-export-global-macros))) + + +#+end_src + +They are used as follows: + +{{{sidenote(1, The very first iteration of this website used the Angular framework\, only after a while I realised (as every Emacs lover does) that I want to make this an Emacs-centric project)}}} + +Use footnotes as follows: +[fn:1] +then put them at the bottom with the respective information. + +* Blorgz + +** ideas: +### **Personal Growth & Self-Improvement** +1. **The Power of Journaling: How Writing Every Day Can Transform Your Life** + - Exploring the benefits of journaling for mental clarity, goal setting, and emotional processing. + +2. **The Science of Happiness: What Really Makes Us Happy?** + - A deep dive into the psychology and neuroscience of happiness and how to apply it to daily life. + +3. **Building a Growth Mindset: How to Shift from a Fixed to a Growth-Oriented Outlook** + - Practical steps and insights on adopting a growth mindset for personal and professional development. + +4. **How to Set and Achieve Long-Term Goals** + - A structured approach to setting clear, actionable goals and staying motivated over time. + +5. **Embracing Failure: How to Learn and Grow from Setbacks** + - Understanding the importance of failure and how to reframe it as an opportunity for growth. + +### **Mental Health & Well-being** +6. **Dealing with Anxiety: Techniques to Cope and Build Resilience** + - Mindfulness, cognitive-behavioral strategies, and lifestyle changes that help manage anxiety. + +7. **How to Build Emotional Intelligence (EQ) for Better Relationships** + - Tips for recognizing, understanding, and managing your own emotions, and how to navigate others' emotions. + +8. **The Importance of Sleep for Mental and Physical Health** + - Why sleep is crucial for your overall well-being, along with tips for improving your sleep hygiene. + +9. **How to Practice Self-Compassion and Be Kinder to Yourself** + - Exploring the importance of self-compassion and how to stop being your own harshest critic. + +10. **Breaking the Cycle of Negative Self-Talk** + - How to identify, challenge, and reframe the negative thoughts that hold you back. + +### **Lifestyle & Balance** +11. **Minimalism: How Decluttering Your Life Can Lead to More Freedom** + - A guide to adopting a minimalist lifestyle, including decluttering your home, work, and digital space. + +12. **The Importance of Work-Life Balance and How to Achieve It** + - Strategies for maintaining a healthy balance between your career, personal life, and self-care. + +13. **How to Create a Morning Routine That Sets You Up for Success** + - A step-by-step guide to designing a morning routine that boosts your productivity and mindset. + +14. **The Power of Saying 'No': Setting Boundaries to Protect Your Time and Energy** + - How to say no gracefully and why it’s important for your mental health and well-being. + +15. **Building Strong Relationships: The Art of Effective Communication** + - How to communicate more clearly and empathetically in both personal and professional settings. + +### **Life Philosophy & Reflection** +16. **Living with Purpose: How to Find Your Life’s Meaning** + - A philosophical exploration of how to align your actions with your core values and life purpose. + +17. **Stoicism for Modern Life: How Ancient Philosophy Can Help You Thrive Today** + - Applying Stoic principles to improve resilience, clarity, and calm in the face of challenges. + +18. **The Concept of ‘Ikigai’: Finding Joy and Fulfillment in Your Work and Life** + - Exploring the Japanese philosophy of Ikigai and how to apply it for greater fulfillment and balance. + +19. **How to Handle Life Transitions: Moving Forward with Confidence** + - Tips for navigating big life changes, from job shifts to personal transformations. + +20. **The Importance of Gratitude: How to Cultivate a Daily Practice for a More Positive Life** + - The science behind gratitude and how to incorporate it into your daily life to increase happiness. + +### **Productivity in Daily Life** +21. **Time Management for Busy People: How to Get More Done Without Burning Out** + - Techniques like time blocking, prioritization, and task batching to make your day more productive. + +22. **Overcoming Overwhelm: How to Tackle Large Tasks Without Feeling Stressed** + - Breaking down big tasks into manageable chunks to prevent feelings of stress or burnout. + +23. **The Importance of Play and Fun in a Productive Life** + - How leisure and play are just as important for mental health and long-term productivity. + +24. **How to Stay Motivated During Long-Term Projects** + - Strategies for maintaining motivation and momentum over the course of a long, challenging task. + +25. **Creating a Digital Detox: How to Unplug and Recharge** + - The benefits of taking time away from screens and how to implement a healthy digital detox. + + +** my emacs.config +- [[id:b2db0b0b-c179-43ab-9e2b-22bbaac69bcb][wp-emacs-config-blorg]] +** prefrontal-cortex +- [[id:b292f5c6-0c27-439c-8274-2150eb45e20d][wp-prefront-cortex-blorg]] +** new emacs config written on: <2025-02-14 Fri> +[[id:1ee754f9-f30f-4976-850b-d18d01a834d2][wp-new-emacs-config-blorg]] +** urge surfing: <2025-03-14 Fri> +[[id:cfc4ce06-7862-49b7-9a4f-e515d690cd38][wp-urge-surfing-blorg]] +** growth mindset +[[id:CD093B85-BF68-4EAB-AABE-733C7BFC99DE][wp-growth-mindset]] <2025-03-14 Fri> +** emotional intelligence +[[id:D02B89DC-84D0-4211-A902-B9399F4179CA][wp-emotional-intelligence]] <2025-03-16 Sun> +** reflection on week 12 +[[id:8CD2F4C4-22C2-4ECC-8F5F-C4779F8AC0F1][wp-week-12-reflections]] +** sadness +[[id:462F091B-9156-48B3-8665-0BE36C95C182][wp-sadness]] +* Commits +** code: +You can add a commit detail by doing this: +#+begin_src elist +(insert-commit-template) +;; "SPC c i c" +#+end_src +** Commit on <2024-12-17 Tue> +*** Details +This commit was focused on getting the blog section ready. So far ive decided to go for a static approach, whereby the blogs are stored in a .json file and populated in an array. The 'slug' property is found in: +- the title of the file (blog) +- the metadata of the blog +- the metadata of the index.json +These three must be consistent +*** What to work on next: +- the rendering of the content of the blogs +- the github project population: match the blog page stylings. +*** Commit message: +"Worked on the blog page, did stylings and began to populate" +** Commit on <2024-12-18 Wed> +*** Details +Decided to change the way the blog is rendered. Using a json index object to display the list (slug is importnant), then blog detail is displayed as a rendered *HTML* from a markdown file. The scss was changed as well: +#+begin_src js +"node_modules/prismjs/themes/prism-dark.css" +#+end_src +this loads the theme for the code blocks. +*** What to work on next: +- the github project population: match the blog page stylings. +*** Commit message: +"continued work on blog page, stylings are done, the rendering changed from using json to md." +** Commit on <2024-12-20 Fri> +*** Details +Worked on the github project display, kept the same look as the blogs. Also done the about me section in the homepage (added some random ai generated info - need to change). Also done the contacts (set up a smpt gmail server) +*** What to work on next: +- Get rid of all the hardcoded blogs, and begin first blog. +*** Commit message: +"finished contact section - added smtp gmail server" +** Commit on <2025-01-01 Wed> +*** Details +Deployed (changed back to emailjs) +*** What to work on next: +*** Commit message: +** Commit on <2025-01-12 Sun> +*** Details +- added new blog: prefrontal cortex and self discipline +- added a estimated time to read +*** What to work on next: +more blogs +*** Commit message: +"added new blog" +** Commit on <2025-02-15 Sat> +*** Details +- added tags with persistency. Redid the whole UI (theme) +*** What to work on next: +- add a cv section +*** Commit message: +** Commit on <2025-03-14 Fri> +*** Details +- added quizzes and used firebase for storage +*** What to work on next: +- rendering of images , spending more time on blogs and creating quizzes +*** Commit message: diff --git a/20241217234944-wp_emacs_config_blorg.org b/20241217234944-wp_emacs_config_blorg.org new file mode 100755 index 0000000..91aa7bb --- /dev/null +++ b/20241217234944-wp_emacs_config_blorg.org @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: b2db0b0b-c179-43ab-9e2b-22bbaac69bcb +:END: +#+title: wp-emacs-config-blorg +#+filetags: :zzq:blogs: + +[[file:~/master-folder/projects/web-port/md-files/emacs_config.md][file]] diff --git a/20241217234944-wp_emacs_config_blorg.org~ b/20241217234944-wp_emacs_config_blorg.org~ new file mode 100755 index 0000000..2ffd941 --- /dev/null +++ b/20241217234944-wp_emacs_config_blorg.org~ @@ -0,0 +1,6 @@ +:PROPERTIES: +:ID: b2db0b0b-c179-43ab-9e2b-22bbaac69bcb +:END: +#+title: wp-emacs-config-blorg + +[[file:~/master-folder/projects/web-port/md-files/emacs_config.md][file]] diff --git a/20241220234456-github_notes.org b/20241220234456-github_notes.org new file mode 100755 index 0000000..f647da4 --- /dev/null +++ b/20241220234456-github_notes.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 710f65e5-0bd4-42be-b5d1-69dbe79b745e +:END: +#+title: github_notes +#+filetags: :git:notes: + +* Open Source Projects: +- [[https://github.com/codecrafters-io/build-your-own-x?tab=readme-ov-file][Build your own `x`]] +https://www.atlassian.com/git/tutorials/saving-changes/gitignore diff --git a/20241220234456-github_notes.org~ b/20241220234456-github_notes.org~ new file mode 100755 index 0000000..b21ffde --- /dev/null +++ b/20241220234456-github_notes.org~ @@ -0,0 +1,8 @@ +:PROPERTIES: +:ID: 710f65e5-0bd4-42be-b5d1-69dbe79b745e +:END: +#+title: github_notes +#+filetags: :git:notes: + +* Open Source Projects: +- [[https://github.com/codecrafters-io/build-your-own-x?tab=readme-ov-file][Build your own `x`]] diff --git a/20241231172511-book_notes.org b/20241231172511-book_notes.org new file mode 100755 index 0000000..b75e6c4 --- /dev/null +++ b/20241231172511-book_notes.org @@ -0,0 +1,16 @@ +:PROPERTIES: +:ID: 2706598f-e6aa-4e88-8d24-5f699bd22787 +:END: +#+title: book_notes +#+filetags: :index:books:notes: + + +* [[id:455ef38f-9a5f-4f62-afe9-25e2261e1282][the_science_of_self_discipline]] + +* [[id:EC9D851F-3A2E-4F32-A584-76F6F7A08E30][the_clean_coder]] + +* [[id:2d7f1ccc-99d7-4c45-8fe7-4b87080edb01][so_good_they_cant_ignore_you]] + +* [[id:dd55d635-59de-4ed9-8ff0-423782c2e0ae][clean-code]] + +* [[id:4426cc9a-1568-4fc8-9242-269654c43a3b][naqshe-hayat]] diff --git a/20241231172511-book_notes.org~ b/20241231172511-book_notes.org~ new file mode 100755 index 0000000..ead8335 --- /dev/null +++ b/20241231172511-book_notes.org~ @@ -0,0 +1,14 @@ +:PROPERTIES: +:ID: 2706598f-e6aa-4e88-8d24-5f699bd22787 +:END: +#+title: book_notes +#+filetags: :index:books:notes: + + +* [[id:455ef38f-9a5f-4f62-afe9-25e2261e1282][the_science_of_self_discipline]] + +* [[id:EC9D851F-3A2E-4F32-A584-76F6F7A08E30][the_clean_coder]] + +* [[id:2d7f1ccc-99d7-4c45-8fe7-4b87080edb01][so_good_they_cant_ignore_you]] + +* [[id:dd55d635-59de-4ed9-8ff0-423782c2e0ae][clean-code]] diff --git a/20241231172543-the_science_of_self_discipline.org b/20241231172543-the_science_of_self_discipline.org new file mode 100755 index 0000000..2332fe8 --- /dev/null +++ b/20241231172543-the_science_of_self_discipline.org @@ -0,0 +1,147 @@ +:PROPERTIES: +:ID: 455ef38f-9a5f-4f62-afe9-25e2261e1282 +:TYPE: Book +:AUTHOR: Peter Hollins +:DATE_STARTED: <2024-12-27 Fri> +:DATE_ENDED: <2025-05-24 Sat> +:END: +#+title: the_science_of_self_discipline +#+filetags: :books: + +* Introduction +Upon completing the book titled "The Science of Self-Discipline" written by Peter Hollins, I wanted to write a +little summary of the lessons the book has to offer. + +* Purpose + +The purpose of the book is to provide a framework for those wanting to build and maintain self-discipline in their +daily routine, through science-based advice and strategies. + +* Biological Basis of Self-Discipline + +One of the first quotes given in the book is from Jim Rohn, who states that: + +> “We must all suffer one of two things: the pain of discipline or the pain of regret.” + +The very first chapter talks about the biology behind self-discipline. The reason for discussing this is that +without having an understanding of the things that cause, diminish or strengthen self-discipline, it would be +difficult to benefit from it. The concept of [[id:a087da71-bcfb-4ddf-9565-b82113d5d27f][neuroplasticity]] is mentioned in the book, which +enables change. Our brain's ability to form and reorganise neural connections alludes to the fact that +self-discipline can be developed and improved over time. The example used is that of a road being taken to and from +work every single day. The more often this road is taken, the more automatic the journey becomes, up to a point +where you will be able to get through it without conscious thought. + +Another important point raised is the concept of *willpower fatigue*. Self-discipline and willpower are not two +static quantities that are fixed, they are like gas in a tank, it can be drained or replenished. Essentially this +emphasises the point that no matter how great somebody's willpower is, it will eventually deplete. How does one +combat this then? One should prioritise important tasks when the willpower is at its highest, larger tasks should be +broken down into smaller ones, and self-care should be practiced to replenish willpower. + +* Two Rules: + +** The 40% Rule + +This rule was developed by Navy SEALs, and states that when you feel like you've reached your mental or physical +limit, the reality is that you've only reached about 40% of your true capacity. This rule allows you to create a +shift in your mindset. Perceived limitations are no longer ones maximum capacity, but rather, this shift pushes you +to tap into hidden reserves and maximises your potential. + +** 10-Minute Rule + +If you ever felt like you crave something, and the urge pushes you to it, the 10 minute rules states that you should +wait for 10 minutes before getting it. If you want to eat a sugary snack, wait for 10 minutes before getting it. +This exercise removes the 'immediate' from immediate gratification, and more-so shows that you *can* withstand your +urges. + +* Discipline Drainers + +The author then goes on to mention common discipline drainers, and how to overcome them. + +** False Hope Syndrome + +Instead of setting unrealistic expectations, set smaller achievable goals, and celebrate the wins along the way. If +you were to do the former, it can quickly lead to disappointment and a decrease in motivation. The latter approach +will give you the sense of accomplishment, build self-confidence and increase momentum, which is more sustainable +over time. + +** Procrastination + +To improve self-discipline, procrastination should be avoided, one should stop waiting to *be ready* or for +everything to feel *just right*. Inaction goes hand in hand with making excuses, and ultimately sabotages the +chances of you getting the thing you want done. The 75% rule was mentioned, where you take action when you are 75% +certain of success. Embracing the imperfection allows you to act, and this action enables you to improve +self-discipline. + +* Flex your Uncomfortable muscle + +By nature self-discipline is uncomfortable. If you were given the choice to play video games or run a mile, most +would choose the former, simply because it is *easier*. Methods such as urge surfing, seeking out +challenges and practicing discomfort are mentioned here that would allow you to develop self-discipline. + +* Create a Disciplined Environment + +The next chapter of the book states that having an environment that is conducive to self-discipline is one of the +most effective and simplest ways to drastically improve ones life. How does one do this? The author lists and +explains ways to create such an environment. From amongst them are: +- Minimising Distractions: essentially you create a clutter-free working environment, and focus on the 'out of sight, + out of mind' principle +- Regulate Dopamine: being mindful of the cues that trigger dopamine release, such as junk food, social media etc. + and instead creating a reward system that enforces positive behaviour and habits +- Optimise default choices: simply put, this is streamlining disciplined behaviour and choosing the path of least + resistance + +* Delayed Gratification + +This chapter was titled 'Why You Should Always Eat Your Vegetables First', and, as one can tell, this is talking +about the art of delaying gratification. The author goes on to explain how this works, and goes back to the +[[id:acba0d25-08db-4784-8cc2-fe5c437ba723][stanford-marshmallow-experiment]]. Two ways one can delay gratification are: +- Visualising your future self: research goes on to state that there is a strong correlation between visualising + your future self and making better long-term decisions. This is simply putting yourself in the shoes of your + future self and imagining what you will be doing in the future +- The 10-10-10 Rule: a question to pose to oneself, asking 'how will I feel in 10 minutes, 10 hours and 10 days?'. + This question forces a perspective shift and can allow you to prioritise long-term benefits over short-term + satisfactions + +* Using targeted questions + +> If you make the effort to ask yourself these four questions and to be +honest in your answers, you’ll become more aware of your tendencies to +rationalize and make excuses, and you’ll be prepared to create better +habits for leading a disciplined life. + +The four questions are as follows: + +1. Do I want to be a disciplined person or not? +2. Am I doing the right thing or simply what’s easy? +3. These are the vegetables, so what am I getting for dessert? +4. Am I being self-aware? + +* Mindset and Approach + +This chapter talks about how our mindset can affect weather we positively or negatively perceive our lives. Some of +the ways one can take on a more positive and optimistic outlook on life are: +- The Endowed Progress Effect: perceiving advancements can make us feel more motivated and optimistic, one can do + this by recognising and acknowledging progress in the past towards a goal +- Goal Proximity: the idea that the closer we are to a goal, the more motivated we are to reach it. +- Think of How Your Actions Can Benefit Others: when one considers how their actions can benefit others, this can + quickly turn into a strong source of motivation and drive +- Think Optimistically: by thinking optimistically, one can create a positive and optimistic outlook on life. The + term used in the book is 'hoping for the best while preparing for the worst' +- Think in Terms of Effort: focus on the effort, not the outcome. When one does this, they are able to enjoy the + process regardless of the outcome + +* Build Routines and Habits + +Motivation is nice to have, but it is something that fluctuates based on emotion and circumstances. Habits on the +other hand, are something concrete and can be built and maintained. Research has shown that it takes 66 days to +build a habit, and requires self-discipline to get through that process. But once it is built, this habit will drive +you instead. The final thing mentioned in the book is the six sources of influence model by Joseph Grenny. These +factors are (1) personal motivation, (2) personal ability, (3) social motivation, (4) social ability, (5) structural +motivation, and (6) structural ability. + +* Summary + +This book is a great read, and taught me a lot about self-discipline and the science behind it. I would definitely +recommend it to anyone who wants to improve their self-discipline. It is, however, something that should be +reflected upon, not all the approaches and strategies are a one-size-fits-all, thus, take it with a grain of salt and +adapt it to your own circumstances. diff --git a/20241231172543-the_science_of_self_discipline.org~ b/20241231172543-the_science_of_self_discipline.org~ new file mode 100755 index 0000000..15e040b --- /dev/null +++ b/20241231172543-the_science_of_self_discipline.org~ @@ -0,0 +1,147 @@ +:PROPERTIES: +:ID: 455ef38f-9a5f-4f62-afe9-25e2261e1282 +:TYPE: Book +:AUTHOR: Peter Hollins +:DATE_STARTED: <2024-12-27 Fri> +:DATE_ENDED: <2025-05-24 Sat> +:END: +#+title: The Science Of Self Discipline +#+filetags: :books:complete: + +* Introduction +Upon completing the book titled "The Science of Self-Discipline" written by Peter Hollins, I wanted to write a +little summary of the lessons the book has to offer. + +* Purpose + +The purpose of the book is to provide a framework for those wanting to build and maintain self-discipline in their +daily routine, through science-based advice and strategies. + +* Biological Basis of Self-Discipline + +One of the first quotes given in the book is from Jim Rohn, who states that: + +> “We must all suffer one of two things: the pain of discipline or the pain of regret.” + +The very first chapter talks about the biology behind self-discipline. The reason for discussing this is that +without having an understanding of the things that cause, diminish or strengthen self-discipline, it would be +difficult to benefit from it. The concept of [[id:a087da71-bcfb-4ddf-9565-b82113d5d27f][neuroplasticity]] is mentioned in the book, which +enables change. Our brain's ability to form and reorganise neural connections alludes to the fact that +self-discipline can be developed and improved over time. The example used is that of a road being taken to and from +work every single day. The more often this road is taken, the more automatic the journey becomes, up to a point +where you will be able to get through it without conscious thought. + +Another important point raised is the concept of *willpower fatigue*. Self-discipline and willpower are not two +static quantities that are fixed, they are like gas in a tank, it can be drained or replenished. Essentially this +emphasises the point that no matter how great somebody's willpower is, it will eventually deplete. How does one +combat this then? One should prioritise important tasks when the willpower is at its highest, larger tasks should be +broken down into smaller ones, and self-care should be practiced to replenish willpower. + +* Two Rules: + +** The 40% Rule + +This rule was developed by Navy SEALs, and states that when you feel like you've reached your mental or physical +limit, the reality is that you've only reached about 40% of your true capacity. This rule allows you to create a +shift in your mindset. Perceived limitations are no longer ones maximum capacity, but rather, this shift pushes you +to tap into hidden reserves and maximises your potential. + +** 10-Minute Rule + +If you ever felt like you crave something, and the urge pushes you to it, the 10 minute rules states that you should +wait for 10 minutes before getting it. If you want to eat a sugary snack, wait for 10 minutes before getting it. +This exercise removes the 'immediate' from immediate gratification, and more-so shows that you *can* withstand your +urges. + +* Discipline Drainers + +The author then goes on to mention common discipline drainers, and how to overcome them. + +** False Hope Syndrome + +Instead of setting unrealistic expectations, set smaller achievable goals, and celebrate the wins along the way. If +you were to do the former, it can quickly lead to disappointment and a decrease in motivation. The latter approach +will give you the sense of accomplishment, build self-confidence and increase momentum, which is more sustainable +over time. + +** Procrastination + +To improve self-discipline, procrastination should be avoided, one should stop waiting to *be ready* or for +everything to feel *just right*. Inaction goes hand in hand with making excuses, and ultimately sabotages the +chances of you getting the thing you want done. The 75% rule was mentioned, where you take action when you are 75% +certain of success. Embracing the imperfection allows you to act, and this action enables you to improve +self-discipline. + +* Flex your Uncomfortable muscle + +By nature self-discipline is uncomfortable. If you were given the choice to play video games or run a mile, most +would choose the former, simply because it is *easier*. Methods such as urge surfing, seeking out +challenges and practicing discomfort are mentioned here that would allow you to develop self-discipline. + +* Create a Disciplined Environment + +The next chapter of the book states that having an environment that is conducive to self-discipline is one of the +most effective and simplest ways to drastically improve ones life. How does one do this? The author lists and +explains ways to create such an environment. From amongst them are: +- Minimising Distractions: essentially you create a clutter-free working environment, and focus on the 'out of sight, + out of mind' principle +- Regulate Dopamine: being mindful of the cues that trigger dopamine release, such as junk food, social media etc. + and instead creating a reward system that enforces positive behaviour and habits +- Optimise default choices: simply put, this is streamlining disciplined behaviour and choosing the path of least + resistance + +* Delayed Gratification + +This chapter was titled 'Why You Should Always Eat Your Vegetables First', and, as one can tell, this is talking +about the art of delaying gratification. The author goes on to explain how this works, and goes back to the +[[id:acba0d25-08db-4784-8cc2-fe5c437ba723][stanford-marshmallow-experiment]]. Two ways one can delay gratification are: +- Visualising your future self: research goes on to state that there is a strong correlation between visualising + your future self and making better long-term decisions. This is simply putting yourself in the shoes of your + future self and imagining what you will be doing in the future +- The 10-10-10 Rule: a question to pose to oneself, asking 'how will I feel in 10 minutes, 10 hours and 10 days?'. + This question forces a perspective shift and can allow you to prioritise long-term benefits over short-term + satisfactions + +* Using targeted questions + +> If you make the effort to ask yourself these four questions and to be +honest in your answers, you’ll become more aware of your tendencies to +rationalize and make excuses, and you’ll be prepared to create better +habits for leading a disciplined life. + +The four questions are as follows: + +1. Do I want to be a disciplined person or not? +2. Am I doing the right thing or simply what’s easy? +3. These are the vegetables, so what am I getting for dessert? +4. Am I being self-aware? + +* Mindset and Approach + +This chapter talks about how our mindset can affect weather we positively or negatively perceive our lives. Some of +the ways one can take on a more positive and optimistic outlook on life are: +- The Endowed Progress Effect: perceiving advancements can make us feel more motivated and optimistic, one can do + this by recognising and acknowledging progress in the past towards a goal +- Goal Proximity: the idea that the closer we are to a goal, the more motivated we are to reach it. +- Think of How Your Actions Can Benefit Others: when one considers how their actions can benefit others, this can + quickly turn into a strong source of motivation and drive +- Think Optimistically: by thinking optimistically, one can create a positive and optimistic outlook on life. The + term used in the book is 'hoping for the best while preparing for the worst' +- Think in Terms of Effort: focus on the effort, not the outcome. When one does this, they are able to enjoy the + process regardless of the outcome + +* Build Routines and Habits + +Motivation is nice to have, but it is something that fluctuates based on emotion and circumstances. Habits on the +other hand, are something concrete and can be built and maintained. Research has shown that it takes 66 days to +build a habit, and requires self-discipline to get through that process. But once it is built, this habit will drive +you instead. The final thing mentioned in the book is the six sources of influence model by Joseph Grenny. These +factors are (1) personal motivation, (2) personal ability, (3) social motivation, (4) social ability, (5) structural +motivation, and (6) structural ability. + +* Summary + +This book is a great read, and taught me a lot about self-discipline and the science behind it. I would definitely +recommend it to anyone who wants to improve their self-discipline. It is, however, something that should be +reflected upon, not all the approaches and strategies are a one-size-fits-all, thus, take it with a grain of salt and +adapt it to your own circumstances. diff --git a/20250111213016-wp_prefront_cortex_blog.org b/20250111213016-wp_prefront_cortex_blog.org new file mode 100755 index 0000000..ac59553 --- /dev/null +++ b/20250111213016-wp_prefront_cortex_blog.org @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: b292f5c6-0c27-439c-8274-2150eb45e20d +:END: +#+title: wp-prefront-cortex-blorg +#+filetags: :zzq:blogs: + +[[file:~/master-folder/projects/web-port/md-files/prefrontal_cortex.md][file]] diff --git a/20250111213016-wp_prefront_cortex_blog.org~ b/20250111213016-wp_prefront_cortex_blog.org~ new file mode 100755 index 0000000..4592887 --- /dev/null +++ b/20250111213016-wp_prefront_cortex_blog.org~ @@ -0,0 +1,6 @@ +:PROPERTIES: +:ID: b292f5c6-0c27-439c-8274-2150eb45e20d +:END: +#+title: wp-prefront-cortex-blorg + +[[file:~/master-folder/projects/web-port/md-files/prefrontal_cortex.md][file]] diff --git a/20250120110833-afp.org b/20250120110833-afp.org new file mode 100755 index 0000000..85de8f2 --- /dev/null +++ b/20250120110833-afp.org @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: 556d10d1-1c74-4d9f-a398-39cb3bd5d935 +:END: +#+title: afp +#+filetags: :uni:index: + +[[id:6c272430-aff5-468b-90d3-5ff3a96152cf][afp_week1]] + +[[id:4bc71106-1d2b-4c71-836d-54b738fe5ff5][afp_week2]] + +[[id:1f395b8c-cf55-43eb-9430-dd9449f6b575][afp_week5]] diff --git a/20250120110833-afp.org~ b/20250120110833-afp.org~ new file mode 100755 index 0000000..d100641 --- /dev/null +++ b/20250120110833-afp.org~ @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: 556d10d1-1c74-4d9f-a398-39cb3bd5d935 +:END: +#+title: AFP +#+filetags: :uni:afp:index: + +[[id:6c272430-aff5-468b-90d3-5ff3a96152cf][afp_week1]] + +[[id:4bc71106-1d2b-4c71-836d-54b738fe5ff5][afp_week2]] + +[[id:1f395b8c-cf55-43eb-9430-dd9449f6b575][afp_week5]] diff --git a/20250120111047-afp_week1.org b/20250120111047-afp_week1.org new file mode 100755 index 0000000..ef72d68 --- /dev/null +++ b/20250120111047-afp_week1.org @@ -0,0 +1,10 @@ +:PROPERTIES: +:ID: 6c272430-aff5-468b-90d3-5ff3a96152cf +:END: +#+title: afp_week1 +#+filetags: :uni:index: + +* <2025-01-20 Mon> : [[id:f6c9e1a7-8465-4cef-9481-2b803d0c43d4][afp_lab_1]] +- Installing Agda + +* <2025-01-21 Tue> : [[id:3aef24fd-b220-4408-aa1e-c3538d661b62][afp_lec_1]] diff --git a/20250120111047-afp_week1.org~ b/20250120111047-afp_week1.org~ new file mode 100755 index 0000000..fcdc763 --- /dev/null +++ b/20250120111047-afp_week1.org~ @@ -0,0 +1,10 @@ +:PROPERTIES: +:ID: 6c272430-aff5-468b-90d3-5ff3a96152cf +:END: +#+title: afp_week1 +#+filetags: :uni: + +* <2025-01-20 Mon> : [[id:f6c9e1a7-8465-4cef-9481-2b803d0c43d4][afp_lab_1]] +- Installing Agda + +* <2025-01-21 Tue> : [[id:3aef24fd-b220-4408-aa1e-c3538d661b62][afp_lec_1]] diff --git a/20250120113936-afp-lab-1.org~ b/20250120113936-afp-lab-1.org~ new file mode 100755 index 0000000..2b7801b --- /dev/null +++ b/20250120113936-afp-lab-1.org~ @@ -0,0 +1,115 @@ +:PROPERTIES: +:ID: f6c9e1a7-8465-4cef-9481-2b803d0c43d4 +:END: +#+title: afp-lab-1 +#+filetags: :notes:uni:afp: +<2025-01-20 Mon> +* Installation of Agda: +** Step 1 +#+BEGIN_SRC eshell +sudo apt-get install zlib1g-dev libncurses5-dev +#+END_SRC + +then install ghc +- https://www.haskell.org/ghcup/ + +Now that you have cabal installed, use it to install Agda as a Haskell package: +#+BEGIN_SRC eshell +cabal update +cabal install Agda +#+END_SRC +** Step 2 +Most users will want to install the standard library. You can install this as any other Agda library (see Library Management). See the agda-stdlib project’s installation instructions for the steps to take to install the latest version. +https://github.com/agda/agda-stdlib +https://agda.readthedocs.io/en/latest/tools/package-system.html#package-system +* Exercises: +[[file:~/master-folder/Uni/ADVFUNC/afp-learning-2024-2025/files/LectureNotes/files/exercises/my-lab1.lagda.md][my lab1]] + + +```agda +data Bool : Type where + true false : Bool +``` + + +In Agda, the snippet `data Bool : Type where true false : Bool` is a definition of a simple data type named `Bool`. Let’s break down and explain all the components and words in this snippet: + +--- + +### 1. **`data`** +- **What it means:** This keyword introduces a new *data type* definition in Agda. +- **Purpose:** Defines a type that consists of one or more *constructors*, which are used to create values of the type. +- **In this case:** The `data` keyword is used to define the `Bool` type. + +--- + +### 2. **`Bool`** +- **What it is:** The name of the data type being defined. +- **Purpose:** Represents a type that has exactly two possible values: `true` and `false`. +- **In this case:** `Bool` is a common type used to represent truth values in logic (true or false). + +--- + +### 3. **`:` (colon)** +- **What it means:** Indicates a type declaration in Agda. +- **Purpose:** Separates the name of the data type (`Bool`) from its type (`Type`). +- **In this case:** `Bool : Type` declares that `Bool` is a type itself (i.e., a type of values). + +--- + +### 4. **`Type`** +- **What it is:** The universe of all types in Agda. +- **Purpose:** In Agda, types are first-class citizens, and `Type` represents the "type of types." For instance: + - `Bool : Type` means `Bool` is a type. + - If you define a type `ℕ : Type` for natural numbers, it also belongs to `Type`. +- **In this case:** `Bool` is defined as a type that belongs to this universe. + +--- + +### 5. **`where`** +- **What it means:** Introduces the constructors (values) of the type. +- **Purpose:** Lists the specific ways you can construct or create values of the newly defined type. +- **In this case:** `where` introduces the two constructors, `true` and `false`, which are the only possible values of the `Bool` type. + +--- + +### 6. **`true false`** +- **What they are:** The *constructors* of the `Bool` type. +- **Purpose:** Constructors are functions (or constants) that produce values of the type. Here: + - `true : Bool` means `true` is a value of type `Bool`. + - `false : Bool` means `false` is a value of type `Bool`. +- **In this case:** These two constructors define all possible values of `Bool`. + +--- + +### 7. **`Bool` after the `:`** +- **What it means:** Specifies the type of each constructor. +- **Purpose:** Ensures that each constructor produces a value of the correct type (`Bool` in this case). +- **In this case:** Both `true` and `false` are of type `Bool`. + +--- + +### Complete Meaning +The entire definition can be read as: +1. Define a new type called `Bool`. +2. `Bool` belongs to the universe of types (`Type`). +3. The `Bool` type has two constructors: + - `true` (a value of type `Bool`). + - `false` (a value of type `Bool`). + +--- + +### Example Usage in Agda +You can use `Bool` in various ways: +```agda +-- A function that negates a Bool +not : Bool → Bool +not true = false +not false = true + +-- A value of type Bool +myBool : Bool +myBool = true +``` + +This showcases how the `Bool` type and its constructors (`true` and `false`) can be used in programs. diff --git a/20250120113936-afp_lab_1.org b/20250120113936-afp_lab_1.org new file mode 100755 index 0000000..8621d02 --- /dev/null +++ b/20250120113936-afp_lab_1.org @@ -0,0 +1,115 @@ +:PROPERTIES: +:ID: f6c9e1a7-8465-4cef-9481-2b803d0c43d4 +:END: +#+title: afp_lab_1 +#+filetags: :notes:uni: +<2025-01-20 Mon> +* Installation of Agda: +** Step 1 +#+BEGIN_SRC eshell +sudo apt-get install zlib1g-dev libncurses5-dev +#+END_SRC + +then install ghc +- https://www.haskell.org/ghcup/ + +Now that you have cabal installed, use it to install Agda as a Haskell package: +#+BEGIN_SRC eshell +cabal update +cabal install Agda +#+END_SRC +** Step 2 +Most users will want to install the standard library. You can install this as any other Agda library (see Library Management). See the agda-stdlib project’s installation instructions for the steps to take to install the latest version. +https://github.com/agda/agda-stdlib +https://agda.readthedocs.io/en/latest/tools/package-system.html#package-system +* Exercises: +[[file:~/master-folder/Uni/ADVFUNC/afp-learning-2024-2025/files/LectureNotes/files/exercises/my-lab1.lagda.md][my lab1]] + + +```agda +data Bool : Type where + true false : Bool +``` + + +In Agda, the snippet `data Bool : Type where true false : Bool` is a definition of a simple data type named `Bool`. Let’s break down and explain all the components and words in this snippet: + +--- + +### 1. **`data`** +- **What it means:** This keyword introduces a new *data type* definition in Agda. +- **Purpose:** Defines a type that consists of one or more *constructors*, which are used to create values of the type. +- **In this case:** The `data` keyword is used to define the `Bool` type. + +--- + +### 2. **`Bool`** +- **What it is:** The name of the data type being defined. +- **Purpose:** Represents a type that has exactly two possible values: `true` and `false`. +- **In this case:** `Bool` is a common type used to represent truth values in logic (true or false). + +--- + +### 3. **`:` (colon)** +- **What it means:** Indicates a type declaration in Agda. +- **Purpose:** Separates the name of the data type (`Bool`) from its type (`Type`). +- **In this case:** `Bool : Type` declares that `Bool` is a type itself (i.e., a type of values). + +--- + +### 4. **`Type`** +- **What it is:** The universe of all types in Agda. +- **Purpose:** In Agda, types are first-class citizens, and `Type` represents the "type of types." For instance: + - `Bool : Type` means `Bool` is a type. + - If you define a type `ℕ : Type` for natural numbers, it also belongs to `Type`. +- **In this case:** `Bool` is defined as a type that belongs to this universe. + +--- + +### 5. **`where`** +- **What it means:** Introduces the constructors (values) of the type. +- **Purpose:** Lists the specific ways you can construct or create values of the newly defined type. +- **In this case:** `where` introduces the two constructors, `true` and `false`, which are the only possible values of the `Bool` type. + +--- + +### 6. **`true false`** +- **What they are:** The *constructors* of the `Bool` type. +- **Purpose:** Constructors are functions (or constants) that produce values of the type. Here: + - `true : Bool` means `true` is a value of type `Bool`. + - `false : Bool` means `false` is a value of type `Bool`. +- **In this case:** These two constructors define all possible values of `Bool`. + +--- + +### 7. **`Bool` after the `:`** +- **What it means:** Specifies the type of each constructor. +- **Purpose:** Ensures that each constructor produces a value of the correct type (`Bool` in this case). +- **In this case:** Both `true` and `false` are of type `Bool`. + +--- + +### Complete Meaning +The entire definition can be read as: +1. Define a new type called `Bool`. +2. `Bool` belongs to the universe of types (`Type`). +3. The `Bool` type has two constructors: + - `true` (a value of type `Bool`). + - `false` (a value of type `Bool`). + +--- + +### Example Usage in Agda +You can use `Bool` in various ways: +```agda +-- A function that negates a Bool +not : Bool → Bool +not true = false +not false = true + +-- A value of type Bool +myBool : Bool +myBool = true +``` + +This showcases how the `Bool` type and its constructors (`true` and `false`) can be used in programs. diff --git a/20250121110241-afp-lec-1.org~ b/20250121110241-afp-lec-1.org~ new file mode 100755 index 0000000..2447418 --- /dev/null +++ b/20250121110241-afp-lec-1.org~ @@ -0,0 +1,154 @@ +:PROPERTIES: +:ID: 3aef24fd-b220-4408-aa1e-c3538d661b62 +:END: +#+title: afp-lec-1 +#+filetags: :notes:uni:afp: +<2025-01-21 Tue> +[[file:~/master-folder/Uni/ADVFUNC/afp-learning-2024-2025/files/LectureNotes/files/introduction.lagda.md][Week 1 Handout]] +* Week 1 lec 1 +if you want to put a hole in the file (ie the { }1 ) then put a ? and load the file + +types are default called 'sets' in agda but we will call them types. + +data Bool : Type where + true false : Bool + +Here we create a type called Bool + +-- + +data Maybe (A : Type) : Type where + nothing : Maybe A + just : A → Maybe A + +Given the type A we produce another type +Then we have two constructors, we can actually call them whatever we want, the only rule is that it shouldnt have spaces in the middle. For example, instead of nothing we can call 'nothing' as 'Nothingljfsdsdj'. + +The below is known as coercion or the disjoint union +Considering Blah = Either ℕ Bool +left 0: Blah +right false: Blah + +-- + +data ℕ : Type where + zero : ℕ + suc : ℕ → ℕ + +-- 4 = suc (suc (suc (suc zero))) + +-- + +data List (A : Type) : Type where + [] : List A + _::_ : A → List A → List A + +Below is a function that maps a type to a type: +myList : Type -> Type +myList = List + +-- N -> Type ... this is called 'Dependant Type' which depends on elements of another type. +When it comes to types, its often the case where the language we use doesnt exactly define the type we want it to. For example in haskell, the binary tree, when we want to use the binary search tree its a little difficult. In agda we can define a precise type; including the binary search tree. In summary agda can write precise types. + +-- + +if_then_else_ : {A : Type} → Bool → A → A → A +if true then x else y = x +if false then x else y = y + +this above is known as mixfix operation, we use the _ to denote where the arguments of the function are going to be places + +-- + +_+_ : ℕ → ℕ → ℕ +zero + y = y +suc x + y = suc (x + y) + +here we can pattern match on any of x or y +in haskell, recursion can be done and there arent restrictions on it. in Agda we have structural recursion as there is a termination on recursion. Structural recursion is when you follow the structure of the definition, for example in suc x + y, we get suc (x + y), we keep removing the x from suc until we are left with 0. scrcpy + +-- + +_*_ : ℕ → ℕ → ℕ +zero * y = zero +suc x * y = x * y + y + +for suc x * y: +(1 + x) * y +y + x * y + +in infixr, the r means the brackets are explicitly on the right, if we use infixl then its on the left: +x + y + z +x + (y + z) : r +(x + y) + z : l + +-- research implicit arguements. + + +reverse : {A : Type} → List A → List A +reverse [] = [] +reverse (x :: xs) = reverse xs ++ [ x ] + +although this program works, its inefficient. + +rev-append : {A : Type} → List A → List A → List A +rev-append [] ys = ys +rev-append (x :: xs) ys = rev-append xs (x :: ys) + +rev : {A : Type} → List A → List A +rev xs = rev-append xs [] + +the revappend is a helper function. you can see theres no ++ (concatenation) involved. +* Week 1 lec 2 + +N-Induction : (P: N -> Type) + -> P 0 + -> ((k:N) -> Pk (P (suc k)) +choose k = 0 + +P0 : P0 +f0 p1 : P1 +f1 p2 : p2 + + -> (n:N) -> Pn + +This is proof by induction, + +ℕ-induction P p0 f 0 = P0 +ℕ-induction P p0 f(suc n) = goal +where + ℍ : Pn + ℍ = ℕ-induction P p0 f n + +ℕ-induction P p0 f 3 = + f3(f2(f1 p0)) +essentially this is a for loop. + +-- +indstep : (k:N) -> k≣k -> suc k ≣ suc k +indstep k e = e + +ℕ-refl n = ℕ-induction (λx -> x≣x) * (λke -> e) + +introduction and elimination rules + + +-- +List-induction : { x : Type } + -> (P : List X -> Type) + -> P [] + -> ((x:X)(xs:List X) -> Pxs -> P(x::xs)) + + -> (xs : List X ) -> P xs + +List-induction + + +* Keybindings: +- C-c C-l : to load the agda file +- SPC-w for the windows +- C-c C-c : case split (agda mode) (put x, or b or whatever the first one is, then use this - very useful). +- C-c C-SPC: give: tries to fill the hole +- C-shift - : undo +- C-c C-r : refine +- C-c C-, : show the context diff --git a/20250121110241-afp_lec_1.org b/20250121110241-afp_lec_1.org new file mode 100755 index 0000000..4ded04b --- /dev/null +++ b/20250121110241-afp_lec_1.org @@ -0,0 +1,154 @@ +:PROPERTIES: +:ID: 3aef24fd-b220-4408-aa1e-c3538d661b62 +:END: +#+title: afp_lec_1 +#+filetags: :notes:uni: +<2025-01-21 Tue> +[[file:~/master-folder/Uni/ADVFUNC/afp-learning-2024-2025/files/LectureNotes/files/introduction.lagda.md][Week 1 Handout]] +* Week 1 lec 1 +if you want to put a hole in the file (ie the { }1 ) then put a ? and load the file + +types are default called 'sets' in agda but we will call them types. + +data Bool : Type where + true false : Bool + +Here we create a type called Bool + +-- + +data Maybe (A : Type) : Type where + nothing : Maybe A + just : A → Maybe A + +Given the type A we produce another type +Then we have two constructors, we can actually call them whatever we want, the only rule is that it shouldnt have spaces in the middle. For example, instead of nothing we can call 'nothing' as 'Nothingljfsdsdj'. + +The below is known as coercion or the disjoint union +Considering Blah = Either ℕ Bool +left 0: Blah +right false: Blah + +-- + +data ℕ : Type where + zero : ℕ + suc : ℕ → ℕ + +-- 4 = suc (suc (suc (suc zero))) + +-- + +data List (A : Type) : Type where + [] : List A + _::_ : A → List A → List A + +Below is a function that maps a type to a type: +myList : Type -> Type +myList = List + +-- N -> Type ... this is called 'Dependant Type' which depends on elements of another type. +When it comes to types, its often the case where the language we use doesnt exactly define the type we want it to. For example in haskell, the binary tree, when we want to use the binary search tree its a little difficult. In agda we can define a precise type; including the binary search tree. In summary agda can write precise types. + +-- + +if_then_else_ : {A : Type} → Bool → A → A → A +if true then x else y = x +if false then x else y = y + +this above is known as mixfix operation, we use the _ to denote where the arguments of the function are going to be places + +-- + +_+_ : ℕ → ℕ → ℕ +zero + y = y +suc x + y = suc (x + y) + +here we can pattern match on any of x or y +in haskell, recursion can be done and there arent restrictions on it. in Agda we have structural recursion as there is a termination on recursion. Structural recursion is when you follow the structure of the definition, for example in suc x + y, we get suc (x + y), we keep removing the x from suc until we are left with 0. scrcpy + +-- + +_*_ : ℕ → ℕ → ℕ +zero * y = zero +suc x * y = x * y + y + +for suc x * y: +(1 + x) * y +y + x * y + +in infixr, the r means the brackets are explicitly on the right, if we use infixl then its on the left: +x + y + z +x + (y + z) : r +(x + y) + z : l + +-- research implicit arguements. + + +reverse : {A : Type} → List A → List A +reverse [] = [] +reverse (x :: xs) = reverse xs ++ [ x ] + +although this program works, its inefficient. + +rev-append : {A : Type} → List A → List A → List A +rev-append [] ys = ys +rev-append (x :: xs) ys = rev-append xs (x :: ys) + +rev : {A : Type} → List A → List A +rev xs = rev-append xs [] + +the revappend is a helper function. you can see theres no ++ (concatenation) involved. +* Week 1 lec 2 + +N-Induction : (P: N -> Type) + -> P 0 + -> ((k:N) -> Pk (P (suc k)) +choose k = 0 + +P0 : P0 +f0 p1 : P1 +f1 p2 : p2 + + -> (n:N) -> Pn + +This is proof by induction, + +ℕ-induction P p0 f 0 = P0 +ℕ-induction P p0 f(suc n) = goal +where + ℍ : Pn + ℍ = ℕ-induction P p0 f n + +ℕ-induction P p0 f 3 = + f3(f2(f1 p0)) +essentially this is a for loop. + +-- +indstep : (k:N) -> k≣k -> suc k ≣ suc k +indstep k e = e + +ℕ-refl n = ℕ-induction (λx -> x≣x) * (λke -> e) + +introduction and elimination rules + + +-- +List-induction : { x : Type } + -> (P : List X -> Type) + -> P [] + -> ((x:X)(xs:List X) -> Pxs -> P(x::xs)) + + -> (xs : List X ) -> P xs + +List-induction + + +* Keybindings: +- C-c C-l : to load the agda file +- SPC-w for the windows +- C-c C-c : case split (agda mode) (put x, or b or whatever the first one is, then use this - very useful). +- C-c C-SPC: give: tries to fill the hole +- C-shift - : undo +- C-c C-r : refine +- C-c C-, : show the context diff --git a/20250128110828-afp_week2.org b/20250128110828-afp_week2.org new file mode 100755 index 0000000..e7247ef --- /dev/null +++ b/20250128110828-afp_week2.org @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: 4bc71106-1d2b-4c71-836d-54b738fe5ff5 +:END: +#+title: afp_week2 +#+filetags: :uni:index: + +<2025-01-27 Mon> + +<2025-01-28 Tue> + +[[id:460f4a49-8ae4-444a-bf82-4e14ca7cad3f][afp_lec_2]] diff --git a/20250128110828-afp_week2.org~ b/20250128110828-afp_week2.org~ new file mode 100755 index 0000000..a44b277 --- /dev/null +++ b/20250128110828-afp_week2.org~ @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 4bc71106-1d2b-4c71-836d-54b738fe5ff5 +:END: +#+title: afp_week2 +#+filetags: :uni:afp: + +<2025-01-27 Mon> + +<2025-01-28 Tue> diff --git a/20250128111008-afp_lec_2.org b/20250128111008-afp_lec_2.org new file mode 100644 index 0000000..d825d9e --- /dev/null +++ b/20250128111008-afp_lec_2.org @@ -0,0 +1,43 @@ +:PROPERTIES: +:ID: 460f4a49-8ae4-444a-bf82-4e14ca7cad3f +:END: +#+title: afp_lec_2 +#+filetags: :uni:notes: + +- List are dependant, thats what makes it so special. + + +```agda +data _≡_ {X : Type} : X → X → Type where + refl : (x : X) → x ≡ x + +infix 0 _≡_ +``` +Here is the identity type. For every type X, im going to define two elements of X, and the only way to define this element the constructor of which is single. The type is like a proposition and the element is like the proof. By just having this rule we can do everything we wanna do, for example, proving that if x=y, y=x. +Definition equal : = +Type equality : ≡ + + + +we want to write propositions as types and proofs as programs. + +A proof is a convincing argument. How do you convince someone that something you believe is true is actually true, it ivolves reasoning. +* AND +To prove A and B we have to prove A, and also prove B. Proof by arguments; you have to argue/justify that A is true and that B is true. + +a : A +the little `a` is a justification of the the big `A`. little a is a way to prove that big A holds. + +So for this it would be: +a : A +b : B +and we need that both holds, imagine them as pairs: (a , b) +cartesian product -> (a , b) : A x B +the cartesian product is just a set of pairs. The below is a translation of conjunction to cartesian product in Agda. + +```agda + +data _ x _ (A B : Type) : Type where + _ , _ : A -> B -> A x B + +``` diff --git a/20250128111008-afp_lec_2.org~ b/20250128111008-afp_lec_2.org~ new file mode 100644 index 0000000..863135c --- /dev/null +++ b/20250128111008-afp_lec_2.org~ @@ -0,0 +1,43 @@ +:PROPERTIES: +:ID: 460f4a49-8ae4-444a-bf82-4e14ca7cad3f +:END: +#+title: afp-lec-2 +#+filetags: :uni:afp:notes: + +- List are dependant, thats what makes it so special. + + +```agda +data _≡_ {X : Type} : X → X → Type where + refl : (x : X) → x ≡ x + +infix 0 _≡_ +``` +Here is the identity type. For every type X, im going to define two elements of X, and the only way to define this element the constructor of which is single. The type is like a proposition and the element is like the proof. By just having this rule we can do everything we wanna do, for example, proving that if x=y, y=x. +Definition equal : = +Type equality : ≡ + + + +we want to write propositions as types and proofs as programs. + +A proof is a convincing argument. How do you convince someone that something you believe is true is actually true, it ivolves reasoning. +* AND +To prove A and B we have to prove A, and also prove B. Proof by arguments; you have to argue/justify that A is true and that B is true. + +a : A +the little `a` is a justification of the the big `A`. little a is a way to prove that big A holds. + +So for this it would be: +a : A +b : B +and we need that both holds, imagine them as pairs: (a , b) +cartesian product -> (a , b) : A x B +the cartesian product is just a set of pairs. The below is a translation of conjunction to cartesian product in Agda. + +```agda + +data _ x _ (A B : Type) : Type where + _ , _ : A -> B -> A x B + +``` diff --git a/20250213124335-i3_wm.org b/20250213124335-i3_wm.org new file mode 100644 index 0000000..1a2911e --- /dev/null +++ b/20250213124335-i3_wm.org @@ -0,0 +1,16 @@ +:PROPERTIES: +:ID: 9d5aae0f-4ae1-49a5-a047-9099baad0a06 +:END: +#+title: i3-wm +#+filetags: :guide: + +* Commands: +*Mod1 = Win Key* + +$mod+Enter = Open Terminal +$mod+s = Stacked layout +$mod+e = Default layout +$mod+d = dmenu + + +* Config file: diff --git a/20250213124335-i3_wm.org~ b/20250213124335-i3_wm.org~ new file mode 100644 index 0000000..f29028a --- /dev/null +++ b/20250213124335-i3_wm.org~ @@ -0,0 +1,16 @@ +:PROPERTIES: +:ID: 9d5aae0f-4ae1-49a5-a047-9099baad0a06 +:END: +#+title: i3-wm +#+filetags: :linux:guide: + +* Commands: +*Mod1 = Win Key* + +$mod+Enter = Open Terminal +$mod+s = Stacked layout +$mod+e = Default layout +$mod+d = dmenu + + +* Config file: diff --git a/20250214155617-wp_new_emacs_config_blorg.org b/20250214155617-wp_new_emacs_config_blorg.org new file mode 100644 index 0000000..83f614b --- /dev/null +++ b/20250214155617-wp_new_emacs_config_blorg.org @@ -0,0 +1,130 @@ +:PROPERTIES: +:ID: 1ee754f9-f30f-4976-850b-d18d01a834d2 +:END: +#+title: wp-new-emacs-config-blorg +#+filetags: :zzq:blogs: + +# Setting Up an Advanced Emacs Configuration for Productivity + +I recently spoke about what Emacs is, and how it is useful for productivity. I wanted to write this up again and dive more into the other files that were stored in the `/scripts` directory , as well as how to set it up. + +## Prerequisites + +Before we begin, ensure you have Emacs installed. You can install Emacs using the following commands based on your operating system: + +- **Ubuntu/Debian:** `sudo apt install emacs` +- **MacOS (Homebrew):** `brew install emacs` +- **Windows:** Use [MSYS2](https://www.msys2.org/) or install Emacs from [GNU Emacs](https://www.gnu.org/software/emacs/). + +Additionally, ensure that `git` is installed to clone repositories and manage configurations. + +## Download the Configuration Files + +First let's walk through how to set this up. + +Clone the repository or manually download the provided configuration files into your `~/.emacs.d/` directory: + +```sh +mkdir -p ~/.emacs.d/ +cd ~/.emacs.d/ +``` + +The following file should be copied to `~/.emacs.d/`: +- `init.el` + +And the following files should be copied into `~/.emacs.d/scripts`: +- `auto-comp.el` +- `custom-agenda.el` +- `displays.el` +- `keyboard.el` +- `shells.el` +- `window.el` + +If you are using `git`, you can clone your repository directly: + +```sh +git clone https://github.com/zainezq/dot-files/tree/main/emacs-config +``` +## Understanding the Configuration + +This configuration is modularised for easier maintenance. Each file handles a specific feature: + +### `init.el`: The Core Configuration + +The `init.el` file is the entry point of the configuration. It: +- Loads package management (MELPA, `use-package`) +- Imports additional modules (`displays`, `shells`, `auto-comp`, `window`, `keyboard`, `custom-agenda`) +- Configures UI elements such as themes, icons, and window behavior +- Sets up Org mode and language support +- Enables Evil mode for Vim-like keybindings + +### `auto-comp.el`: Auto-Completion Setup + +This file configures `company-mode` for autocompletion in Emacs. It: +- Loads `company-mode` and `company-box` for a better UI +- Sets the minimum prefix length and delay before suggestions appear +- Enables backend support for various modes + +### `keyboard.el`: Custom Keybindings + +This file sets up keybindings using the `general.el` package. Some useful shortcuts include: +- `SPC .` → Open file finder +- `SPC f c` → Open `init.el` for quick edits +- `SPC b b` → Switch buffers +- `SPC w 1` → Removes (not kills) all buffers except the current one +- `SPC t n` → Toggle NeoTree file explorer + +### `window.el`: Window Management + +Defines functions for moving buffers between splits using `windmove`. Functions include: +- `buf-move-up` → Swap buffers up +- `buf-move-down` → Swap buffers down +- `buf-move-left` → Swap buffers left +- `buf-move-right` → Swap buffers right + +### `shells.el`: Shell and Terminal Integration + +Configures: +- `vterm` as the primary terminal +- `eshell-toggle` for quick access to Eshell +- `vterm-toggle` for easy terminal toggling + +### `custom-agenda.el`: Org Mode Enhancements + +This file customises Org mode agendas. It: +- Configures custom agenda views +- Hides the Org agenda startup message +- Enables extra features such as displaying scheduled tasks + +### `displays.el`: UI Enhancements + +This file improves the visual experience in Emacs: +- Configures `dashboard.el` to show a custom startup screen, you may modify this to your liking, see: [Emacs Dashboard](https://github.com/emacs-dashboard/emacs-dashboard) +- Enables `neotree` for file navigation +- Hides unnecessary UI elements for a cleaner look + +## Installing Dependencies + +Open Emacs and run the following command to install missing packages: + +```sh +M-x package-refresh-contents +M-x package-install-selected-packages +``` + +Alternatively, restart Emacs, and `use-package` will automatically install any missing dependencies. + +If any issues arise, check `*Messages*` buffer (`M-x view-echo-area-messages`) or start Emacs with debugging mode enabled (`emacs --debug-init`). What I tend to do is whenever I encounter any errors, I run emacs in minimal mode: `emacs -Q`, this loads emacs without the init.el file (if I can't pinpoint the exact error). + +## Final Notes + +This configuration optimises Emacs for efficient navigation, organisation, and shell integration. +Everybodies configuration will differ based on their needs, so feel free to take and leave the parts as you wish! + +For additional customisation, refer to the official package documentation: +- [General.el (Keybindings)](https://github.com/noctuid/general.el) +- [Evil Mode (Vim keybindings)](https://github.com/emacs-evil/evil) +- [Org Mode](https://orgmode.org/) +- [Neotree (File navigation)](https://github.com/jaypei/emacs-neotree) + + diff --git a/20250214155617-wp_new_emacs_config_blorg.org~ b/20250214155617-wp_new_emacs_config_blorg.org~ new file mode 100644 index 0000000..d35f8b6 --- /dev/null +++ b/20250214155617-wp_new_emacs_config_blorg.org~ @@ -0,0 +1,129 @@ +:PROPERTIES: +:ID: 1ee754f9-f30f-4976-850b-d18d01a834d2 +:END: +#+title: wp-new-emacs-config-blorg + +# Setting Up an Advanced Emacs Configuration for Productivity + +I recently spoke about what Emacs is, and how it is useful for productivity. I wanted to write this up again and dive more into the other files that were stored in the `/scripts` directory , as well as how to set it up. + +## Prerequisites + +Before we begin, ensure you have Emacs installed. You can install Emacs using the following commands based on your operating system: + +- **Ubuntu/Debian:** `sudo apt install emacs` +- **MacOS (Homebrew):** `brew install emacs` +- **Windows:** Use [MSYS2](https://www.msys2.org/) or install Emacs from [GNU Emacs](https://www.gnu.org/software/emacs/). + +Additionally, ensure that `git` is installed to clone repositories and manage configurations. + +## Download the Configuration Files + +First let's walk through how to set this up. + +Clone the repository or manually download the provided configuration files into your `~/.emacs.d/` directory: + +```sh +mkdir -p ~/.emacs.d/ +cd ~/.emacs.d/ +``` + +The following file should be copied to `~/.emacs.d/`: +- `init.el` + +And the following files should be copied into `~/.emacs.d/scripts`: +- `auto-comp.el` +- `custom-agenda.el` +- `displays.el` +- `keyboard.el` +- `shells.el` +- `window.el` + +If you are using `git`, you can clone your repository directly: + +```sh +git clone https://github.com/zainezq/dot-files/tree/main/emacs-config +``` +## Understanding the Configuration + +This configuration is modularised for easier maintenance. Each file handles a specific feature: + +### `init.el`: The Core Configuration + +The `init.el` file is the entry point of the configuration. It: +- Loads package management (MELPA, `use-package`) +- Imports additional modules (`displays`, `shells`, `auto-comp`, `window`, `keyboard`, `custom-agenda`) +- Configures UI elements such as themes, icons, and window behavior +- Sets up Org mode and language support +- Enables Evil mode for Vim-like keybindings + +### `auto-comp.el`: Auto-Completion Setup + +This file configures `company-mode` for autocompletion in Emacs. It: +- Loads `company-mode` and `company-box` for a better UI +- Sets the minimum prefix length and delay before suggestions appear +- Enables backend support for various modes + +### `keyboard.el`: Custom Keybindings + +This file sets up keybindings using the `general.el` package. Some useful shortcuts include: +- `SPC .` → Open file finder +- `SPC f c` → Open `init.el` for quick edits +- `SPC b b` → Switch buffers +- `SPC w 1` → Removes (not kills) all buffers except the current one +- `SPC t n` → Toggle NeoTree file explorer + +### `window.el`: Window Management + +Defines functions for moving buffers between splits using `windmove`. Functions include: +- `buf-move-up` → Swap buffers up +- `buf-move-down` → Swap buffers down +- `buf-move-left` → Swap buffers left +- `buf-move-right` → Swap buffers right + +### `shells.el`: Shell and Terminal Integration + +Configures: +- `vterm` as the primary terminal +- `eshell-toggle` for quick access to Eshell +- `vterm-toggle` for easy terminal toggling + +### `custom-agenda.el`: Org Mode Enhancements + +This file customises Org mode agendas. It: +- Configures custom agenda views +- Hides the Org agenda startup message +- Enables extra features such as displaying scheduled tasks + +### `displays.el`: UI Enhancements + +This file improves the visual experience in Emacs: +- Configures `dashboard.el` to show a custom startup screen, you may modify this to your liking, see: [Emacs Dashboard](https://github.com/emacs-dashboard/emacs-dashboard) +- Enables `neotree` for file navigation +- Hides unnecessary UI elements for a cleaner look + +## Installing Dependencies + +Open Emacs and run the following command to install missing packages: + +```sh +M-x package-refresh-contents +M-x package-install-selected-packages +``` + +Alternatively, restart Emacs, and `use-package` will automatically install any missing dependencies. + +If any issues arise, check `*Messages*` buffer (`M-x view-echo-area-messages`) or start Emacs with debugging mode enabled (`emacs --debug-init`). What I tend to do is whenever I encounter any errors, I run emacs in minimal mode: `emacs -Q`, this loads emacs without the init.el file (if I can't pinpoint the exact error). + +## Final Notes + +This configuration optimises Emacs for efficient navigation, organisation, and shell integration. +Everybodies configuration will differ based on their needs, so feel free to take and leave the parts as you wish! + +For additional customisation, refer to the official package documentation: +- [General.el (Keybindings)](https://github.com/noctuid/general.el) +- [Evil Mode (Vim keybindings)](https://github.com/emacs-evil/evil) +- [Org Mode](https://orgmode.org/) +- [Neotree (File navigation)](https://github.com/jaypei/emacs-neotree) + + diff --git a/20250218110239-afp_week5.org b/20250218110239-afp_week5.org new file mode 100644 index 0000000..4c46dd2 --- /dev/null +++ b/20250218110239-afp_week5.org @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: 1f395b8c-cf55-43eb-9430-dd9449f6b575 +:END: +#+title: afp_week5 +#+filetags: :uni:index: + +[[id:ed4c372b-0314-4b6e-9119-742f69b5e434][afp_lec_5]] diff --git a/20250218110239-afp_week5.org~ b/20250218110239-afp_week5.org~ new file mode 100644 index 0000000..fb9ac42 --- /dev/null +++ b/20250218110239-afp_week5.org~ @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: 1f395b8c-cf55-43eb-9430-dd9449f6b575 +:END: +#+title: afp_week5 +#+filetags: :uni:afp: + +[[id:ed4c372b-0314-4b6e-9119-742f69b5e434][afp-lec-5]] diff --git a/20250218110346-af_wk5_lec1.org~ b/20250218110346-af_wk5_lec1.org~ new file mode 100644 index 0000000..960ecf6 --- /dev/null +++ b/20250218110346-af_wk5_lec1.org~ @@ -0,0 +1,8 @@ +:PROPERTIES: +:ID: ed4c372b-0314-4b6e-9119-742f69b5e434 +:END: +#+title: af_wk5_lec1 + +* +the first half of the lecture we went through the practice test solutions. +for the last question we got a hint, namely to redefine the leaf and node constructors of the Rose Trees. diff --git a/20250218110346-afp_lec_5.org b/20250218110346-afp_lec_5.org new file mode 100644 index 0000000..3b87490 --- /dev/null +++ b/20250218110346-afp_lec_5.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: ed4c372b-0314-4b6e-9119-742f69b5e434 +:END: +#+title: afp_lec_5 +#+filetags: :uni:notes: + +* +the first half of the lecture we went through the practice test solutions. +for the last question we got a hint, namely to redefine the leaf and node constructors of the Rose Trees. diff --git a/20250218110346-afp_lec_5.org~ b/20250218110346-afp_lec_5.org~ new file mode 100644 index 0000000..0ec4711 --- /dev/null +++ b/20250218110346-afp_lec_5.org~ @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: ed4c372b-0314-4b6e-9119-742f69b5e434 +:END: +#+title: afp-lec-5 +#+filetags: :uni:afp:notes: + +* +the first half of the lecture we went through the practice test solutions. +for the last question we got a hint, namely to redefine the leaf and node constructors of the Rose Trees. diff --git a/20250218174735-emacs_stuff_keybindings.org b/20250218174735-emacs_stuff_keybindings.org new file mode 100644 index 0000000..6510ae5 --- /dev/null +++ b/20250218174735-emacs_stuff_keybindings.org @@ -0,0 +1,18 @@ +:PROPERTIES: +:ID: 966175d4-3b58-4abc-9b41-08cbf328dd87 +:END: +#+title: emacs-stuff-keybindings +#+filetags: :emacs:guide: + +Keybindings I have come across: + +* Get help for a major mode: + +Type `C-h m` to get information for a major mode. + + +* TO indent a region n amount of spaces (where n is a number): `C-u n C-x Tab` + +* Projectile: +- `SPC-p p` - switch project +- `SPC-p f` - find project diff --git a/20250218174735-emacs_stuff_keybindings.org~ b/20250218174735-emacs_stuff_keybindings.org~ new file mode 100644 index 0000000..ed2171b --- /dev/null +++ b/20250218174735-emacs_stuff_keybindings.org~ @@ -0,0 +1,13 @@ +:PROPERTIES: +:ID: 966175d4-3b58-4abc-9b41-08cbf328dd87 +:END: +#+title: emacs-stuff-keybindings +#+filetags: :emacs:guide: + +Keybindings I have come across: + +* TO indent a region n amount of spaces (where n is a number): `C-u n C-x Tab` + +* Projectile: +- `SPC-p p` - switch project +- `SPC-p f` - find project diff --git a/20250226184629-wp_urge_surfing_blorg.org b/20250226184629-wp_urge_surfing_blorg.org new file mode 100644 index 0000000..6e87aec --- /dev/null +++ b/20250226184629-wp_urge_surfing_blorg.org @@ -0,0 +1,69 @@ +:PROPERTIES: +:ID: cfc4ce06-7862-49b7-9a4f-e515d690cd38 +:END: +#+title: wp-urge-surfing-blorg +#+filetags: :blogs:zzq: + +# Urge Surfing: Mastering the Art of Riding Your Impulses + +By Zaine Qayyum + +## Table of Contents + +1. [Introduction](#introduction) +2. [What is Urge Surfing?](#what-is-urge-surfing) +3. [How Urge Surfing Works](#how-urge-surfing-works) +4. [Conclusion](#conclusion) + +## Introduction + +I've spoken about the internal components of 'self-discipline' in another blog, but if we take a look at this whole self-improvement topic from another angle, we can see that the underlying reason for us not being able to 'stick to things' is due to us giving in to our urges. That may sound trivial, and we may connect the dots that if we control our impulses, we can do xyz. However, that form of thinking requires a bit of explanation. + +Psychologists have researched and found that opposing our urges is like making them stronger because we give it that 'attention' it wants (Wegner, 1994). In his Ironic Process Theory, Daniel Wegner demonstrated that trying to suppress thoughts such as resisting cravings or unwanted impulses paradoxically makes them more persistent (Wegner, Schneider, Carter, & White, 1987). Addiction research further emphasises this, where forcefully fighting cravings can intensify them rather than make them disappear. + +But what if, instead of giving in or fighting them, we learned to ride them like a wave? This is the foundation of urge surfing, a mindfulness based technique developed by Dr. Alan Marlatt, which teaches individuals to observe their cravings without reacting to them, allowing them to naturally peak and fade. + +## What is Urge Surfing? + +Urge surfing is a concept that originated in addiction therapy and mindfulness practices. Developed by psychologist **Dr. Alan Marlatt**, it was designed to help people struggling with addictive behaviors by teaching them to observe their cravings rather than acting on them. + +The fundamental aspect of the technique is based on the ideology that **urges are temporary** (so real), they rise, peak and then eventually fade away, which is where the term **surfing** intuitively comes from. + +## How Urge Surfing Works + +Urge surfing relies on mindfulness, where we recognise the urge, observe it, then let it fade away. + +The process can be broken down into three main steps: + +### 1. **Recognising the Urge** +The first step is to *identify the urge* as it arises. This means paying close attention to bodily sensations, thoughts, and emotions that signal a craving. For example: +- A sudden tension in the stomach when craving sweets. +- Restlessness and an urge to check social media. +- A racing heart and a compulsion to lash out in anger. + +Acknowledging the urge early gives you the power to observe it rather than be consumed by it (kind of wanted to link this to "The Observer and the Observed"). + +### 2. **Riding the Wave** +Once you recognise the urge, the next step is to **observe it without reacting**. Imagine the urge as a wave in the ocean. rather than fighting it, you ride it by: +- *Breathing deeply*: In other words, focussing on slow deep breaths to achor yourself in the present moment +- *Noticing sensations*: Where do you feel the urge? Is it in your chest, hands, or stomach? +- *Labeling the urge*: Mentally note, "This is just a craving," or "This is just an impulse." This helps you distance yourself from it +- *Practicing non-judgment*: Don't label the urge as good or bad. Just observe it as it rises and falls + +### 3. **Letting It Fade Away** +With time, urges *naturally subside*. Like waves, they reach a peak and then fade away. The trick behind this is accepting that they come and go, and this gives you a much better control over your impulses. + +## The Science Behind Urge Surfing +Now you might be thinking "Hey you just spouted a bunch of things but where is the scientific correlation???". Let's take a look at the science behind it: + +- *The 90-Second Rule*: Neuroscientist **Dr. Jill Bolte Taylor** suggests that most emotional reactions last about 90 seconds. If we can *sit with an urge* for that duration, it often begins to dissipate. +- *Neuroplasticity*: Every time we resist an impulse instead of acting on it, we *weaken the neural pathways* associated with that habit. Over time, the urges become less intense. +- *The Prefrontal Cortex*: Self-control is governed by the prefrontal cortex, the rational part of our brain. Practicing urge surfing strengthens this area, which improves discipline. + +![Urge Surfing Diagram](./assets/urge-surfing.png) + +*Source: [Link](https://www.thenourishedpath.com/blog/eating-mindfully-urge-surfing)* + +## Conclusion + +Urge surfing is truly a powerful technique when mastered, not only does it allow you to control your urges without giving in, it also helps you to become more self-disciplined. If you are interested in learning more about this, I would recommend reading the book "The Science of Self-Discipline" by Peter Hollins. diff --git a/20250226184629-wp_urge_surfing_blorg.org~ b/20250226184629-wp_urge_surfing_blorg.org~ new file mode 100644 index 0000000..4ad70ea --- /dev/null +++ b/20250226184629-wp_urge_surfing_blorg.org~ @@ -0,0 +1,68 @@ +:PROPERTIES: +:ID: cfc4ce06-7862-49b7-9a4f-e515d690cd38 +:END: +#+title: wp-urge-surfing-blorg + +# Urge Surfing: Mastering the Art of Riding Your Impulses + +By Zaine Qayyum + +## Table of Contents + +1. [Introduction](#introduction) +2. [What is Urge Surfing?](#what-is-urge-surfing) +3. [How Urge Surfing Works](#how-urge-surfing-works) +4. [Conclusion](#conclusion) + +## Introduction + +I've spoken about the internal components of 'self-discipline' in another blog, but if we take a look at this whole self-improvement topic from another angle, we can see that the underlying reason for us not being able to 'stick to things' is due to us giving in to our urges. That may sound trivial, and we may connect the dots that if we control our impulses, we can do xyz. However, that form of thinking requires a bit of explanation. + +Psychologists have researched and found that opposing our urges is like making them stronger because we give it that 'attention' it wants (Wegner, 1994). In his Ironic Process Theory, Daniel Wegner demonstrated that trying to suppress thoughts such as resisting cravings or unwanted impulses paradoxically makes them more persistent (Wegner, Schneider, Carter, & White, 1987). Addiction research further emphasises this, where forcefully fighting cravings can intensify them rather than make them disappear. + +But what if, instead of giving in or fighting them, we learned to ride them like a wave? This is the foundation of urge surfing, a mindfulness based technique developed by Dr. Alan Marlatt, which teaches individuals to observe their cravings without reacting to them, allowing them to naturally peak and fade. + +## What is Urge Surfing? + +Urge surfing is a concept that originated in addiction therapy and mindfulness practices. Developed by psychologist **Dr. Alan Marlatt**, it was designed to help people struggling with addictive behaviors by teaching them to observe their cravings rather than acting on them. + +The fundamental aspect of the technique is based on the ideology that **urges are temporary** (so real), they rise, peak and then eventually fade away, which is where the term **surfing** intuitively comes from. + +## How Urge Surfing Works + +Urge surfing relies on mindfulness, where we recognise the urge, observe it, then let it fade away. + +The process can be broken down into three main steps: + +### 1. **Recognising the Urge** +The first step is to *identify the urge* as it arises. This means paying close attention to bodily sensations, thoughts, and emotions that signal a craving. For example: +- A sudden tension in the stomach when craving sweets. +- Restlessness and an urge to check social media. +- A racing heart and a compulsion to lash out in anger. + +Acknowledging the urge early gives you the power to observe it rather than be consumed by it (kind of wanted to link this to "The Observer and the Observed"). + +### 2. **Riding the Wave** +Once you recognise the urge, the next step is to **observe it without reacting**. Imagine the urge as a wave in the ocean. rather than fighting it, you ride it by: +- *Breathing deeply*: In other words, focussing on slow deep breaths to achor yourself in the present moment +- *Noticing sensations*: Where do you feel the urge? Is it in your chest, hands, or stomach? +- *Labeling the urge*: Mentally note, "This is just a craving," or "This is just an impulse." This helps you distance yourself from it +- *Practicing non-judgment*: Don't label the urge as good or bad. Just observe it as it rises and falls + +### 3. **Letting It Fade Away** +With time, urges *naturally subside*. Like waves, they reach a peak and then fade away. The trick behind this is accepting that they come and go, and this gives you a much better control over your impulses. + +## The Science Behind Urge Surfing +Now you might be thinking "Hey you just spouted a bunch of things but where is the scientific correlation???". Let's take a look at the science behind it: + +- *The 90-Second Rule*: Neuroscientist **Dr. Jill Bolte Taylor** suggests that most emotional reactions last about 90 seconds. If we can *sit with an urge* for that duration, it often begins to dissipate. +- *Neuroplasticity*: Every time we resist an impulse instead of acting on it, we *weaken the neural pathways* associated with that habit. Over time, the urges become less intense. +- *The Prefrontal Cortex*: Self-control is governed by the prefrontal cortex, the rational part of our brain. Practicing urge surfing strengthens this area, which improves discipline. + +![Urge Surfing Diagram](./assets/urge-surfing.png) + +*Source: [Link](https://www.thenourishedpath.com/blog/eating-mindfully-urge-surfing)* + +## Conclusion + +Urge surfing is truly a powerful technique when mastered, not only does it allow you to control your urges without giving in, it also helps you to become more self-disciplined. If you are interested in learning more about this, I would recommend reading the book "The Science of Self-Discipline" by Peter Hollins. diff --git a/20250314223811-wp_growth_mindset.org b/20250314223811-wp_growth_mindset.org new file mode 100644 index 0000000..65fbff4 --- /dev/null +++ b/20250314223811-wp_growth_mindset.org @@ -0,0 +1,86 @@ +:PROPERTIES: +:ID: CD093B85-BF68-4EAB-AABE-733C7BFC99DE +:END: +#+title: wp-growth-mindset +#+filetags: :blogs:zzq: + +# Building a Growth Mindset + +By Zaine Qayyum + +--- + +This topic is something that I've been wanting to talk about for a while, and the reason is because of how important it is as human beings to have this **growth mindset**. You might ask "why? what is the need when I can just have a fixed mindset?". The answer is simple: having a growth mindset is essential for personal and professional success. This is what I wanted to talk about in this blog, and I hope you find it useful! + +## Table of Contents + +1. [What Is a Growth Mindset?](#what-is-a-growth-mindset) +2. [Why Does a Growth Mindset Matter?](#why-does-a-growth-mindset-matter) +3. [How to Develop a Growth Mindset](#how-to-develop-a-growth-mindset) +4. [Final Thoughts](#final-thoughts). + +## What Is a Growth Mindset? + +The term *growth mindset* was introduced by psychologist **Dr. Carol Dweck** in her research on motivation and learning. It refers to the belief that our abilities, intelligence, and talents can be developed through **effort, learning, and persistence**. Take for example the muscles in our body, we develop them through repeated "reps" and consistent effort. The same applies to our intelligence, talents, and abilities; we can develop them through effort, learning, and persistence. + +This contrasts with a **fixed mindset**, where people believe their intelligence and talents are static traits, they either "have it" or they don’t. + +### Growth Mindset vs. Fixed Mindset + +| Growth Mindset | Fixed Mindset | +|---------------|--------------| +| Challenges are opportunities to grow | Challenges are threats to avoid | +| Failure is a stepping stone for learning | Failure defines intelligence and worth | +| Effort is the path to mastery | If you have to try, you're not naturally talented | +| Constructive criticism is valuable | Criticism is a personal attack | +| Inspired by others' success | Feels threatened by others' success | + +## Why Does a Growth Mindset Matter? +The question now might arise, "why does a growth mindset matter?" +Having a growth mindset is **not just motivational jargon,** but it has real benefits, here are some of them: + +- **Increases resilience:** People with a growth mindset are more likely to persist in the face of challenges, which ultimately allows you to grow in multiple ways. +- **Encourages continuous learning:** Lifelong learning is something so valued and desired (subject for another blog?), and a growth mindset goes hand in hand with it. +- **Boosts performance:** Research shows that students and professionals with a growth mindset perform better over time. This "performance" can be related to arbitrary things like academic success, job performance, or personal growth. +- **Improves relationships:** It helps people handle feedback better and build stronger connections with others. + +## How to Develop a Growth Mindset + +### 1. **Reframe Failure as Learning** +Instead of viewing failure as proof of inadequacy, see it as feedback. Ask yourself: +- *What can I learn from this?* +- *How can I approach this differently next time?* + +The questions I always ask myself are "What did I do that went well?" and "What can I do differently next time?" + +### 2. **Challenges should be embraced** +A common trap of a fixed mindset is avoiding challenges to protect your self-esteem. Instead: +- Take on **new projects** that push your abilities. +- Step outside your **comfort zone** regularly. +- Remind yourself: *Every expert was once a beginner*. + +### 3. **Use "Yet" to Change Your Self Talk** +Pay attention to your inner dialogue (yes we all have one, even if we don't realise it). If you catch yourself saying: +> *"I'm not good at this."* + +Reframe it to: +> *"I'm not good at this **yet**."* + +This small change can shift your perspective from **impossibility to potential**. + +### 4. **Value Effort Over Talent** +Society often glorifies natural talent, but effort is what leads to mastery. Instead of aiming to be "the best," focus on: +- Developing **discipline and consistency**. +- Tracking your **progress** rather than comparing yourself to others. +- Celebrating small wins along the way. + +## Final Thoughts + +A **growth mindset** isn’t something you "get" overnight, it takes a while to cultivate. It’s a daily practice. It requires self awareness, patience, and a willingness to embrace discomfort. But once achieved, it can take you to unimaginable heights. + +I honestly feel as though the best thing that worked for me was shifting my mindset, being positive about the situations I am in and learning to embrace the now. + +I hope this inspires you even in the slightest :) + +--- + diff --git a/20250314223811-wp_growth_mindset.org~ b/20250314223811-wp_growth_mindset.org~ new file mode 100644 index 0000000..f751fbd --- /dev/null +++ b/20250314223811-wp_growth_mindset.org~ @@ -0,0 +1,85 @@ +:PROPERTIES: +:ID: CD093B85-BF68-4EAB-AABE-733C7BFC99DE +:END: +#+title: wp-growth-mindset + +# Building a Growth Mindset + +By Zaine Qayyum + +--- + +This topic is something that I've been wanting to talk about for a while, and the reason is because of how important it is as human beings to have this **growth mindset**. You might ask "why? what is the need when I can just have a fixed mindset?". The answer is simple: having a growth mindset is essential for personal and professional success. This is what I wanted to talk about in this blog, and I hope you find it useful! + +## Table of Contents + +1. [What Is a Growth Mindset?](#what-is-a-growth-mindset) +2. [Why Does a Growth Mindset Matter?](#why-does-a-growth-mindset-matter) +3. [How to Develop a Growth Mindset](#how-to-develop-a-growth-mindset) +4. [Final Thoughts](#final-thoughts). + +## What Is a Growth Mindset? + +The term *growth mindset* was introduced by psychologist **Dr. Carol Dweck** in her research on motivation and learning. It refers to the belief that our abilities, intelligence, and talents can be developed through **effort, learning, and persistence**. Take for example the muscles in our body, we develop them through repeated "reps" and consistent effort. The same applies to our intelligence, talents, and abilities; we can develop them through effort, learning, and persistence. + +This contrasts with a **fixed mindset**, where people believe their intelligence and talents are static traits, they either "have it" or they don’t. + +### Growth Mindset vs. Fixed Mindset + +| Growth Mindset | Fixed Mindset | +|---------------|--------------| +| Challenges are opportunities to grow | Challenges are threats to avoid | +| Failure is a stepping stone for learning | Failure defines intelligence and worth | +| Effort is the path to mastery | If you have to try, you're not naturally talented | +| Constructive criticism is valuable | Criticism is a personal attack | +| Inspired by others' success | Feels threatened by others' success | + +## Why Does a Growth Mindset Matter? +The question now might arise, "why does a growth mindset matter?" +Having a growth mindset is **not just motivational jargon,** but it has real benefits, here are some of them: + +- **Increases resilience:** People with a growth mindset are more likely to persist in the face of challenges, which ultimately allows you to grow in multiple ways. +- **Encourages continuous learning:** Lifelong learning is something so valued and desired (subject for another blog?), and a growth mindset goes hand in hand with it. +- **Boosts performance:** Research shows that students and professionals with a growth mindset perform better over time. This "performance" can be related to arbitrary things like academic success, job performance, or personal growth. +- **Improves relationships:** It helps people handle feedback better and build stronger connections with others. + +## How to Develop a Growth Mindset + +### 1. **Reframe Failure as Learning** +Instead of viewing failure as proof of inadequacy, see it as feedback. Ask yourself: +- *What can I learn from this?* +- *How can I approach this differently next time?* + +The questions I always ask myself are "What did I do that went well?" and "What can I do differently next time?" + +### 2. **Challenges should be embraced** +A common trap of a fixed mindset is avoiding challenges to protect your self-esteem. Instead: +- Take on **new projects** that push your abilities. +- Step outside your **comfort zone** regularly. +- Remind yourself: *Every expert was once a beginner*. + +### 3. **Use "Yet" to Change Your Self Talk** +Pay attention to your inner dialogue (yes we all have one, even if we don't realise it). If you catch yourself saying: +> *"I'm not good at this."* + +Reframe it to: +> *"I'm not good at this **yet**."* + +This small change can shift your perspective from **impossibility to potential**. + +### 4. **Value Effort Over Talent** +Society often glorifies natural talent, but effort is what leads to mastery. Instead of aiming to be "the best," focus on: +- Developing **discipline and consistency**. +- Tracking your **progress** rather than comparing yourself to others. +- Celebrating small wins along the way. + +## Final Thoughts + +A **growth mindset** isn’t something you "get" overnight, it takes a while to cultivate. It’s a daily practice. It requires self awareness, patience, and a willingness to embrace discomfort. But once achieved, it can take you to unimaginable heights. + +I honestly feel as though the best thing that worked for me was shifting my mindset, being positive about the situations I am in and learning to embrace the now. + +I hope this inspires you even in the slightest :) + +--- + diff --git a/20250314230952-wp_emotional_intelligence.org b/20250314230952-wp_emotional_intelligence.org new file mode 100644 index 0000000..2d93aaf --- /dev/null +++ b/20250314230952-wp_emotional_intelligence.org @@ -0,0 +1,95 @@ +:PROPERTIES: +:ID: D02B89DC-84D0-4211-A902-B9399F4179CA +:END: +#+title: wp-emotional-intelligence +#+filetags: :blogs:zzq: + +# How to Build Emotional Intelligence (EQ) for Better Relationships + +Someone asked me a while ago "bro, do you think I have emotional intelligence?", and after having that conversation, I thought to myself "what exactly does *mean* to have emotional intelligence? Emotional Intelligence (EQ) is the ability to recognise, understand, and manage your own emotions, as well as the emotions of others. I wanted to write out this post so that this can be better understood and applied to our daily lives. + +--- + +## What is Emotional Intelligence (EQ)? + +Emotional Intelligence is often broken down into five key components: + +1. **Self-Awareness**: Recognising and understanding your own emotions. +2. **Self-Regulation**: Managing and controlling your emotional reactions. +3. **Motivation**: Harnessing emotions to pursue goals with energy and persistence. +4. **Empathy**: Understanding and sharing the feelings of others. +5. **Social Skills**: Building and maintaining healthy relationships through effective communication and conflict resolution. + +Knowledge is of little use if not applied. These five components, one can say, are the building blocks for EQ. + +--- + +## Why EQ Matters in Relationships + +Relationships depend on emotional connection. Whether it’s with a partner, family member, friend, or colleague, EQ helps you: + +- Communicate more effectively. +- Resolve conflicts constructively. +- Build trust and intimacy. +- Understand and meet the emotional needs of others. + +Without emotional intelligence, you may not be able to *understand* the emotions of others, which can ultimately lead to conflicts. + +--- + +## How to Build Emotional Intelligence for Better Relationships + +Based on the 5 components of EQ, here are practical steps to develop your EQ and strengthen your relationships: + +### **Self-Awareness** + - **Reflect on Your Emotions**: Take time each day to identify and label your emotions. Ask yourself, “What am I feeling right now, and why?” + - **Journal**: Writing about your emotions can help you process them and identify patterns in your reactions. + - **Seek Feedback**: Ask friends or family members how they perceive your emotional responses. This can provide valuable insights into blind spots. + +### **Self-Regulation** + - **Pause Before Reacting**: When you feel a strong emotion, take a deep breath and give yourself a moment to respond thoughtfully rather than reacting impulsively. + - **Practice Stress Management**: Techniques like meditation, exercise, or deep breathing can help you stay calm in emotionally charged situations. + - **Set Boundaries**: Learn to say no and manage your emotional energy to avoid depletion. + +### **Empathy** + - **Listen Actively**: Pay full attention when someone is speaking. Focus on their words, tone, and body language without interrupting or planning your response. There is a huge difference between active listening and passive listening. + - **Put Yourself in Their Shoes**: Try to understand the other person’s perspective, even if you don’t agree with it. + - **Validate Their Feelings**: Acknowledge their emotions by saying things like, “I understand why you’d feel that way.” + +### **Social Skills** + - **Communicate Clearly**: Use “I” statements to express your feelings without blaming others (e.g., “I feel upset when…”). + - **Practice Conflict Resolution**: Approach disagreements with a problem solving mindset rather than a confrontational one. Remember its you and them versus the problem, not each other! + - **Show Appreciation**: Regularly express gratitude and appreciation for the people in your life. + +### **Motivation** + - **Set Personal Goals**: Identify what you want to achieve in your relationships and take steps to work toward those goals. + - **Stay Positive**: Focus on the good in your relationships and maintain a hopeful outlook, even during challenging times. + +--- + +## Real-Life Examples of EQ in Action + +There are many practical examples of EQ in action in our daily lives. Take work as an example, if you notice your colleague a little stressed, offer them support and ask if they need help! Not only will they feel grateful that they're being seen, you'll also strengthen your professional relationship with said colleague. Another one is in a platonic relationship, when a friend shares a problem, listen without judgement and offer empathy. + +--- + +## The Long-Term Benefits of High EQ + +Building emotional intelligence is a lifelong journey, but the rewards are immense. Over time, you’ll notice: + +- Stronger, more meaningful relationships. +- Improved communication. +- Greater resilience in the face of challenges. +- A deeper understanding of yourself and others. +- Being able to actively listen to others. + +--- + +## Final Thoughts + +This whole thought and discussion stemmed from that single question. I find myself becoming more intrigued in the intricacies of relationships and human interaction. EQ is one of those components that make up a considerable portion of how we interact with others, without which relationships would become stale. Thank you for reading :) + + +--- + +*“Emotional intelligence is the key to both personal and professional success.” – Daniel Goleman* diff --git a/20250314230952-wp_emotional_intelligence.org~ b/20250314230952-wp_emotional_intelligence.org~ new file mode 100644 index 0000000..6e985f0 --- /dev/null +++ b/20250314230952-wp_emotional_intelligence.org~ @@ -0,0 +1,94 @@ +:PROPERTIES: +:ID: D02B89DC-84D0-4211-A902-B9399F4179CA +:END: +#+title: wp-emotional-intelligence + +# How to Build Emotional Intelligence (EQ) for Better Relationships + +Someone asked me a while ago "bro, do you think I have emotional intelligence?", and after having that conversation, I thought to myself "what exactly does *mean* to have emotional intelligence? Emotional Intelligence (EQ) is the ability to recognise, understand, and manage your own emotions, as well as the emotions of others. I wanted to write out this post so that this can be better understood and applied to our daily lives. + +--- + +## What is Emotional Intelligence (EQ)? + +Emotional Intelligence is often broken down into five key components: + +1. **Self-Awareness**: Recognising and understanding your own emotions. +2. **Self-Regulation**: Managing and controlling your emotional reactions. +3. **Motivation**: Harnessing emotions to pursue goals with energy and persistence. +4. **Empathy**: Understanding and sharing the feelings of others. +5. **Social Skills**: Building and maintaining healthy relationships through effective communication and conflict resolution. + +Knowledge is of little use if not applied. These five components, one can say, are the building blocks for EQ. + +--- + +## Why EQ Matters in Relationships + +Relationships depend on emotional connection. Whether it’s with a partner, family member, friend, or colleague, EQ helps you: + +- Communicate more effectively. +- Resolve conflicts constructively. +- Build trust and intimacy. +- Understand and meet the emotional needs of others. + +Without emotional intelligence, you may not be able to *understand* the emotions of others, which can ultimately lead to conflicts. + +--- + +## How to Build Emotional Intelligence for Better Relationships + +Based on the 5 components of EQ, here are practical steps to develop your EQ and strengthen your relationships: + +### **Self-Awareness** + - **Reflect on Your Emotions**: Take time each day to identify and label your emotions. Ask yourself, “What am I feeling right now, and why?” + - **Journal**: Writing about your emotions can help you process them and identify patterns in your reactions. + - **Seek Feedback**: Ask friends or family members how they perceive your emotional responses. This can provide valuable insights into blind spots. + +### **Self-Regulation** + - **Pause Before Reacting**: When you feel a strong emotion, take a deep breath and give yourself a moment to respond thoughtfully rather than reacting impulsively. + - **Practice Stress Management**: Techniques like meditation, exercise, or deep breathing can help you stay calm in emotionally charged situations. + - **Set Boundaries**: Learn to say no and manage your emotional energy to avoid depletion. + +### **Empathy** + - **Listen Actively**: Pay full attention when someone is speaking. Focus on their words, tone, and body language without interrupting or planning your response. There is a huge difference between active listening and passive listening. + - **Put Yourself in Their Shoes**: Try to understand the other person’s perspective, even if you don’t agree with it. + - **Validate Their Feelings**: Acknowledge their emotions by saying things like, “I understand why you’d feel that way.” + +### **Social Skills** + - **Communicate Clearly**: Use “I” statements to express your feelings without blaming others (e.g., “I feel upset when…”). + - **Practice Conflict Resolution**: Approach disagreements with a problem solving mindset rather than a confrontational one. Remember its you and them versus the problem, not each other! + - **Show Appreciation**: Regularly express gratitude and appreciation for the people in your life. + +### **Motivation** + - **Set Personal Goals**: Identify what you want to achieve in your relationships and take steps to work toward those goals. + - **Stay Positive**: Focus on the good in your relationships and maintain a hopeful outlook, even during challenging times. + +--- + +## Real-Life Examples of EQ in Action + +There are many practical examples of EQ in action in our daily lives. Take work as an example, if you notice your colleague a little stressed, offer them support and ask if they need help! Not only will they feel grateful that they're being seen, you'll also strengthen your professional relationship with said colleague. Another one is in a platonic relationship, when a friend shares a problem, listen without judgement and offer empathy. + +--- + +## The Long-Term Benefits of High EQ + +Building emotional intelligence is a lifelong journey, but the rewards are immense. Over time, you’ll notice: + +- Stronger, more meaningful relationships. +- Improved communication. +- Greater resilience in the face of challenges. +- A deeper understanding of yourself and others. +- Being able to actively listen to others. + +--- + +## Final Thoughts + +This whole thought and discussion stemmed from that single question. I find myself becoming more intrigued in the intricacies of relationships and human interaction. EQ is one of those components that make up a considerable portion of how we interact with others, without which relationships would become stale. Thank you for reading :) + + +--- + +*“Emotional intelligence is the key to both personal and professional success.” – Daniel Goleman* diff --git a/20250324041724-wp_week_12_reflections.org b/20250324041724-wp_week_12_reflections.org new file mode 100644 index 0000000..0b8fc6e --- /dev/null +++ b/20250324041724-wp_week_12_reflections.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 8CD2F4C4-22C2-4ECC-8F5F-C4779F8AC0F1 +:END: +#+title: wp-week-12-reflection +#+filetags: :blogs:zzq: + +# Week 12 reflections + +12 out of the 52 weeks are now completed (following the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601)), and I guess this blog post will be a little different from the usual *information-centric* posts. 12 weeks having passed from this year means there's only 9 months left of 2025, and i've come to realise that time is moving *quick*. The question then arose, "how can I maximise the time that I have?", the answer to which isn't as simple as one may think. Albeit this, let's take a look at one particularly useful equation that may serve as a guide to modelling the value of time: diff --git a/20250324041724-wp_week_12_reflections.org~ b/20250324041724-wp_week_12_reflections.org~ new file mode 100644 index 0000000..6b3dd75 --- /dev/null +++ b/20250324041724-wp_week_12_reflections.org~ @@ -0,0 +1,8 @@ +:PROPERTIES: +:ID: 8CD2F4C4-22C2-4ECC-8F5F-C4779F8AC0F1 +:END: +#+title: wp-week-12-reflection + +# Week 12 reflections + +12 out of the 52 weeks are now completed (following the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601)), and I guess this blog post will be a little different from the usual *information-centric* posts. 12 weeks having passed from this year means there's only 9 months left of 2025, and i've come to realise that time is moving *quick*. The question then arose, "how can I maximise the time that I have?", the answer to which isn't as simple as one may think. Albeit this, let's take a look at one particularly useful equation that may serve as a guide to modelling the value of time: diff --git a/20250326002128-emacs_stuff_elisp.org b/20250326002128-emacs_stuff_elisp.org new file mode 100644 index 0000000..0c6bfed --- /dev/null +++ b/20250326002128-emacs_stuff_elisp.org @@ -0,0 +1,82 @@ +:PROPERTIES: +:ID: 7e79e4c5-383d-450f-882c-33d4f87ba1b5 +:END: +#+title: emacs-stuff-elisp +#+filetags: :emacs:elisp:guide: + +-- use ` + +** DT + - What is decision tree: a tree structure that split the data depending on different values. + - Each node is a test on the attribute. + - Each branch represents the outcome. + +** NB + - What is Naive Bayes? Classifier based on the conditional probability given by the Bayes theorem. + - Calculating the probability of each class, and classify the given features into the one with higher probability. + +** LR + - What is logistic regression: a linear model for classification + - Fitting the logistic growth and the sigmoid midpoint + - Output a probability, but can use a cutoff point to decide class. + +** Results: +Choose the top 20/50 words when theyre used as a feature diff --git a/20250329114848-ise_week_1.org~ b/20250329114848-ise_week_1.org~ new file mode 100644 index 0000000..a18fa83 --- /dev/null +++ b/20250329114848-ise_week_1.org~ @@ -0,0 +1,56 @@ +:PROPERTIES: +:ID: 06b2a012-4e8a-4a8a-9494-de7ed9fbe1d3 +:END: +#+title: ise-week-1 +#+filetags: :uni:ise:notes: + + +* Bug report classification + +Perform bug report classification with AI following the steps +below: + + - Text filtering + - Stemming + - Indexing + - Train machine learning models, i.e., Decision Tree, Naive Bayes, and Logistic + Regression + - Prediction (after data pre-processing) + +** Text filtering: + - Punctuation removal + - Specific transformations occur: + the myUser has no meaning, its just a word. You need to split it into two meaningful words. + - Stop words should not be removed, as it changes the whole meaning of a bug report. + - Unlike other NLP tasks, removing stop words may distort the meaning of bug reports. + +** Stemming: + - Stemming reduces different forms of a word to its common base by sequential application of stemming rules. For example: light caresses colours becomes Light caress colour + +** Indexing: + + - Indexing: we need to convert the text into numeric representation, there are two common ways of doing this: TF and IDF + - TF: total words / specific word . for example: "bug" appears 50 times in a 150 terms. + - IDF: We penalise certain words based on their frequency. + - bug report classifications here often does not use IDF but TF, because some frequent terms should not be penalized + + - For each report, we will have a vector of indexing for words in the reports according to a dictionary + - Example: A bug report = {“this”, “bugs”, “failure”, “interesting”, …} + Vector = <0.123, 0.34, 0.1, ….> + +** DT + - What is decision tree: a tree structure that split the data depending on different values. + - Each node is a test on the attribute. + - Each branch represents the outcome. + +** NB + - What is Naive Bayes? Classifier based on the conditional probability given by the Bayes theorem. + - Calculating the probability of each class, and classify the given features into the one with higher probability. + +** LR + - What is logistic regression: a linear model for classification + - Fitting the logistic growth and the sigmoid midpoint + - Output a probability, but can use a cutoff point to decide class. + +** Results: +Choose the top 20/50 words when theyre used as a feature diff --git a/20250329121843-ise_week_2.org b/20250329121843-ise_week_2.org new file mode 100644 index 0000000..2c6bf9d --- /dev/null +++ b/20250329121843-ise_week_2.org @@ -0,0 +1,229 @@ +:PROPERTIES: +:ID: f308642d-fcf3-410b-b154-d60582e112a2 +:END: +#+title: ise_week_2 +#+filetags: :uni:notes: + + +* DONE Different Configuration Sampling Methods (pages 8-19) +* DONE Configuration Encodings (pages 21-28) +* DONE Single Environment Learning (DaL) (pages 39-46) + +* 2.1 +** Configuration Sampling +In general machine learning problem, we dont care where the data comes from , but here we do. + +Configuration sampling is used to select representative samples for learning performance models. + +- Types of options: + - Binary (e.g., on/off) + - Numeric (e.g., value ranges) +- Goal: Balance model accuracy with sampling effort. + +** Binary Sampling Strategies + +*** Option-wise Strategy +- Each binary option is selected at least once in some configuration. +- Minimize other options to reduce unknown interaction effects. +- Size: Linear in the number of binary options. + +*** T-wise Strategy +- Covers all T-wise combinations of options (T ≥ 2). +- Example (2-wise): {001}, {010}, {100}, {111} +- Size: Exponential in T. + +*** Negative Option-wise Strategy +- For each option: one configuration where it is disabled, all others enabled. +- Adds one all-yes configuration. +- Size: Linear. +- Example (3 options): {110}, {101}, {011}, {111} +- you can see the 4th one is an all-yes configuration + +*** Random (Binary) +- Select n configurations randomly. +- Simple but may be less representative. + +*** Difference Between Option-wise and Negative Option-wise Strategies + +Both strategies are used for sampling configurations in systems with binary options, but they focus on different aspects of option selection. + +**** Option-wise Strategy +- **Goal:** Ensure each option is enabled (selected) at least once across configurations. +- For every binary option, create a configuration where it is **on**. +- Other options are minimized to avoid unknown interactions. +- **Focus:** Testing the **presence** of each option. +- **Example (3 options):** + - {100} → Option 1 enabled, others off + - {010} → Option 2 enabled, others off + - {001} → Option 3 enabled, others off + +**** Negative Option-wise Strategy +- **Goal:** Ensure each option is disabled (deselected) at least once. +- For each option, create a configuration where it is **off**, and **all others are on**. +- Also includes a configuration where all options are **on**. +- **Focus:** Testing the **absence** of each option. +- **Example (3 options):** + - {110} → Option 3 disabled + - {101} → Option 2 disabled + - {011} → Option 1 disabled + - {111} → All options enabled + +**** Comparison Summary + +| Feature | Option-wise | Negative Option-wise | +|-------------------------+--------------------------+-------------------------------| +| Focus | Presence of each option | Absence of each option | +| What is varied | Each option enabled once | Each option disabled once | +| Other options in config | Typically disabled | Typically enabled | +| Additional config? | Not required | Yes, includes all-on config | +| Use case | Minimal presence testing | Influence of removing options | + +** Non-Binary (Numeric) Sampling Strategies + +*** One-Factor-At-A-Time (OFAT) +- Assumes no interactions among options. +- Varies one option at a time, others fixed at center values. +- Size: Linear in number of options. +- Example (values = 1,3,5): {333}, {533}, {133}, {353}, {313}, {331}, {335} + +*** Box-Behnken Design (BBD) +- Captures quadratic effects and 2-wise interactions. +- Uses subset of 3^k full factorial (min, center, max). +- Size: Exponential in number of options. +- Example: {111}, {113}, {115}, {131}, {151}, etc. + +*** Central Composite Design (CCD) +- Combines: + - 2^k factorial points + - 2k axial points at α-distance + - 1 center point +- Captures curvature and interactions. +- Example: 8 full factorial + 6 axial + {333} + +*** Plackett-Burman Design (PBD) +- Focus on main effects, assumes negligible interactions. +- Uses predefined seeds, e.g., PBD(9,3) +- First config from seed, rest by right-shifting seed. +- Uses indices only for values. +- Example: If O = {1,100,1000,10000,100000}, index 3 could mean 1, 1000, 100000 + +*** Random (Non-Binary) +- Random selection of numeric configurations. +- Risk of non-uniformity and clustering. +- Can negatively impact learning performance. + +** Mixed Variable Sampling + +Some systems include both binary and non-binary (numeric) configuration options. +These are referred to as **mixed systems**. + +- Requires hybrid or combined strategies to ensure representative coverage. +- One approach: **Permute over the mixed space** by combining possible binary and numeric value combinations. +- This can grow combinatorially, so sampling techniques may be needed to reduce the total number of permutations. + +*** Example +- Non-binary configs: {0.1, 0.4, 5}, {0.2, 0.4, 7}, {0.2, 0.7, 5} +- Binary configs: {1,0}, {1,1} +- Full mixed permutations: + - {0.1, 0.4, 5, 1, 0} + - {0.1, 0.4, 5, 1, 1} + - {0.2, 0.4, 7, 1, 0} + - {0.2, 0.4, 7, 1, 1} + - {0.2, 0.7, 5, 1, 0} + - {0.2, 0.7, 5, 1, 1} + +* 2.2 +** Single Environment Learning: DeepPerf + Source: Ha & Zhang, ICSE 2019 + + DeepPerf is an early approach using deep neural networks (>3 layers) to predict software performance in configurable systems. + + - Designed to address: + - Small data size: Limited measurements available. + - Feature sparsity: Only a few configuration options significantly impact performance. + - Network instability: Tackled with tailored hyperparameter tuning. + +** Limitation of DeepPerf + - Does not handle sample sparsity, a major issue in configuration performance prediction. + +** Improved Approach: Divide-and-Learn (DaL) + Source: Gong & Chen, ESEC/FSE 2023 + +*** Key Problem: Sample Sparsity + - Caused by: + - Inherited feature sparsity. + - Small configuration changes leading to drastic performance shifts. + - Not all configurations being valid. + - Training data is sparse due to expensive measurements. + +*** Key Properties of Configuration Landscape + 1. Intra-division smoothness: Configurations in the same division show smooth performance variations. + 2. Inter-division sharpness: Cross-division configurations differ significantly, possibly on key options. + + Risk: Limited data might lead to overfitting within divisions. + +*** Architecture of DaL + + Three Goals: + 1. Divide the configuration data into meaningful divisions → function ϕ + 2. Learn a local model for each division → function μ + 3. Assign new configurations to the correct local model → using ϕ and μ + + - Implementation: + - CART (Decision Tree) is used for dividing. + - DeepPerf models are trained within each division. + - Random Forest is used for classifying unseen configurations into divisions. + +*** Trade-off: Number of Divisions + - More divisions → better at tackling sparsity, but less data per model → risks underfitting. + - Need to balance: + - Generalizability vs. + - Specialization + +*** Results + - DaL outperforms or matches state-of-the-art in 33 out of 40 cases. + - Achieves up to 1.94× improvement. + - Needs fewer training samples for same accuracy. + - Especially beneficial in complex systems or with more training data. +* 2.3 +** Single Environment Learning: Encoding + Source: Gong & Chen, MSR 2022 + + A study conducted by the lab investigates how different encoding schemes impact the software performance learning pipeline. + +*** Three Common Encoding Schemes + - Label encoding + - Scaled label encoding (e.g., max-min normalization) + - One-hot encoding + +** Encoding Schemes Explained + +*** Label Encoding + - Converts configuration options into numeric values. + - Example: + - Configuration: (cache_size, interval, ssl, data_strategy) + - Values: cache_size = (1, 10, 10000), interval = (1–4), ssl = (0, 1), data_strategy = (strategy_1, strategy_2, strategy_3) + - Encoded: (10000, 2, 1, 1) → (2, 1, 1, 1) → data_strategy: (0, 1, 2) + +*** Scaled Label Encoding + - Similar to label encoding but normalizes all values to the range [0, 1]. + - Example (10000, 2, 1, 1) becomes (1, 1/3, 1, 0.5) + +*** One-Hot Encoding + - Transforms each categorical value into a binary vector. + - Example: (10000, 2, 1, 1) becomes (0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0) + +** Community Debate and Justifications + + - Categorical features (e.g., cache_mode = memory, disk, mixed): + - Label encoding implies false ordering (1, 2, 3) + - One-hot encoding avoids this but may introduce multicollinearity. + + - Numeric options (e.g., cache_size = 1, 10, 10000): + - Label encoding maintains order but struggles with large scale differences. + - Scaled label encoding improves numeric stability but weakens interaction with binary features. + +** Study Protocol + - Evaluated using 7 learning algorithms across 5 software systems. + + diff --git a/20250329121843-ise_week_2.org~ b/20250329121843-ise_week_2.org~ new file mode 100644 index 0000000..b61749f --- /dev/null +++ b/20250329121843-ise_week_2.org~ @@ -0,0 +1,229 @@ +:PROPERTIES: +:ID: f308642d-fcf3-410b-b154-d60582e112a2 +:END: +#+title: ise-week-2 +#+filetags: :uni:ise:notes: + + +* DONE Different Configuration Sampling Methods (pages 8-19) +* DONE Configuration Encodings (pages 21-28) +* DONE Single Environment Learning (DaL) (pages 39-46) + +* 2.1 +** Configuration Sampling +In general machine learning problem, we dont care where the data comes from , but here we do. + +Configuration sampling is used to select representative samples for learning performance models. + +- Types of options: + - Binary (e.g., on/off) + - Numeric (e.g., value ranges) +- Goal: Balance model accuracy with sampling effort. + +** Binary Sampling Strategies + +*** Option-wise Strategy +- Each binary option is selected at least once in some configuration. +- Minimize other options to reduce unknown interaction effects. +- Size: Linear in the number of binary options. + +*** T-wise Strategy +- Covers all T-wise combinations of options (T ≥ 2). +- Example (2-wise): {001}, {010}, {100}, {111} +- Size: Exponential in T. + +*** Negative Option-wise Strategy +- For each option: one configuration where it is disabled, all others enabled. +- Adds one all-yes configuration. +- Size: Linear. +- Example (3 options): {110}, {101}, {011}, {111} +- you can see the 4th one is an all-yes configuration + +*** Random (Binary) +- Select n configurations randomly. +- Simple but may be less representative. + +*** Difference Between Option-wise and Negative Option-wise Strategies + +Both strategies are used for sampling configurations in systems with binary options, but they focus on different aspects of option selection. + +**** Option-wise Strategy +- **Goal:** Ensure each option is enabled (selected) at least once across configurations. +- For every binary option, create a configuration where it is **on**. +- Other options are minimized to avoid unknown interactions. +- **Focus:** Testing the **presence** of each option. +- **Example (3 options):** + - {100} → Option 1 enabled, others off + - {010} → Option 2 enabled, others off + - {001} → Option 3 enabled, others off + +**** Negative Option-wise Strategy +- **Goal:** Ensure each option is disabled (deselected) at least once. +- For each option, create a configuration where it is **off**, and **all others are on**. +- Also includes a configuration where all options are **on**. +- **Focus:** Testing the **absence** of each option. +- **Example (3 options):** + - {110} → Option 3 disabled + - {101} → Option 2 disabled + - {011} → Option 1 disabled + - {111} → All options enabled + +**** Comparison Summary + +| Feature | Option-wise | Negative Option-wise | +|-------------------------+--------------------------+-------------------------------| +| Focus | Presence of each option | Absence of each option | +| What is varied | Each option enabled once | Each option disabled once | +| Other options in config | Typically disabled | Typically enabled | +| Additional config? | Not required | Yes, includes all-on config | +| Use case | Minimal presence testing | Influence of removing options | + +** Non-Binary (Numeric) Sampling Strategies + +*** One-Factor-At-A-Time (OFAT) +- Assumes no interactions among options. +- Varies one option at a time, others fixed at center values. +- Size: Linear in number of options. +- Example (values = 1,3,5): {333}, {533}, {133}, {353}, {313}, {331}, {335} + +*** Box-Behnken Design (BBD) +- Captures quadratic effects and 2-wise interactions. +- Uses subset of 3^k full factorial (min, center, max). +- Size: Exponential in number of options. +- Example: {111}, {113}, {115}, {131}, {151}, etc. + +*** Central Composite Design (CCD) +- Combines: + - 2^k factorial points + - 2k axial points at α-distance + - 1 center point +- Captures curvature and interactions. +- Example: 8 full factorial + 6 axial + {333} + +*** Plackett-Burman Design (PBD) +- Focus on main effects, assumes negligible interactions. +- Uses predefined seeds, e.g., PBD(9,3) +- First config from seed, rest by right-shifting seed. +- Uses indices only for values. +- Example: If O = {1,100,1000,10000,100000}, index 3 could mean 1, 1000, 100000 + +*** Random (Non-Binary) +- Random selection of numeric configurations. +- Risk of non-uniformity and clustering. +- Can negatively impact learning performance. + +** Mixed Variable Sampling + +Some systems include both binary and non-binary (numeric) configuration options. +These are referred to as **mixed systems**. + +- Requires hybrid or combined strategies to ensure representative coverage. +- One approach: **Permute over the mixed space** by combining possible binary and numeric value combinations. +- This can grow combinatorially, so sampling techniques may be needed to reduce the total number of permutations. + +*** Example +- Non-binary configs: {0.1, 0.4, 5}, {0.2, 0.4, 7}, {0.2, 0.7, 5} +- Binary configs: {1,0}, {1,1} +- Full mixed permutations: + - {0.1, 0.4, 5, 1, 0} + - {0.1, 0.4, 5, 1, 1} + - {0.2, 0.4, 7, 1, 0} + - {0.2, 0.4, 7, 1, 1} + - {0.2, 0.7, 5, 1, 0} + - {0.2, 0.7, 5, 1, 1} + +* 2.2 +** Single Environment Learning: DeepPerf + Source: Ha & Zhang, ICSE 2019 + + DeepPerf is an early approach using deep neural networks (>3 layers) to predict software performance in configurable systems. + + - Designed to address: + - Small data size: Limited measurements available. + - Feature sparsity: Only a few configuration options significantly impact performance. + - Network instability: Tackled with tailored hyperparameter tuning. + +** Limitation of DeepPerf + - Does not handle sample sparsity, a major issue in configuration performance prediction. + +** Improved Approach: Divide-and-Learn (DaL) + Source: Gong & Chen, ESEC/FSE 2023 + +*** Key Problem: Sample Sparsity + - Caused by: + - Inherited feature sparsity. + - Small configuration changes leading to drastic performance shifts. + - Not all configurations being valid. + - Training data is sparse due to expensive measurements. + +*** Key Properties of Configuration Landscape + 1. Intra-division smoothness: Configurations in the same division show smooth performance variations. + 2. Inter-division sharpness: Cross-division configurations differ significantly, possibly on key options. + + Risk: Limited data might lead to overfitting within divisions. + +*** Architecture of DaL + + Three Goals: + 1. Divide the configuration data into meaningful divisions → function ϕ + 2. Learn a local model for each division → function μ + 3. Assign new configurations to the correct local model → using ϕ and μ + + - Implementation: + - CART (Decision Tree) is used for dividing. + - DeepPerf models are trained within each division. + - Random Forest is used for classifying unseen configurations into divisions. + +*** Trade-off: Number of Divisions + - More divisions → better at tackling sparsity, but less data per model → risks underfitting. + - Need to balance: + - Generalizability vs. + - Specialization + +*** Results + - DaL outperforms or matches state-of-the-art in 33 out of 40 cases. + - Achieves up to 1.94× improvement. + - Needs fewer training samples for same accuracy. + - Especially beneficial in complex systems or with more training data. +* 2.3 +** Single Environment Learning: Encoding + Source: Gong & Chen, MSR 2022 + + A study conducted by the lab investigates how different encoding schemes impact the software performance learning pipeline. + +*** Three Common Encoding Schemes + - Label encoding + - Scaled label encoding (e.g., max-min normalization) + - One-hot encoding + +** Encoding Schemes Explained + +*** Label Encoding + - Converts configuration options into numeric values. + - Example: + - Configuration: (cache_size, interval, ssl, data_strategy) + - Values: cache_size = (1, 10, 10000), interval = (1–4), ssl = (0, 1), data_strategy = (strategy_1, strategy_2, strategy_3) + - Encoded: (10000, 2, 1, 1) → (2, 1, 1, 1) → data_strategy: (0, 1, 2) + +*** Scaled Label Encoding + - Similar to label encoding but normalizes all values to the range [0, 1]. + - Example (10000, 2, 1, 1) becomes (1, 1/3, 1, 0.5) + +*** One-Hot Encoding + - Transforms each categorical value into a binary vector. + - Example: (10000, 2, 1, 1) becomes (0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0) + +** Community Debate and Justifications + + - Categorical features (e.g., cache_mode = memory, disk, mixed): + - Label encoding implies false ordering (1, 2, 3) + - One-hot encoding avoids this but may introduce multicollinearity. + + - Numeric options (e.g., cache_size = 1, 10, 10000): + - Label encoding maintains order but struggles with large scale differences. + - Scaled label encoding improves numeric stability but weakens interaction with binary features. + +** Study Protocol + - Evaluated using 7 learning algorithms across 5 software systems. + + diff --git a/20250329142725-ise_week_3.org b/20250329142725-ise_week_3.org new file mode 100644 index 0000000..c0cac06 --- /dev/null +++ b/20250329142725-ise_week_3.org @@ -0,0 +1,182 @@ +:PROPERTIES: +:ID: 1d0fa257-579f-49f3-b8fd-a3b68ddccf10 +:END: +#+title: ise_week_3 +#+filetags: :uni:notes: + + +* DONE Classic Code Complexity Metrics (pages 8-27) +* DONE How to Mine Bugs for Learning? (pages 37-43) +* DONE Cross Project Prediction (HDP) (pages 50-60) + +* 3.1 Intelligent Software Engineering: Classic Metrics +** Software Defect Prediction +- The foundation of software defect prediction lies in metric identification. +- This was a key research direction in the 1980s. +- Metrics aim to quantify properties of code to detect potential defects and improve quality. +** Classic Code Metrics + +*** 1. McCabe Cyclomatic Complexity +- Purpose: Measures the complexity of code based on the number of linearly independent paths in the code’s flow graph. + +**** Why it Matters +- More conditional statements = More possible execution paths = Higher complexity. +- Useful for identifying complex, hard-to-test, and error-prone code. + +**** Simple Definition +- McCabe Complexity = Number of simple conditions + 1 + +**** What is a “Simple Condition”? +- A conditional without logical connectors (AND, OR). +- Examples: + - if (a > b) + - while (a > b) + - for (a=b; a > b; b++) + - do {…} while (a > b) + +**** Compound Conditions +- Count each simple condition inside: + - if (a > b || a > 2) → 2 simple conditions + - if (a > b && a > 2) → 2 simple conditions + +**** Use Case +- Helps determine test case count needed for complete branch coverage. + +*** 2. Halstead Complexity Measures +- Purpose: Measures complexity based on the operators and operands used in code. + +**** Definitions: +- n1: Number of distinct operators (e.g., !=, !, %, /, *, +, &&, ||) +- n2: Number of distinct operands (e.g., variable names, constants, types like bool, char) +- N1: Total occurrences of operators +- N2: Total occurrences of operands + +**** Why Use Halstead? +- Evaluates: + - Code length + - Code vocabulary + - Effort required to implement or understand the code + - Potential bugs + +*** 3. Lines of Code (LOC) +- LOC: Total number of lines in a program. +- Comment Lines: Lines containing only comments. + +**** Usefulness: +- Simple indicator of: + - Code size + - Code density + - Maintainability and readability + +* 3.2 Intelligent Software Engineering: Within-Project Prediction +** Just-in-Time (JIT) Defect Prediction +- Based on the classic work by Kim et al. (2008). +- Focuses on predicting defects at the commit/change level rather than file or module level. + +** Steps in the JIT Defect Prediction Pipeline: +1. File-level changes are extracted from a project's revision history. +2. Bug fix changes are identified using keywords in SCM (Source Code Management) change log messages. +3. Bug-introducing and clean changes are identified by tracing backwards from the bug fix commits. +4. A classification model (e.g., SVM) is trained on these labeled examples. +5. Once trained, the classifier can predict if new code changes are likely to be buggy or clean. + +** Change-wise Prediction Details + +*** Change History Extraction +- Collected information includes: + - Change log + - Author + - Change date + - Source code + - Change delta + - Change metadata + +*** Identifying Bug-Introducing Changes + +**** Step 1: Search for Bug Fixes +- Use keywords (e.g., “fix”, “bug”, “patch”) to find bug-fixing commits. + +**** Step 2: Use the SZZ Algorithm +- Determine what was changed in bug fixes. +- Produces a list of regions ("hunks") showing differences between two revisions. +- Deleted or modified code in each hunk is treated as the location of a bug. +- Traces origin of this code to find the earlier bug-introducing changes. + +** Example Walkthrough + +*** Revision 1: +- Initial creation of a function `bar`. +- Introduces a bug: `if (report == null)` (should be `!=`). +- SCM annotate shows all lines as modified in revision 1 by "kim". + +*** Revision 2: +- Two changes: + - Function `bar` renamed to `foo`. + - Argument changed from `report` to `report.str` in `println`. +- Annotate output shows lines 1 and 4 were last modified by "ejw" in revision 2. + +*** Revision 3: +- Bug fix applied: changes `==` to `!=` on line 3. +- SZZ algorithm compares revisions 3 and 2, identifying line 3 as modified. +- Traces line 3’s origin back to revision 1 — identifying the bug-introducing change. + +* 3.3 Intelligent Software Engineering: Cross-Project Prediction (HDP) +** Heterogeneous Defect Prediction (HDP) +- Based on the work by Nam and Kim (2015). +- Motivation: Metrics used for defect prediction often differ across projects. +- Goal: Address the metric mismatching problem across projects (heterogeneous settings). +- Classifier agnostic — can be used with any machine learning model. + +** HDP Architecture + +*** Metric Selection in Source Datasets +- Uses well-known feature selection methods: + - Gain ratio + - Chi-square + - Relief-F + - Significance attribute evaluation +- Empirical testing used to choose the best approach. +- Top 15% metrics per source project are selected. +- Metric mismatching arises because each project may prioritize different metrics. + +*** Matching Source and Target Metrics + +**** Key Steps: +1. Pair all metrics from source and target projects. +2. Remove poorly matched metrics based on a cutoff threshold for matching scores. +3. Apply maximum weighted bipartite matching to select the best group of matched metric pairs: + - Goal: Maximize sum of matching scores. + - Ensure no duplicated metrics are selected. + +**** Example: +- 2 source metrics: X1, X2 +- 2 target metrics: Y1, Y2 +- Matching pairs: (X1,Y1), (X1,Y2), (X2,Y1), (X2,Y2) + +After applying a cutoff threshold of 0.30: +- Group 1: (X1,Y1) and (X2,Y2) with total score 1.3 (=0.8+0.5) +- Group 2: (X2,Y1) with score 0.4 (Stands alone (can't be paired with any other remaining pair without duplication)). +- Group 1 is chosen as the matched metric set. + +** Methods for Calculating Matching Scores + +*** Percentile-Based Method +- Compares 9 percentiles (10th, 20th, ..., 90th) between source and target metric values. +- Uses the formula: + Pij(n) = 1 - |spij(n) - bpij(n)| / bpij(n) + - spij(n): smaller percentile value + - bpij(n): bigger percentile value +- Matching score is 1 when all percentiles are identical. + +*** Kolmogorov-Smirnov (KS) Test Method +- Non-parametric two-sample test. +- Useful when distributions are unknown or have unequal variances. +- Computes a p-value to indicate the similarity. +- Matching score derived from the p-value. + +*** Spearman’s Rank Correlation Coefficient Method +- Measures correlation between two sets of values. +- If dataset sizes differ, randomly sample the larger set to match sizes. + +** Classifier Independence +- HDP approach can be paired with any machine learning algorithm (e.g., SVM, RF, etc.) diff --git a/20250329142725-ise_week_3.org~ b/20250329142725-ise_week_3.org~ new file mode 100644 index 0000000..05f980e --- /dev/null +++ b/20250329142725-ise_week_3.org~ @@ -0,0 +1,182 @@ +:PROPERTIES: +:ID: 1d0fa257-579f-49f3-b8fd-a3b68ddccf10 +:END: +#+title: ise-week-3 +#+filetags: :uni:ise:notes: + + +* DONE Classic Code Complexity Metrics (pages 8-27) +* DONE How to Mine Bugs for Learning? (pages 37-43) +* DONE Cross Project Prediction (HDP) (pages 50-60) + +* 3.1 Intelligent Software Engineering: Classic Metrics +** Software Defect Prediction +- The foundation of software defect prediction lies in metric identification. +- This was a key research direction in the 1980s. +- Metrics aim to quantify properties of code to detect potential defects and improve quality. +** Classic Code Metrics + +*** 1. McCabe Cyclomatic Complexity +- Purpose: Measures the complexity of code based on the number of linearly independent paths in the code’s flow graph. + +**** Why it Matters +- More conditional statements = More possible execution paths = Higher complexity. +- Useful for identifying complex, hard-to-test, and error-prone code. + +**** Simple Definition +- McCabe Complexity = Number of simple conditions + 1 + +**** What is a “Simple Condition”? +- A conditional without logical connectors (AND, OR). +- Examples: + - if (a > b) + - while (a > b) + - for (a=b; a > b; b++) + - do {…} while (a > b) + +**** Compound Conditions +- Count each simple condition inside: + - if (a > b || a > 2) → 2 simple conditions + - if (a > b && a > 2) → 2 simple conditions + +**** Use Case +- Helps determine test case count needed for complete branch coverage. + +*** 2. Halstead Complexity Measures +- Purpose: Measures complexity based on the operators and operands used in code. + +**** Definitions: +- n1: Number of distinct operators (e.g., !=, !, %, /, *, +, &&, ||) +- n2: Number of distinct operands (e.g., variable names, constants, types like bool, char) +- N1: Total occurrences of operators +- N2: Total occurrences of operands + +**** Why Use Halstead? +- Evaluates: + - Code length + - Code vocabulary + - Effort required to implement or understand the code + - Potential bugs + +*** 3. Lines of Code (LOC) +- LOC: Total number of lines in a program. +- Comment Lines: Lines containing only comments. + +**** Usefulness: +- Simple indicator of: + - Code size + - Code density + - Maintainability and readability + +* 3.2 Intelligent Software Engineering: Within-Project Prediction +** Just-in-Time (JIT) Defect Prediction +- Based on the classic work by Kim et al. (2008). +- Focuses on predicting defects at the commit/change level rather than file or module level. + +** Steps in the JIT Defect Prediction Pipeline: +1. File-level changes are extracted from a project's revision history. +2. Bug fix changes are identified using keywords in SCM (Source Code Management) change log messages. +3. Bug-introducing and clean changes are identified by tracing backwards from the bug fix commits. +4. A classification model (e.g., SVM) is trained on these labeled examples. +5. Once trained, the classifier can predict if new code changes are likely to be buggy or clean. + +** Change-wise Prediction Details + +*** Change History Extraction +- Collected information includes: + - Change log + - Author + - Change date + - Source code + - Change delta + - Change metadata + +*** Identifying Bug-Introducing Changes + +**** Step 1: Search for Bug Fixes +- Use keywords (e.g., “fix”, “bug”, “patch”) to find bug-fixing commits. + +**** Step 2: Use the SZZ Algorithm +- Determine what was changed in bug fixes. +- Produces a list of regions ("hunks") showing differences between two revisions. +- Deleted or modified code in each hunk is treated as the location of a bug. +- Traces origin of this code to find the earlier bug-introducing changes. + +** Example Walkthrough + +*** Revision 1: +- Initial creation of a function `bar`. +- Introduces a bug: `if (report == null)` (should be `!=`). +- SCM annotate shows all lines as modified in revision 1 by "kim". + +*** Revision 2: +- Two changes: + - Function `bar` renamed to `foo`. + - Argument changed from `report` to `report.str` in `println`. +- Annotate output shows lines 1 and 4 were last modified by "ejw" in revision 2. + +*** Revision 3: +- Bug fix applied: changes `==` to `!=` on line 3. +- SZZ algorithm compares revisions 3 and 2, identifying line 3 as modified. +- Traces line 3’s origin back to revision 1 — identifying the bug-introducing change. + +* 3.3 Intelligent Software Engineering: Cross-Project Prediction (HDP) +** Heterogeneous Defect Prediction (HDP) +- Based on the work by Nam and Kim (2015). +- Motivation: Metrics used for defect prediction often differ across projects. +- Goal: Address the metric mismatching problem across projects (heterogeneous settings). +- Classifier agnostic — can be used with any machine learning model. + +** HDP Architecture + +*** Metric Selection in Source Datasets +- Uses well-known feature selection methods: + - Gain ratio + - Chi-square + - Relief-F + - Significance attribute evaluation +- Empirical testing used to choose the best approach. +- Top 15% metrics per source project are selected. +- Metric mismatching arises because each project may prioritize different metrics. + +*** Matching Source and Target Metrics + +**** Key Steps: +1. Pair all metrics from source and target projects. +2. Remove poorly matched metrics based on a cutoff threshold for matching scores. +3. Apply maximum weighted bipartite matching to select the best group of matched metric pairs: + - Goal: Maximize sum of matching scores. + - Ensure no duplicated metrics are selected. + +**** Example: +- 2 source metrics: X1, X2 +- 2 target metrics: Y1, Y2 +- Matching pairs: (X1,Y1), (X1,Y2), (X2,Y1), (X2,Y2) + +After applying a cutoff threshold of 0.30: +- Group 1: (X1,Y1) and (X2,Y2) with total score 1.3 (=0.8+0.5) +- Group 2: (X2,Y1) with score 0.4 (Stands alone (can't be paired with any other remaining pair without duplication)). +- Group 1 is chosen as the matched metric set. + +** Methods for Calculating Matching Scores + +*** Percentile-Based Method +- Compares 9 percentiles (10th, 20th, ..., 90th) between source and target metric values. +- Uses the formula: + Pij(n) = 1 - |spij(n) - bpij(n)| / bpij(n) + - spij(n): smaller percentile value + - bpij(n): bigger percentile value +- Matching score is 1 when all percentiles are identical. + +*** Kolmogorov-Smirnov (KS) Test Method +- Non-parametric two-sample test. +- Useful when distributions are unknown or have unequal variances. +- Computes a p-value to indicate the similarity. +- Matching score derived from the p-value. + +*** Spearman’s Rank Correlation Coefficient Method +- Measures correlation between two sets of values. +- If dataset sizes differ, randomly sample the larger set to match sizes. + +** Classifier Independence +- HDP approach can be paired with any machine learning algorithm (e.g., SVM, RF, etc.) diff --git a/20250329200158-ise_week_4.org b/20250329200158-ise_week_4.org new file mode 100644 index 0000000..f86fab1 --- /dev/null +++ b/20250329200158-ise_week_4.org @@ -0,0 +1,268 @@ +:PROPERTIES: +:ID: ebf874d9-0554-47f0-be8b-5c9a948738bf +:END: +#+title: ise_week_4 +#+filetags: :uni:notes: + + + +* DONE Different Coverage Metrics and Branch Concepts (pages 6-12) +* DONE Evolutionary Algorithm (pages 24-32) +* DONE Test Case Generation (EvoSuite) (pages 44-55) +* DONE Multi/Many-objective Software Testing (Sapienz) (pages 80-97) + +want to figure out how to translate the real world phenotype to a genotype +* 4.2 Evolutionary Algorithms - Intelligent Software Engineering + +** 1. Illustrative Optimization Problem + +- Problem: Maximize the objective function \( f(x) = x^2 \) +- Design variable: \( x \in \{-15, -14, ..., 0, 1, ..., 15\} \) +- Search space: All integers between -15 and 15 inclusive +- Objective function: \( f(x) = x^2 \), to be maximized +- Constraints: None +- This problem is simple and allows us to demonstrate the application of evolutionary algorithms without involving additional complexity from constraints. + +** 2. Representation + +Evolutionary algorithms operate on representations of solutions called genotypes, which map to actual solutions (phenotypes). The choice of representation is crucial and problem-dependent. + +*** Binary Representation + +- The solution is represented as a fixed-length binary string. +- For the example problem (maximizing \( f(x) = x^2 \)), we use a 5-bit binary representation: + - The first bit indicates the sign of \( x \): 0 for positive, 1 for negative. + - The remaining bits represent the magnitude in binary. +- The genotype space is \( \{0,1\}^L \), where L is the length of the binary string. + +*** Other Common Representations + +- **Binary**: Suitable for many simple problems. +- **Integer**: Useful for categorical or discrete variables (e.g., car brands such as Toyota, Volkswagen, etc.). +- **Floating Point**: Used for problems with continuous variables. For example, optimizing \( f(x_1, x_2) = x_1 + x_2 \), where \( x_1, x_2 \in [0,1] \). +- **Permutations**: Suitable for ordering problems like the Traveling Salesman Problem. +- **Matrices**: Employed in more complex problems such as staff allocation or scheduling. + +** 3. Evolutionary Algorithm Steps + +The typical steps in an evolutionary algorithm include: + +1. **Initialization**: + - Start with a randomly generated population of candidate solutions. + - Ensure a diverse set of individuals to explore the search space effectively. + - Optionally include known solutions or use heuristics to seed the initial population. + +2. **Evaluation**: + - Each individual is evaluated using a fitness function. + - The fitness function quantifies how well an individual performs with respect to the problem objective. + +3. **Main Loop** (repeats until termination condition is met): + a. **Selection**: + - Select parent individuals based on their fitness. + - Higher fitness individuals have a higher chance of being selected. + + b. **Recombination (Crossover)**: + - Combine selected parents to produce new offspring. + - Occurs with probability \( P_c \) (crossover probability). + + c. **Mutation**: + - Randomly alter offspring genes to maintain diversity. + - Occurs with probability \( P_m \) (mutation probability). + + d. **Evaluation of Offspring**: + - Assess the fitness of each newly created individual. + + e. **Survivor Selection**: + - Decide which individuals (from parents and offspring) will make up the next generation. + - Can use various strategies like elitism or generational replacement. + +** 4. Fitness Function + +- The fitness function is derived from the problem’s objective or quality function. +- It assigns a single real-valued score to each individual (phenotype). +- The function reflects the degree to which a solution meets the desired criteria. +- Typically, the aim is to **maximize** fitness. +- If the problem is better posed as a minimization task, it can be transformed accordingly (e.g., minimizing \( f(x) \) is equivalent to maximizing \( -f(x) \)). + +* 4.3 Test Case Generation using EvoSuite - Intelligent Software Engineering + +** 1. Introduction to EvoSuite + +- EvoSuite is a tool developed by Fraser and Arcuri (2011) for automated test case generation. +- It generates whole test suites (not just individual test cases) for a given software system. +- The tool accepts a list of input classes to be tested and produces corresponding JUnit test case code. +- It leverages **genetic algorithms**, a form of evolutionary computation, to evolve effective test suites. + +** 2. Motivation and Limitations of Traditional Methods + +- Conventional test generation tools typically focus on **single coverage goals** (e.g., a single program branch). +- Assumes: + - All coverage goals are equally important. + - All goals are equally difficult to reach. + - Goals are independent of each other. +- These assumptions are problematic: + - The sequence in which goals are selected can significantly affect the quality of the resulting test suite. + - Interdependencies among goals are often ignored. + +*** Solution: +- Generate **whole test suites** rather than isolated test cases. +- Takes into account relationships between methods/classes. + +** 3. Architecture and Representation + +*** Test Suite Representation + +- A test suite \( T \) consists of multiple test cases. +- Each **test case** is a sequence of statements of varying types and lengths. +- The total length of a test suite is the sum of the lengths of its individual test cases. + +*** Statement Types in Test Cases + +1. **Primitive statements**: Initialize basic types (e.g., `int var0 = 54`) +2. **Constructor statements**: Create new instances (e.g., `Stack var1 = new Stack()`) +3. **Field statements**: Access object members (e.g., `int var2 = var1.size`) +4. **Method statements**: Call methods (e.g., `int var3 = var1.pop()`) + +** 4. Fitness Function + +- Guides the **selection of parents** in the genetic algorithm. +- Aims to **maximize code coverage**. +- If two test suites achieve the same coverage, the one with fewer statements is preferred (parsimony). +- Uses **branch coverage** as the primary metric. +- Employs the **branch distance heuristic**: + - Measures how close an input is to flipping a predicate’s boolean outcome. + +** 5. Bloat Control + +- A known issue in Genetic Algorithms is **bloat**, where test cases grow unnecessarily large. +- Can lead to memory exhaustion and inefficiency. + +*** Techniques Used: +- Set limits: + - Maximum number of test cases \( N \) + - Maximum length per test case \( L \) +- Discard offspring that do not provide improved coverage. + +** 6. Search Operators + +*** Crossover Operator + +- Combines two parent test suites (P1 and P2) to generate two offspring (O1 and O2). +- O1 = first \( a \cdot |P1| \) test cases from P1 + remaining from P2. +- O2 = similar combination from P2 and P1. +- Valid since test cases are independent. +- Helps reduce difference in length between resulting test suites. + +*** Mutation Operator + +- Mutation is applied with a probability of \( 1/T \), where \( T \) is the number of test cases. +- New test cases may be added with a probability \( p \), up to a maximum count \( N \). + +*** Mutation Operations (applied with equal probability 1/3): + +1. **Remove**: + - Each statement \( s_i \) is deleted with probability \( 1/n \), where \( n \) is the number of statements. + - If needed, replace deleted statements to keep test case valid. + +2. **Change**: + - Each statement \( s_i \) may be altered. + - For primitives: change numeric value randomly within ±Δ. + - For others: change to a method/field/constructor of the same type. + +3. **Insert**: + - A new statement is inserted at a random position in the test case. + +** 7. Results and Evaluation + +- Key takeaway: **EvoSuite outperforms traditional single-goal test generation tools**. +- Reported improvement: Up to **18x better branch coverage** than single-branch strategies. + + +* 4.4 Multi/Many-objective Software Testing with Sapienz - Intelligent Software Engineering + +** 1. Introduction to Sapienz + +- Sapienz is an automated software testing tool developed by Mao et al. (2016). +- It uses evolutionary algorithms to generate test cases for Android apps. +- Notable Achievements: + - Tested the top 1000 most popular Google Play apps. + - Discovered 558 unique and previously unknown app crashes. + - Led to a commercial spinout company named **MaJiCkE**. + - Acquired by **Facebook/Meta**. + +- Sapienz customizes the **NSGA-II** algorithm (a multi-objective genetic algorithm) for test case generation. + +Reference: Mao, Ke, Mark Harman, and Yue Jia. *"Sapienz: Multi-objective automated testing for android applications."* ISSTA 2016. + +** 2. NSGA-II: An Overview + +- NSGA-II is a Genetic Algorithm (GA) adapted for **multi-objective optimization**. +- Key Differences from standard GA: + - Uses **Pareto dominance** for survival selection. + - A solution **a dominates** solution **b** if: + - \( a_i \leq b_i \) for all objectives, and + - \( \exists j \) such that \( a_j < b_j \) + - A **Pareto optimal** solution is one that is not dominated by any other in the population. + +- NSGA-II also uses: + - **Non-dominated sorting**: Separates population into Pareto fronts. + - **Crowding distance**: Prefers diverse solutions within the same front. + +** 3. Representation + +- Specific representation details were not included in the slides but are tailored to represent Android GUI interaction sequences. + +** 4. Objective Functions in Sapienz + +Sapienz optimizes multiple objectives simultaneously: + +*** a. Code Coverage + +- Types of coverage used: + - **Statement Coverage**: Measures how many individual code statements are executed. + - **Method Coverage**: Measures the number of methods invoked. + - **Android Activity Coverage**: Tracks which screens (activities) of the app are accessed. + - Example: A dialer app may include separate activities for contacts, keypad, call history, etc. + +*** b. Test Case Length + +- Shorter test cases are generally preferred to improve efficiency and reduce overhead. +- Multiple slides (86–89) emphasize the importance of minimizing test length. + +*** c. Crash Discovery + +- The number of test cases that lead to app crashes is also a key metric. +- Objective: Maximize the number of crash-inducing test cases. + +** 5. Search Operators + +*** a. Crossover + +- Combines parts of two parent test sequences to form new offspring. +- Details of the crossover structure are tool-specific but follow the typical GA-style recombination. + +*** b. Mutation + +- Mutations are applied to test cases to explore new behaviors. +- Types of Mutation: + + 1. **High-Level Mutation**: + - Alters the structure or intent of test sequences. + + 2. **Low-Level Mutation (Same Size)**: + - Changes test actions without altering the sequence length. + + 3. **Low-Level Mutation (Different Size)**: + - Adds or removes actions to vary the length of test cases. + + 4. **Low-Level Mutation (Shuffling)**: + - Reorders existing actions in the test case. + +** 6. Results and Observations + +- Sapienz significantly **outperforms other automated testing tools** in terms of: + - Number of crashes detected. + - Coverage achieved. + - Efficiency in test generation. + + diff --git a/20250329200158-ise_week_4.org~ b/20250329200158-ise_week_4.org~ new file mode 100644 index 0000000..424ee9b --- /dev/null +++ b/20250329200158-ise_week_4.org~ @@ -0,0 +1,268 @@ +:PROPERTIES: +:ID: ebf874d9-0554-47f0-be8b-5c9a948738bf +:END: +#+title: ise-week-4 +#+filetags: :uni:ise:notes: + + + +* DONE Different Coverage Metrics and Branch Concepts (pages 6-12) +* DONE Evolutionary Algorithm (pages 24-32) +* DONE Test Case Generation (EvoSuite) (pages 44-55) +* DONE Multi/Many-objective Software Testing (Sapienz) (pages 80-97) + +want to figure out how to translate the real world phenotype to a genotype +* 4.2 Evolutionary Algorithms - Intelligent Software Engineering + +** 1. Illustrative Optimization Problem + +- Problem: Maximize the objective function \( f(x) = x^2 \) +- Design variable: \( x \in \{-15, -14, ..., 0, 1, ..., 15\} \) +- Search space: All integers between -15 and 15 inclusive +- Objective function: \( f(x) = x^2 \), to be maximized +- Constraints: None +- This problem is simple and allows us to demonstrate the application of evolutionary algorithms without involving additional complexity from constraints. + +** 2. Representation + +Evolutionary algorithms operate on representations of solutions called genotypes, which map to actual solutions (phenotypes). The choice of representation is crucial and problem-dependent. + +*** Binary Representation + +- The solution is represented as a fixed-length binary string. +- For the example problem (maximizing \( f(x) = x^2 \)), we use a 5-bit binary representation: + - The first bit indicates the sign of \( x \): 0 for positive, 1 for negative. + - The remaining bits represent the magnitude in binary. +- The genotype space is \( \{0,1\}^L \), where L is the length of the binary string. + +*** Other Common Representations + +- **Binary**: Suitable for many simple problems. +- **Integer**: Useful for categorical or discrete variables (e.g., car brands such as Toyota, Volkswagen, etc.). +- **Floating Point**: Used for problems with continuous variables. For example, optimizing \( f(x_1, x_2) = x_1 + x_2 \), where \( x_1, x_2 \in [0,1] \). +- **Permutations**: Suitable for ordering problems like the Traveling Salesman Problem. +- **Matrices**: Employed in more complex problems such as staff allocation or scheduling. + +** 3. Evolutionary Algorithm Steps + +The typical steps in an evolutionary algorithm include: + +1. **Initialization**: + - Start with a randomly generated population of candidate solutions. + - Ensure a diverse set of individuals to explore the search space effectively. + - Optionally include known solutions or use heuristics to seed the initial population. + +2. **Evaluation**: + - Each individual is evaluated using a fitness function. + - The fitness function quantifies how well an individual performs with respect to the problem objective. + +3. **Main Loop** (repeats until termination condition is met): + a. **Selection**: + - Select parent individuals based on their fitness. + - Higher fitness individuals have a higher chance of being selected. + + b. **Recombination (Crossover)**: + - Combine selected parents to produce new offspring. + - Occurs with probability \( P_c \) (crossover probability). + + c. **Mutation**: + - Randomly alter offspring genes to maintain diversity. + - Occurs with probability \( P_m \) (mutation probability). + + d. **Evaluation of Offspring**: + - Assess the fitness of each newly created individual. + + e. **Survivor Selection**: + - Decide which individuals (from parents and offspring) will make up the next generation. + - Can use various strategies like elitism or generational replacement. + +** 4. Fitness Function + +- The fitness function is derived from the problem’s objective or quality function. +- It assigns a single real-valued score to each individual (phenotype). +- The function reflects the degree to which a solution meets the desired criteria. +- Typically, the aim is to **maximize** fitness. +- If the problem is better posed as a minimization task, it can be transformed accordingly (e.g., minimizing \( f(x) \) is equivalent to maximizing \( -f(x) \)). + +* 4.3 Test Case Generation using EvoSuite - Intelligent Software Engineering + +** 1. Introduction to EvoSuite + +- EvoSuite is a tool developed by Fraser and Arcuri (2011) for automated test case generation. +- It generates whole test suites (not just individual test cases) for a given software system. +- The tool accepts a list of input classes to be tested and produces corresponding JUnit test case code. +- It leverages **genetic algorithms**, a form of evolutionary computation, to evolve effective test suites. + +** 2. Motivation and Limitations of Traditional Methods + +- Conventional test generation tools typically focus on **single coverage goals** (e.g., a single program branch). +- Assumes: + - All coverage goals are equally important. + - All goals are equally difficult to reach. + - Goals are independent of each other. +- These assumptions are problematic: + - The sequence in which goals are selected can significantly affect the quality of the resulting test suite. + - Interdependencies among goals are often ignored. + +*** Solution: +- Generate **whole test suites** rather than isolated test cases. +- Takes into account relationships between methods/classes. + +** 3. Architecture and Representation + +*** Test Suite Representation + +- A test suite \( T \) consists of multiple test cases. +- Each **test case** is a sequence of statements of varying types and lengths. +- The total length of a test suite is the sum of the lengths of its individual test cases. + +*** Statement Types in Test Cases + +1. **Primitive statements**: Initialize basic types (e.g., `int var0 = 54`) +2. **Constructor statements**: Create new instances (e.g., `Stack var1 = new Stack()`) +3. **Field statements**: Access object members (e.g., `int var2 = var1.size`) +4. **Method statements**: Call methods (e.g., `int var3 = var1.pop()`) + +** 4. Fitness Function + +- Guides the **selection of parents** in the genetic algorithm. +- Aims to **maximize code coverage**. +- If two test suites achieve the same coverage, the one with fewer statements is preferred (parsimony). +- Uses **branch coverage** as the primary metric. +- Employs the **branch distance heuristic**: + - Measures how close an input is to flipping a predicate’s boolean outcome. + +** 5. Bloat Control + +- A known issue in Genetic Algorithms is **bloat**, where test cases grow unnecessarily large. +- Can lead to memory exhaustion and inefficiency. + +*** Techniques Used: +- Set limits: + - Maximum number of test cases \( N \) + - Maximum length per test case \( L \) +- Discard offspring that do not provide improved coverage. + +** 6. Search Operators + +*** Crossover Operator + +- Combines two parent test suites (P1 and P2) to generate two offspring (O1 and O2). +- O1 = first \( a \cdot |P1| \) test cases from P1 + remaining from P2. +- O2 = similar combination from P2 and P1. +- Valid since test cases are independent. +- Helps reduce difference in length between resulting test suites. + +*** Mutation Operator + +- Mutation is applied with a probability of \( 1/T \), where \( T \) is the number of test cases. +- New test cases may be added with a probability \( p \), up to a maximum count \( N \). + +*** Mutation Operations (applied with equal probability 1/3): + +1. **Remove**: + - Each statement \( s_i \) is deleted with probability \( 1/n \), where \( n \) is the number of statements. + - If needed, replace deleted statements to keep test case valid. + +2. **Change**: + - Each statement \( s_i \) may be altered. + - For primitives: change numeric value randomly within ±Δ. + - For others: change to a method/field/constructor of the same type. + +3. **Insert**: + - A new statement is inserted at a random position in the test case. + +** 7. Results and Evaluation + +- Key takeaway: **EvoSuite outperforms traditional single-goal test generation tools**. +- Reported improvement: Up to **18x better branch coverage** than single-branch strategies. + + +* 4.4 Multi/Many-objective Software Testing with Sapienz - Intelligent Software Engineering + +** 1. Introduction to Sapienz + +- Sapienz is an automated software testing tool developed by Mao et al. (2016). +- It uses evolutionary algorithms to generate test cases for Android apps. +- Notable Achievements: + - Tested the top 1000 most popular Google Play apps. + - Discovered 558 unique and previously unknown app crashes. + - Led to a commercial spinout company named **MaJiCkE**. + - Acquired by **Facebook/Meta**. + +- Sapienz customizes the **NSGA-II** algorithm (a multi-objective genetic algorithm) for test case generation. + +Reference: Mao, Ke, Mark Harman, and Yue Jia. *"Sapienz: Multi-objective automated testing for android applications."* ISSTA 2016. + +** 2. NSGA-II: An Overview + +- NSGA-II is a Genetic Algorithm (GA) adapted for **multi-objective optimization**. +- Key Differences from standard GA: + - Uses **Pareto dominance** for survival selection. + - A solution **a dominates** solution **b** if: + - \( a_i \leq b_i \) for all objectives, and + - \( \exists j \) such that \( a_j < b_j \) + - A **Pareto optimal** solution is one that is not dominated by any other in the population. + +- NSGA-II also uses: + - **Non-dominated sorting**: Separates population into Pareto fronts. + - **Crowding distance**: Prefers diverse solutions within the same front. + +** 3. Representation + +- Specific representation details were not included in the slides but are tailored to represent Android GUI interaction sequences. + +** 4. Objective Functions in Sapienz + +Sapienz optimizes multiple objectives simultaneously: + +*** a. Code Coverage + +- Types of coverage used: + - **Statement Coverage**: Measures how many individual code statements are executed. + - **Method Coverage**: Measures the number of methods invoked. + - **Android Activity Coverage**: Tracks which screens (activities) of the app are accessed. + - Example: A dialer app may include separate activities for contacts, keypad, call history, etc. + +*** b. Test Case Length + +- Shorter test cases are generally preferred to improve efficiency and reduce overhead. +- Multiple slides (86–89) emphasize the importance of minimizing test length. + +*** c. Crash Discovery + +- The number of test cases that lead to app crashes is also a key metric. +- Objective: Maximize the number of crash-inducing test cases. + +** 5. Search Operators + +*** a. Crossover + +- Combines parts of two parent test sequences to form new offspring. +- Details of the crossover structure are tool-specific but follow the typical GA-style recombination. + +*** b. Mutation + +- Mutations are applied to test cases to explore new behaviors. +- Types of Mutation: + + 1. **High-Level Mutation**: + - Alters the structure or intent of test sequences. + + 2. **Low-Level Mutation (Same Size)**: + - Changes test actions without altering the sequence length. + + 3. **Low-Level Mutation (Different Size)**: + - Adds or removes actions to vary the length of test cases. + + 4. **Low-Level Mutation (Shuffling)**: + - Reorders existing actions in the test case. + +** 6. Results and Observations + +- Sapienz significantly **outperforms other automated testing tools** in terms of: + - Number of crashes detected. + - Coverage achieved. + - Efficiency in test generation. + + diff --git a/20250329231658-emacs_stuff_magit.org b/20250329231658-emacs_stuff_magit.org new file mode 100644 index 0000000..feb5544 --- /dev/null +++ b/20250329231658-emacs_stuff_magit.org @@ -0,0 +1,46 @@ +:PROPERTIES: +:ID: 2ab0fa3f-8ac6-4af2-8cd4-1dd490fb19c3 +:END: +#+title: emacs-stuff-magit +#+filetags: :emacs:git:guide: + +* Magit Key Guide (Quick Reference) + +** Open Magit +- C-x g :: Open Magit status buffer + +** Staging & Unstaging +- s :: Stage (file or hunk) +- u :: Unstage +- S :: Stage all +- U :: Unstage all + +** Committing +- c c :: Commit +- C-c C-c :: Confirm commit (in commit buffer) +- c a :: Amend last commit + +** Branching +- b b :: Switch branch +- b c :: Create new branch +- b m :: Merge into current +- b M :: Rebase onto another branch + +** Push / Pull +- P u :: Push to upstream +- F u :: Pull from upstream +- f u :: Fetch from upstream + +** Logs & Diffs +- l l :: Show log for current branch +- d :: Show diff (between commits, etc.) +- RET :: View diff at point + +** Help & Dispatch +- ? :: Show help for current buffer +- x :: Open Magit dispatch menu (magit-dispatch) +- ! :: Run Git command (rebase, cherry-pick, etc.) + +** Other Essentials +- k :: Discard changes (careful) +- q :: Quit Magit buffer diff --git a/20250331201944-ise_week_5.org b/20250331201944-ise_week_5.org new file mode 100644 index 0000000..4441549 --- /dev/null +++ b/20250331201944-ise_week_5.org @@ -0,0 +1,117 @@ +:PROPERTIES: +:ID: 0e70c535-b145-42d9-a9ed-fe48cddbb1a5 +:END: +#+title: ise_week_5 +#+filetags: :uni:notes: + +* TODO Model free Tuning (for ORM) (pages 9-17) +* TODO Model free Tuning (BestConfig) (pages 18-23) + + +* 5.1 Model-Free Tuning for ORM Systems - Intelligent Software Engineering + +** 1. Introduction and Background + +- This approach was proposed by Singh et al. (2016). +- The goal is to optimize Object-Relational Mapping (ORM) systems without relying on models. +- Uses **NSGA-II**, a multi-objective evolutionary algorithm, to handle **multiple performance concerns**. + +Reference: Singh, Ravjot et al. *"Optimizing the performance-related configurations of object-relational mapping frameworks using a multi-objective genetic algorithm."* ACM/SPEC ICPE 2016. + +** 2. Architecture and Setup + +- Focuses exclusively on **binary configuration options**. +- Example of a configuration: `{0011}` – a binary vector where each bit represents a configuration toggle (on/off). +- Evaluates performance using three objective metrics: + - **Execution time** + - **CPU load** + - **Memory consumption** +- Other components follow the standard NSGA-II flow: selection, crossover, mutation, and fitness evaluation. + +** 3. Stopping Criteria + +Two specific stopping rules are proposed for determining when to terminate the evolutionary process: + +*** a. Setting 1: t-test-based Stopping + +- Conducts statistical **t-tests** to compare changes in objective values between generations. +- For each pair of consecutive generations \( g_i \) and \( g_j \): + - Run a t-test on ∆CPU and ∆MEM between all configurations in both generations. +- If **all p-values > 0.05** for **two consecutive generations**, it indicates **no statistically significant improvement**, and the algorithm is stopped. + +*** b. Setting 2: Mutual Dominance Rate (MDR) + +- Measures how much progress is made by comparing the current and previous generation. +- Let: + - Set A = configurations from the previous generation + - Set B = configurations from the current generation +- Define \( dom(A,B) \) as the number of configurations in A that are **dominated** by any configuration in B. + +Interpretation: +- **MDR = 0**: No progress — performance plateau +- **MDR < 0**: Regression — performance is deteriorating +- **MDR > 0**: Improvement — current generation is better than the last + +** 4. Termination Condition + +- The tuning process should stop if **any** of the defined stopping conditions (t-test or MDR) are met. + +** 5. Experimental Results + +- NSGA-II consistently found configurations that ranked within the **top 25%** of all possible configurations across tested applications. +- Results were obtained by combining different **aggregation functions** and **stopping rules**, demonstrating strong generalization and effectiveness. + + +* 5.2 Model-Free Tuning with BestConfig - Intelligent Software Engineering + +** 1. Introduction and Background + +- BestConfig is a model-free configuration tuning system proposed by **Zhu et al. (2017)**. +- It focuses on tuning for **a single performance objective** (e.g., throughput, latency). +- Utilizes **local search techniques** rather than global evolutionary approaches. +- Employs **label encoding** for parameters (e.g., {0, 23, 100}). +- Key strategy: aggressively explore **promising regions** of the configuration space. + +Reference: Zhu, Yuqing et al. *"BestConfig: tapping the performance potential of systems via automatic configuration tuning."* SoCC 2017. + +** 2. Architecture Overview + +- BestConfig is designed to intelligently search a high-dimensional configuration space. +- Architecture relies on two core components: + - DDS (Divide & Diverge Sampling) + - RBS (Recursive Bound & Search) + +** 3. DDS: Divide & Diverge Sampling + +- Purpose: Ensures **coverage** of the entire configuration space by dividing it into **subspaces**. +- Process: + 1. Each configuration parameter's range is divided into **k intervals**. + 2. These intervals are combined across all parameters, forming \( k^n \) subspaces. + 3. **One random sample** is taken from each subspace. + +- Advantages: + - Avoids bias in sampling (common in uniform random search). + - More likely to sample from all areas of the space. + - Especially useful in **high-dimensional spaces**. + +** 4. RBS: Recursive Bound & Search + +- Purpose: Locally refines and improves the best-known configuration. +- Steps: + 1. Identify the best-performing configuration \( C_0 \) from the initial samples. + 2. Define **bounds** for each parameter based on neighboring values around \( C_0 \). + 3. Sample new points within this bounded space to find a better configuration \( C_1 \). + 4. Repeat the bounding and sampling process **recursively** until no improvement is found. + +- Bound Definition: + - For each parameter value in \( C_0 \), the closest lower and higher values in the dataset are chosen as bounds. + +- Termination Conditions: + - If no better configuration is found in a recursive round, the search **restarts from a broader space**. + - The entire tuning process **stops** only when a **predefined resource budget** (e.g., time, evaluations) is exhausted. + +** 5. Results and Observations + +- BestConfig consistently finds configurations **significantly better than the system’s default settings**. +- Achieves these improvements within a **reasonable time frame**, making it practical for real-world use. + diff --git a/20250331201944-ise_week_5.org~ b/20250331201944-ise_week_5.org~ new file mode 100644 index 0000000..24dedc2 --- /dev/null +++ b/20250331201944-ise_week_5.org~ @@ -0,0 +1,117 @@ +:PROPERTIES: +:ID: 0e70c535-b145-42d9-a9ed-fe48cddbb1a5 +:END: +#+title: ise-week-5 +#+filetags: :uni:ise:notes: + +* TODO Model free Tuning (for ORM) (pages 9-17) +* TODO Model free Tuning (BestConfig) (pages 18-23) + + +* 5.1 Model-Free Tuning for ORM Systems - Intelligent Software Engineering + +** 1. Introduction and Background + +- This approach was proposed by Singh et al. (2016). +- The goal is to optimize Object-Relational Mapping (ORM) systems without relying on models. +- Uses **NSGA-II**, a multi-objective evolutionary algorithm, to handle **multiple performance concerns**. + +Reference: Singh, Ravjot et al. *"Optimizing the performance-related configurations of object-relational mapping frameworks using a multi-objective genetic algorithm."* ACM/SPEC ICPE 2016. + +** 2. Architecture and Setup + +- Focuses exclusively on **binary configuration options**. +- Example of a configuration: `{0011}` – a binary vector where each bit represents a configuration toggle (on/off). +- Evaluates performance using three objective metrics: + - **Execution time** + - **CPU load** + - **Memory consumption** +- Other components follow the standard NSGA-II flow: selection, crossover, mutation, and fitness evaluation. + +** 3. Stopping Criteria + +Two specific stopping rules are proposed for determining when to terminate the evolutionary process: + +*** a. Setting 1: t-test-based Stopping + +- Conducts statistical **t-tests** to compare changes in objective values between generations. +- For each pair of consecutive generations \( g_i \) and \( g_j \): + - Run a t-test on ∆CPU and ∆MEM between all configurations in both generations. +- If **all p-values > 0.05** for **two consecutive generations**, it indicates **no statistically significant improvement**, and the algorithm is stopped. + +*** b. Setting 2: Mutual Dominance Rate (MDR) + +- Measures how much progress is made by comparing the current and previous generation. +- Let: + - Set A = configurations from the previous generation + - Set B = configurations from the current generation +- Define \( dom(A,B) \) as the number of configurations in A that are **dominated** by any configuration in B. + +Interpretation: +- **MDR = 0**: No progress — performance plateau +- **MDR < 0**: Regression — performance is deteriorating +- **MDR > 0**: Improvement — current generation is better than the last + +** 4. Termination Condition + +- The tuning process should stop if **any** of the defined stopping conditions (t-test or MDR) are met. + +** 5. Experimental Results + +- NSGA-II consistently found configurations that ranked within the **top 25%** of all possible configurations across tested applications. +- Results were obtained by combining different **aggregation functions** and **stopping rules**, demonstrating strong generalization and effectiveness. + + +* 5.2 Model-Free Tuning with BestConfig - Intelligent Software Engineering + +** 1. Introduction and Background + +- BestConfig is a model-free configuration tuning system proposed by **Zhu et al. (2017)**. +- It focuses on tuning for **a single performance objective** (e.g., throughput, latency). +- Utilizes **local search techniques** rather than global evolutionary approaches. +- Employs **label encoding** for parameters (e.g., {0, 23, 100}). +- Key strategy: aggressively explore **promising regions** of the configuration space. + +Reference: Zhu, Yuqing et al. *"BestConfig: tapping the performance potential of systems via automatic configuration tuning."* SoCC 2017. + +** 2. Architecture Overview + +- BestConfig is designed to intelligently search a high-dimensional configuration space. +- Architecture relies on two core components: + - DDS (Divide & Diverge Sampling) + - RBS (Recursive Bound & Search) + +** 3. DDS: Divide & Diverge Sampling + +- Purpose: Ensures **coverage** of the entire configuration space by dividing it into **subspaces**. +- Process: + 1. Each configuration parameter's range is divided into **k intervals**. + 2. These intervals are combined across all parameters, forming \( k^n \) subspaces. + 3. **One random sample** is taken from each subspace. + +- Advantages: + - Avoids bias in sampling (common in uniform random search). + - More likely to sample from all areas of the space. + - Especially useful in **high-dimensional spaces**. + +** 4. RBS: Recursive Bound & Search + +- Purpose: Locally refines and improves the best-known configuration. +- Steps: + 1. Identify the best-performing configuration \( C_0 \) from the initial samples. + 2. Define **bounds** for each parameter based on neighboring values around \( C_0 \). + 3. Sample new points within this bounded space to find a better configuration \( C_1 \). + 4. Repeat the bounding and sampling process **recursively** until no improvement is found. + +- Bound Definition: + - For each parameter value in \( C_0 \), the closest lower and higher values in the dataset are chosen as bounds. + +- Termination Conditions: + - If no better configuration is found in a recursive round, the search **restarts from a broader space**. + - The entire tuning process **stops** only when a **predefined resource budget** (e.g., time, evaluations) is exhausted. + +** 5. Results and Observations + +- BestConfig consistently finds configurations **significantly better than the system’s default settings**. +- Achieves these improvements within a **reasonable time frame**, making it practical for real-world use. + diff --git a/20250331202447-ise_week_7.org b/20250331202447-ise_week_7.org new file mode 100644 index 0000000..4a38ddf --- /dev/null +++ b/20250331202447-ise_week_7.org @@ -0,0 +1,134 @@ +:PROPERTIES: +:ID: 9ad3f3f1-55f7-4114-bc8c-17250b6dd25d +:END: +#+title: ise_week_7 +#+filetags: :uni:notes: + +* DONE Statistical Test Selection and Use (pages 21-67) + +* 7.1 Comparing Algorithms in Intelligent Software Engineering + +** 1. Motivation + +- Algorithms and configurations vary in performance. +- No universally best algorithm: performance depends on the specific problem ("No Free Lunch" theorem). +- To determine which algorithm/configuration is suitable, **comparison is essential**. +- However, comparison is challenging due to the **stochastic nature** of computational intelligence algorithms. + +** 2. Stochastic Behaviour in Algorithms + +- Sources of randomness: + - In the algorithm (e.g., random initial population, stochastic gradient descent, mutation/crossover probabilities). + - In data sampling. +- Result: Running the same algorithm multiple times on the same problem yields **different results**. +- Therefore, comparisons must account for this randomness. + +** 3. Handling Stochastic Behaviour + +- To compare algorithms meaningfully: + - Run each algorithm **multiple times** (e.g., 30+ runs) using **different random seeds**. + - This helps capture typical performance and reduce reliance on single-run outliers. + +** 4. Methods for Comparison + +*** a. Mean (Average) + +- Simple and common. +- Problems: + - Sensitive to **outliers**. + - Does not represent **variability** in results. + +*** b. Mean + Standard Deviation + +- Adds information about variation. +- Still affected by outliers. +- Hard to tell whether differences are statistically significant. + +*** c. Median + +- More robust to outliers. +- Example: + - Sorted list: 0.000001, 0.6, 0.62, 0.65, 0.7, 0.75, 0.8, 0.8, 0.81 + - Median = 0.7 +- Problem: Ignores **variation** in data. + +*** d. Median + Quartiles + +- 1st and 3rd quartiles provide information about data spread. +- Still doesn't guarantee ability to distinguish between groups. + +*** e. Statistical Hypothesis Testing + +- Scientific method to determine if observed differences are **statistically significant**. +- Necessary for robust and credible comparison of algorithms. + +** 5. Statistical Hypothesis Testing: Process + +1. Define what to compare (e.g., accuracy or fitness). +2. Ensure fair comparison: + - Equal number of evaluations or explain why not. + - Example: Adjust generations to equate computational budget across algorithms. +3. Formulate hypotheses: + - **Null hypothesis (H₀)**: No difference between the two groups. + - **Alternative hypothesis (H₁)**: A statistically significant difference exists. +4. Select an appropriate test based on data distribution. + +** 6. Choosing the Test + +*** a. Normality Assumption + +- Many statistical tests assume a **normal distribution** of values. +- Visual inspection or tests (e.g., Shapiro-Wilk) can check this. + +*** b. Parametric vs Non-parametric Tests + +- Parametric tests (e.g., t-test): + - More powerful. + - Require assumptions (e.g., normality, homogeneity of variance). +- Non-parametric tests (e.g., Wilcoxon, Mann-Whitney): + - Safer for non-normal data. + - Widely used in stochastic algorithm comparisons. + +*** c. Paired vs Unpaired Tests + +- **Paired**: Use when comparing results from same initial conditions. +- **Unpaired**: Use when runs are completely independent. + +** 7. Test Outputs + +- Test produces a **statistic** and a **p-value**. + - If **p ≤ 0.05**, reject H₀: significant difference exists. + - If **p > 0.05**, do not reject H₀: no significant difference found. +- Significance level is usually set to **0.05**, corresponding to 95% confidence. +- Lower significance (e.g., 0.01) may be used in critical applications. + +** 8. Interpreting P-Values + +- High p-value → Observed difference likely due to chance → **Do not reject H₀**. +- Low p-value → Observed difference unlikely due to chance → **Reject H₀**. + +** 9. Test Examples (in R) + +- Two-tailed Wilcoxon Rank-Sum Test (unpaired). +- Two-tailed Wilcoxon Signed-Rank Test (paired). + +** 10. Multiple Comparisons Problem + +- Comparing many algorithms or configurations increases the risk of **Type I errors** (false positives). +- Correction methods: + - Adjust the significance threshold (e.g., Bonferroni correction). + - Downside: Conservative → **reduced power** (risk of missing real differences). + +** 11. Tests for N Groups + +- Stronger than multiple pairwise tests with correction. +- Common tests: + - **Kruskal-Wallis Test**: for unpaired comparisons across groups. + - **Friedman Test**: for paired comparisons across groups. + +*** Post-hoc Analysis + +- Needed when the global test finds significant differences but doesn't specify **which pairs** differ. + - Kruskal-Wallis → Dunn post-hoc test. + - Friedman → Nemenyi post-hoc test. + diff --git a/20250331202447-ise_week_7.org~ b/20250331202447-ise_week_7.org~ new file mode 100644 index 0000000..108ac7b --- /dev/null +++ b/20250331202447-ise_week_7.org~ @@ -0,0 +1,134 @@ +:PROPERTIES: +:ID: 9ad3f3f1-55f7-4114-bc8c-17250b6dd25d +:END: +#+title: ise-week-7 +#+filetags: :uni:ise:notes: + +* TODO Statistical Test Selection and Use (pages 21-67) + +* 7.1 Comparing Algorithms in Intelligent Software Engineering + +** 1. Motivation + +- Algorithms and configurations vary in performance. +- No universally best algorithm: performance depends on the specific problem ("No Free Lunch" theorem). +- To determine which algorithm/configuration is suitable, **comparison is essential**. +- However, comparison is challenging due to the **stochastic nature** of computational intelligence algorithms. + +** 2. Stochastic Behaviour in Algorithms + +- Sources of randomness: + - In the algorithm (e.g., random initial population, stochastic gradient descent, mutation/crossover probabilities). + - In data sampling. +- Result: Running the same algorithm multiple times on the same problem yields **different results**. +- Therefore, comparisons must account for this randomness. + +** 3. Handling Stochastic Behaviour + +- To compare algorithms meaningfully: + - Run each algorithm **multiple times** (e.g., 30+ runs) using **different random seeds**. + - This helps capture typical performance and reduce reliance on single-run outliers. + +** 4. Methods for Comparison + +*** a. Mean (Average) + +- Simple and common. +- Problems: + - Sensitive to **outliers**. + - Does not represent **variability** in results. + +*** b. Mean + Standard Deviation + +- Adds information about variation. +- Still affected by outliers. +- Hard to tell whether differences are statistically significant. + +*** c. Median + +- More robust to outliers. +- Example: + - Sorted list: 0.000001, 0.6, 0.62, 0.65, 0.7, 0.75, 0.8, 0.8, 0.81 + - Median = 0.7 +- Problem: Ignores **variation** in data. + +*** d. Median + Quartiles + +- 1st and 3rd quartiles provide information about data spread. +- Still doesn't guarantee ability to distinguish between groups. + +*** e. Statistical Hypothesis Testing + +- Scientific method to determine if observed differences are **statistically significant**. +- Necessary for robust and credible comparison of algorithms. + +** 5. Statistical Hypothesis Testing: Process + +1. Define what to compare (e.g., accuracy or fitness). +2. Ensure fair comparison: + - Equal number of evaluations or explain why not. + - Example: Adjust generations to equate computational budget across algorithms. +3. Formulate hypotheses: + - **Null hypothesis (H₀)**: No difference between the two groups. + - **Alternative hypothesis (H₁)**: A statistically significant difference exists. +4. Select an appropriate test based on data distribution. + +** 6. Choosing the Test + +*** a. Normality Assumption + +- Many statistical tests assume a **normal distribution** of values. +- Visual inspection or tests (e.g., Shapiro-Wilk) can check this. + +*** b. Parametric vs Non-parametric Tests + +- Parametric tests (e.g., t-test): + - More powerful. + - Require assumptions (e.g., normality, homogeneity of variance). +- Non-parametric tests (e.g., Wilcoxon, Mann-Whitney): + - Safer for non-normal data. + - Widely used in stochastic algorithm comparisons. + +*** c. Paired vs Unpaired Tests + +- **Paired**: Use when comparing results from same initial conditions. +- **Unpaired**: Use when runs are completely independent. + +** 7. Test Outputs + +- Test produces a **statistic** and a **p-value**. + - If **p ≤ 0.05**, reject H₀: significant difference exists. + - If **p > 0.05**, do not reject H₀: no significant difference found. +- Significance level is usually set to **0.05**, corresponding to 95% confidence. +- Lower significance (e.g., 0.01) may be used in critical applications. + +** 8. Interpreting P-Values + +- High p-value → Observed difference likely due to chance → **Do not reject H₀**. +- Low p-value → Observed difference unlikely due to chance → **Reject H₀**. + +** 9. Test Examples (in R) + +- Two-tailed Wilcoxon Rank-Sum Test (unpaired). +- Two-tailed Wilcoxon Signed-Rank Test (paired). + +** 10. Multiple Comparisons Problem + +- Comparing many algorithms or configurations increases the risk of **Type I errors** (false positives). +- Correction methods: + - Adjust the significance threshold (e.g., Bonferroni correction). + - Downside: Conservative → **reduced power** (risk of missing real differences). + +** 11. Tests for N Groups + +- Stronger than multiple pairwise tests with correction. +- Common tests: + - **Kruskal-Wallis Test**: for unpaired comparisons across groups. + - **Friedman Test**: for paired comparisons across groups. + +*** Post-hoc Analysis + +- Needed when the global test finds significant differences but doesn't specify **which pairs** differ. + - Kruskal-Wallis → Dunn post-hoc test. + - Friedman → Nemenyi post-hoc test. + diff --git a/20250402185735-java_moc.org b/20250402185735-java_moc.org new file mode 100644 index 0000000..431117a --- /dev/null +++ b/20250402185735-java_moc.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: ae343652-96fe-4341-8a36-ec3a1abd0dc6 +:END: +#+title: java_moc +#+filetags: :moc:java: + +Use this node for pom.xml: [[id:bcd41e87-120c-455c-8898-996ddaa41f75][maven-pom-file]] + +Tests: [[id:7b8de14c-a73e-4c92-a403-a9a1c419c0b3][java-junit-testing]] diff --git a/20250402185735-technical_java_notes.org b/20250402185735-technical_java_notes.org new file mode 100644 index 0000000..431117a --- /dev/null +++ b/20250402185735-technical_java_notes.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: ae343652-96fe-4341-8a36-ec3a1abd0dc6 +:END: +#+title: java_moc +#+filetags: :moc:java: + +Use this node for pom.xml: [[id:bcd41e87-120c-455c-8898-996ddaa41f75][maven-pom-file]] + +Tests: [[id:7b8de14c-a73e-4c92-a403-a9a1c419c0b3][java-junit-testing]] diff --git a/20250402185735-technical_java_notes.org~ b/20250402185735-technical_java_notes.org~ new file mode 100644 index 0000000..40cebaf --- /dev/null +++ b/20250402185735-technical_java_notes.org~ @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: ae343652-96fe-4341-8a36-ec3a1abd0dc6 +:END: +#+title: Java Notes +#+filetags: :index:java:notes: + +[[id:5cfd7f6f-f5ac-4f18-90f9-be9a31dd238e][java-portswrigger-test]] + +Use this node for pom.xml: [[id:bcd41e87-120c-455c-8898-996ddaa41f75][maven-pom-file]] + +Tests: [[id:7b8de14c-a73e-4c92-a403-a9a1c419c0b3][java-junit-testing]] diff --git a/20250403120140-fyp_report_planning.org b/20250403120140-fyp_report_planning.org new file mode 100644 index 0000000..46b3e29 --- /dev/null +++ b/20250403120140-fyp_report_planning.org @@ -0,0 +1,213 @@ +:PROPERTIES: +:ID: 26b2ed9a-cb81-4c43-bc63-6b3c8ffa3bf1 +:END: +#+title: fyp-report-planning +#+filetags: :uni: + +1. Title Page + + Title: "AI-Assisted Note-Taking Web Application" + + Your Name + + Supervisor's Name + + Institution/Department + + Date + + + +2. Abstract + + A concise summary of the project (150–250 words). + + Highlight the problem, solution, methods, and results. + + + + + +3. Table of Contents + + Include all headings and subheadings with page numbers. + + + +4. Introduction + + 4.1 Background: Explain the context of note-taking and its challenges. + + 4.2 Problem Statement: Describe the specific problem you aim to solve (e.g., information overload, accessibility). + + 4.3 Objectives: Define the goals of your project. + + 4.4 Scope: Clearly state the boundaries of the project. + + 4.5 Dissertation Structure: Briefly outline the contents of each section. + + + +5. Literature Review + + 5.1 Existing Solutions: Review existing tools for note-taking, their advantages, and limitations. + + 5.2 Related Research: Explore research on AI, NLP, and note-taking technologies. + + 5.3 Gaps in the Literature: Identify areas not addressed by current solutions, justifying the need for your project. + + + +6. Methodology + + 6.1 Problem Analysis: Define the user requirements and personas. + + 6.2 Proposed Solution: Describe your AI-assisted note-taking solution conceptually. + + 6.3 Technology Stack: Outline the tools, frameworks, APIs, and databases you plan to use. + + 6.4 System Architecture: Include diagrams for the client-server architecture and system workflow. + + 6.5 Data Handling: Describe how the AI will process input data (e.g., text, audio) and produce outputs. + + + +7. Implementation + + 7.1 Development Process: Document how you built the system (e.g., Agile methodology). + + 7.2 Features: Detail key features, such as AI-powered summarization, search functionality, or collaboration tools. + + 7.3 Challenges: Discuss technical challenges and how you addressed them. + + + +8. Evaluation + + 8.1 Testing: Describe how you tested the application (e.g., user testing, performance metrics). + + 8.2 Results: Present quantitative and qualitative results, including user feedback and performance benchmarks. + + 8.3 Analysis: Critically analyze the results and their implications. + + + +9. Discussion + + 9.1 Contributions: Highlight the unique aspects of your solution. + + 9.2 Limitations: Address any shortcomings in your system. + + 9.3 Future Work: Suggest possible enhancements and future research directions. + + + +10. Conclusion + + Summarize the problem, solution, and key findings. + + Reiterate the impact of your work and its importance. + + + +11. References + + List all the sources cited in the document using a consistent citation style (e.g., APA, IEEE, Harvard). + + + +12. Appendices + + Include any additional materials, such as: + + Code snippets + + User manuals + + Detailed testing data + + Wireframes or UI designs + +* intro +# Introduction + +## 1.1 Background + +The digital era has revolutionized the way people consume and manage information. With the proliferation of online content, academic resources, and professional documentation, individuals are constantly processing vast amounts of data. Note-taking, a fundamental cognitive tool for organizing knowledge, has evolved from traditional pen-and-paper methods to digital platforms that offer increased accessibility, storage, and retrieval capabilities. Despite these advancements, users still face challenges such as information overload, inefficient retrieval, and lack of contextual understanding. + +Artificial Intelligence (AI) and Natural Language Processing (NLP) have emerged as transformative technologies in optimizing information management. AI-powered note-taking applications can enhance the process by automatically summarizing content, organizing notes, and enabling intelligent search functionalities. By leveraging machine learning techniques, these systems can provide a personalized and efficient approach to note-taking, reducing cognitive load and improving productivity. + +## 1.2 Problem Statement + +While digital note-taking applications exist, most rely on manual input and basic text organization without leveraging AI to enhance usability. Users often struggle with the sheer volume of notes, leading to difficulties in retrieving relevant information quickly. Traditional search mechanisms lack semantic understanding, making it challenging to locate specific insights. Additionally, manually summarizing large amounts of text is time-consuming and inefficient. There is a growing need for a system that can intelligently process, categorize, and retrieve notes in an intuitive manner. + +## 1.3 Objectives + +This project aims to develop an AI-assisted note-taking web application that enhances knowledge management through NLP and machine learning. The primary objectives include: + +- **Automated Summarization**: Implement AI-powered summarization to extract key points from lengthy notes. +- **Intelligent Search**: Develop a smart search function that understands context and retrieves relevant information efficiently. +- **Automated Tagging and Organization**: Utilize AI to categorize and label notes for easy navigation. +- **Speech-to-Text Integration**: Enable users to convert spoken content into structured notes. +- **User-Friendly Interface**: Design an intuitive UI/UX for seamless interaction and accessibility. + +## 1.4 Scope + +This project focuses on developing a web-based AI-assisted note-taking application with core functionalities such as summarization, intelligent search, and speech-to-text conversion. The system will leverage NLP models and machine learning techniques to process textual data effectively. However, the project does not aim to develop a fully autonomous AI capable of understanding handwritten notes or processing multimedia inputs such as images and videos. Future enhancements may incorporate these aspects. + +## 1.5 Dissertation Structure + +This dissertation is structured as follows: + +- **Chapter 2: Literature Review** – Discusses existing note-taking solutions, AI applications in knowledge management, and identifies gaps in the literature. +- **Chapter 3: Methodology** – Outlines the technical approach, system architecture, and technologies used in developing the application. +- **Chapter 4: Implementation** – Details the development process, features, and challenges encountered. +- **Chapter 5: Evaluation** – Presents testing methodologies, results, and user feedback. +- **Chapter 6: Discussion** – Analyzes contributions, limitations, and potential future work. +- **Chapter 7: Conclusion** – Summarizes findings and the impact of the research. + +By addressing the challenges of digital note-taking with AI, this project aims to provide an innovative solution that enhances productivity and information management. + +* intor 2 +Absolutely! Here's a draft of the **Introduction** section for your dissertation titled **"AI-Assisted Note-Taking Web Application"**. This version reflects a strong academic tone and addresses all required subheadings (4.1–4.5). Feel free to tweak any specific names or phrases to better match your own work: + +--- + +## 4. Introduction + +### 4.1 Background + +Note-taking plays a fundamental role in both academic and professional contexts, serving as a critical tool for learning, information retention, and productivity. Traditional methods of note-taking, whether handwritten or digital, often rely heavily on user input, which can be cognitively demanding, time-consuming, and inconsistent across users. In the age of digital information, individuals are increasingly overwhelmed by the volume and complexity of content encountered during lectures, meetings, or research. This has led to growing concerns about cognitive overload, especially when users must process, organize, and retrieve large quantities of data manually. + +With the advancement of Artificial Intelligence (AI) and Natural Language Processing (NLP), there is a growing potential to revolutionize the way notes are captured, organized, and utilized. By leveraging machine learning algorithms, semantic understanding, and contextual summarization, AI can assist users in real-time or post-session to generate coherent and concise notes. However, the integration of such technologies into practical, user-friendly applications remains an ongoing challenge. + +### 4.2 Problem Statement + +Despite the availability of numerous note-taking tools, many fail to address critical user pain points such as cognitive overload, poor summarization, lack of personalization, and limited accessibility. Students, professionals, and individuals with neurodivergent needs may find it especially difficult to engage with existing solutions that require constant manual interaction. There remains a significant gap in tools that can intelligently process raw input (e.g., text or speech), summarize key points, and provide structured, searchable output that adapts to the user’s workflow. This project aims to bridge that gap by developing an AI-assisted web application that automates and enhances the note-taking process. + +### 4.3 Objectives + +The primary objectives of this dissertation project are: + +- To design and implement a web-based note-taking application that integrates AI capabilities for summarization and organization. +- To explore the use of NLP and machine learning techniques for processing text-based inputs. +- To improve accessibility and reduce cognitive load for users by automating key aspects of the note-taking process. +- To evaluate the effectiveness and usability of the system through user feedback and performance metrics. + +### 4.4 Scope + +This project focuses on the development of a prototype web application tailored to textual note input, though the underlying architecture may be extended to support audio input in future iterations. The system will include core features such as AI-powered summarization, keyword extraction, and searchable note archives. It will be built using Angular for the frontend, Spring Boot for the backend, and PostgreSQL for data storage. OpenAI’s API will be utilized to integrate advanced language processing capabilities. While the project does not aim to develop novel NLP models, it will focus on the integration and optimization of existing tools to deliver a practical, user-centric solution. + +### 4.5 Dissertation Structure + +This dissertation is structured as follows: +- **Chapter 5: Literature Review** examines current note-taking tools, relevant AI technologies, and identifies gaps that justify this project. +- **Chapter 6: Methodology** describes the user research, system design, technology stack, and system architecture. +- **Chapter 7: Implementation** details the development process, key features, and technical challenges faced during the build. +- **Chapter 8: Evaluation** outlines the testing methods used and presents results with analysis. +- **Chapter 9: Discussion** reflects on the project’s contributions, limitations, and potential directions for future work. +- **Chapter 10: Conclusion** summarizes the project and reiterates its significance. + +--- + +Would you like help tailoring this to reflect specific design decisions you've already made, like how your AI summarizer works or your user testing process? diff --git a/20250403120140-fyp_report_planning.org~ b/20250403120140-fyp_report_planning.org~ new file mode 100644 index 0000000..d277856 --- /dev/null +++ b/20250403120140-fyp_report_planning.org~ @@ -0,0 +1,213 @@ +:PROPERTIES: +:ID: 26b2ed9a-cb81-4c43-bc63-6b3c8ffa3bf1 +:END: +#+title: fyp-report-planning +#+filetags: :uni:fyp: + +1. Title Page + + Title: "AI-Assisted Note-Taking Web Application" + + Your Name + + Supervisor's Name + + Institution/Department + + Date + + + +2. Abstract + + A concise summary of the project (150–250 words). + + Highlight the problem, solution, methods, and results. + + + + + +3. Table of Contents + + Include all headings and subheadings with page numbers. + + + +4. Introduction + + 4.1 Background: Explain the context of note-taking and its challenges. + + 4.2 Problem Statement: Describe the specific problem you aim to solve (e.g., information overload, accessibility). + + 4.3 Objectives: Define the goals of your project. + + 4.4 Scope: Clearly state the boundaries of the project. + + 4.5 Dissertation Structure: Briefly outline the contents of each section. + + + +5. Literature Review + + 5.1 Existing Solutions: Review existing tools for note-taking, their advantages, and limitations. + + 5.2 Related Research: Explore research on AI, NLP, and note-taking technologies. + + 5.3 Gaps in the Literature: Identify areas not addressed by current solutions, justifying the need for your project. + + + +6. Methodology + + 6.1 Problem Analysis: Define the user requirements and personas. + + 6.2 Proposed Solution: Describe your AI-assisted note-taking solution conceptually. + + 6.3 Technology Stack: Outline the tools, frameworks, APIs, and databases you plan to use. + + 6.4 System Architecture: Include diagrams for the client-server architecture and system workflow. + + 6.5 Data Handling: Describe how the AI will process input data (e.g., text, audio) and produce outputs. + + + +7. Implementation + + 7.1 Development Process: Document how you built the system (e.g., Agile methodology). + + 7.2 Features: Detail key features, such as AI-powered summarization, search functionality, or collaboration tools. + + 7.3 Challenges: Discuss technical challenges and how you addressed them. + + + +8. Evaluation + + 8.1 Testing: Describe how you tested the application (e.g., user testing, performance metrics). + + 8.2 Results: Present quantitative and qualitative results, including user feedback and performance benchmarks. + + 8.3 Analysis: Critically analyze the results and their implications. + + + +9. Discussion + + 9.1 Contributions: Highlight the unique aspects of your solution. + + 9.2 Limitations: Address any shortcomings in your system. + + 9.3 Future Work: Suggest possible enhancements and future research directions. + + + +10. Conclusion + + Summarize the problem, solution, and key findings. + + Reiterate the impact of your work and its importance. + + + +11. References + + List all the sources cited in the document using a consistent citation style (e.g., APA, IEEE, Harvard). + + + +12. Appendices + + Include any additional materials, such as: + + Code snippets + + User manuals + + Detailed testing data + + Wireframes or UI designs + +* intro +# Introduction + +## 1.1 Background + +The digital era has revolutionized the way people consume and manage information. With the proliferation of online content, academic resources, and professional documentation, individuals are constantly processing vast amounts of data. Note-taking, a fundamental cognitive tool for organizing knowledge, has evolved from traditional pen-and-paper methods to digital platforms that offer increased accessibility, storage, and retrieval capabilities. Despite these advancements, users still face challenges such as information overload, inefficient retrieval, and lack of contextual understanding. + +Artificial Intelligence (AI) and Natural Language Processing (NLP) have emerged as transformative technologies in optimizing information management. AI-powered note-taking applications can enhance the process by automatically summarizing content, organizing notes, and enabling intelligent search functionalities. By leveraging machine learning techniques, these systems can provide a personalized and efficient approach to note-taking, reducing cognitive load and improving productivity. + +## 1.2 Problem Statement + +While digital note-taking applications exist, most rely on manual input and basic text organization without leveraging AI to enhance usability. Users often struggle with the sheer volume of notes, leading to difficulties in retrieving relevant information quickly. Traditional search mechanisms lack semantic understanding, making it challenging to locate specific insights. Additionally, manually summarizing large amounts of text is time-consuming and inefficient. There is a growing need for a system that can intelligently process, categorize, and retrieve notes in an intuitive manner. + +## 1.3 Objectives + +This project aims to develop an AI-assisted note-taking web application that enhances knowledge management through NLP and machine learning. The primary objectives include: + +- **Automated Summarization**: Implement AI-powered summarization to extract key points from lengthy notes. +- **Intelligent Search**: Develop a smart search function that understands context and retrieves relevant information efficiently. +- **Automated Tagging and Organization**: Utilize AI to categorize and label notes for easy navigation. +- **Speech-to-Text Integration**: Enable users to convert spoken content into structured notes. +- **User-Friendly Interface**: Design an intuitive UI/UX for seamless interaction and accessibility. + +## 1.4 Scope + +This project focuses on developing a web-based AI-assisted note-taking application with core functionalities such as summarization, intelligent search, and speech-to-text conversion. The system will leverage NLP models and machine learning techniques to process textual data effectively. However, the project does not aim to develop a fully autonomous AI capable of understanding handwritten notes or processing multimedia inputs such as images and videos. Future enhancements may incorporate these aspects. + +## 1.5 Dissertation Structure + +This dissertation is structured as follows: + +- **Chapter 2: Literature Review** – Discusses existing note-taking solutions, AI applications in knowledge management, and identifies gaps in the literature. +- **Chapter 3: Methodology** – Outlines the technical approach, system architecture, and technologies used in developing the application. +- **Chapter 4: Implementation** – Details the development process, features, and challenges encountered. +- **Chapter 5: Evaluation** – Presents testing methodologies, results, and user feedback. +- **Chapter 6: Discussion** – Analyzes contributions, limitations, and potential future work. +- **Chapter 7: Conclusion** – Summarizes findings and the impact of the research. + +By addressing the challenges of digital note-taking with AI, this project aims to provide an innovative solution that enhances productivity and information management. + +* intor 2 +Absolutely! Here's a draft of the **Introduction** section for your dissertation titled **"AI-Assisted Note-Taking Web Application"**. This version reflects a strong academic tone and addresses all required subheadings (4.1–4.5). Feel free to tweak any specific names or phrases to better match your own work: + +--- + +## 4. Introduction + +### 4.1 Background + +Note-taking plays a fundamental role in both academic and professional contexts, serving as a critical tool for learning, information retention, and productivity. Traditional methods of note-taking, whether handwritten or digital, often rely heavily on user input, which can be cognitively demanding, time-consuming, and inconsistent across users. In the age of digital information, individuals are increasingly overwhelmed by the volume and complexity of content encountered during lectures, meetings, or research. This has led to growing concerns about cognitive overload, especially when users must process, organize, and retrieve large quantities of data manually. + +With the advancement of Artificial Intelligence (AI) and Natural Language Processing (NLP), there is a growing potential to revolutionize the way notes are captured, organized, and utilized. By leveraging machine learning algorithms, semantic understanding, and contextual summarization, AI can assist users in real-time or post-session to generate coherent and concise notes. However, the integration of such technologies into practical, user-friendly applications remains an ongoing challenge. + +### 4.2 Problem Statement + +Despite the availability of numerous note-taking tools, many fail to address critical user pain points such as cognitive overload, poor summarization, lack of personalization, and limited accessibility. Students, professionals, and individuals with neurodivergent needs may find it especially difficult to engage with existing solutions that require constant manual interaction. There remains a significant gap in tools that can intelligently process raw input (e.g., text or speech), summarize key points, and provide structured, searchable output that adapts to the user’s workflow. This project aims to bridge that gap by developing an AI-assisted web application that automates and enhances the note-taking process. + +### 4.3 Objectives + +The primary objectives of this dissertation project are: + +- To design and implement a web-based note-taking application that integrates AI capabilities for summarization and organization. +- To explore the use of NLP and machine learning techniques for processing text-based inputs. +- To improve accessibility and reduce cognitive load for users by automating key aspects of the note-taking process. +- To evaluate the effectiveness and usability of the system through user feedback and performance metrics. + +### 4.4 Scope + +This project focuses on the development of a prototype web application tailored to textual note input, though the underlying architecture may be extended to support audio input in future iterations. The system will include core features such as AI-powered summarization, keyword extraction, and searchable note archives. It will be built using Angular for the frontend, Spring Boot for the backend, and PostgreSQL for data storage. OpenAI’s API will be utilized to integrate advanced language processing capabilities. While the project does not aim to develop novel NLP models, it will focus on the integration and optimization of existing tools to deliver a practical, user-centric solution. + +### 4.5 Dissertation Structure + +This dissertation is structured as follows: +- **Chapter 5: Literature Review** examines current note-taking tools, relevant AI technologies, and identifies gaps that justify this project. +- **Chapter 6: Methodology** describes the user research, system design, technology stack, and system architecture. +- **Chapter 7: Implementation** details the development process, key features, and technical challenges faced during the build. +- **Chapter 8: Evaluation** outlines the testing methods used and presents results with analysis. +- **Chapter 9: Discussion** reflects on the project’s contributions, limitations, and potential directions for future work. +- **Chapter 10: Conclusion** summarizes the project and reiterates its significance. + +--- + +Would you like help tailoring this to reflect specific design decisions you've already made, like how your AI summarizer works or your user testing process? diff --git a/20250412234351-wp_sadness.org b/20250412234351-wp_sadness.org new file mode 100644 index 0000000..b8823b7 --- /dev/null +++ b/20250412234351-wp_sadness.org @@ -0,0 +1,16 @@ +:PROPERTIES: +:ID: 462F091B-9156-48B3-8665-0BE36C95C182 +:END: +#+title: wp-sadness +#+filetags: :zzq:blogs: + +Emotions. We all feel them on a daily basis. Happiness, anger, sadness, fear and disgust. They come and they go, sometimes for a long duration, and at other times merely for a few seconds. Sadness in particular is an interesting emotion; I say this for two reasons: the first is that it reminds us of what matters to us, and the second is that it makes you realise things about yourself that you never knew of before. Sadness is something that honestly makes you step out of your own body and view things in a different light, you become more perceptive despite the phyiscal and mental tang you feel. Should we strive to stop feeling sad? Who knows, some may say it's a part of who we are, others may counter and say that it's not a desired emotion. Regardless, we all have felt it at some point in our lives; the quantity of which varies across people, for some, it could be very minute and for some very large. + +> "Some psychologists argue that sadness plays an evolutionary role—it slows us down, forces us to think, to reflect, to re-evaluate our priorities. It’s the brain’s way of making us pause, take stock, and reorient ourselves." + +There comes that word: *pause*. How important is it to sometimes just pause and reflect, to ponder over life and the things happening around us. When was the last time we sat in silence with no distractions, no phones, no people, nothing. We learn a lot when we tune in to our emotions, despite how much sadness may heart, and how much it makes us want to cry, we should always remember that this same sadness adds value to the happy moments in life. Like shadows on a painting, it gives dimension to our emotional world. + +It reminds me of this verse in the noble Quran: فَإِنَّ مَعَ ٱلْعُسْرِ يُسْرًا which means: "So, surely with hardship comes ease." The hardship we face in life always has a positive aspect to it, sometimes we become too blinded and short sighted by the trials and tribulations that we forget to look at it from another angle. + +Anyways I'll end this with this poetic touch: +> "Sadness doesn’t shout. It whispers. It sits beside you in silence. It tugs at your sleeve when the world moves too fast. And in that quiet tug, you find pieces of yourself you forgot existed." diff --git a/20250412234351-wp_sadness.org~ b/20250412234351-wp_sadness.org~ new file mode 100644 index 0000000..11a9fde --- /dev/null +++ b/20250412234351-wp_sadness.org~ @@ -0,0 +1,15 @@ +:PROPERTIES: +:ID: 462F091B-9156-48B3-8665-0BE36C95C182 +:END: +#+title: wp-sadness + +Emotions. We all feel them on a daily basis. Happiness, anger, sadness, fear and disgust. They come and they go, sometimes for a long duration, and at other times merely for a few seconds. Sadness in particular is an interesting emotion; I say this for two reasons: the first is that it reminds us of what matters to us, and the second is that it makes you realise things about yourself that you never knew of before. Sadness is something that honestly makes you step out of your own body and view things in a different light, you become more perceptive despite the phyiscal and mental tang you feel. Should we strive to stop feeling sad? Who knows, some may say it's a part of who we are, others may counter and say that it's not a desired emotion. Regardless, we all have felt it at some point in our lives; the quantity of which varies across people, for some, it could be very minute and for some very large. + +> "Some psychologists argue that sadness plays an evolutionary role—it slows us down, forces us to think, to reflect, to re-evaluate our priorities. It’s the brain’s way of making us pause, take stock, and reorient ourselves." + +There comes that word: *pause*. How important is it to sometimes just pause and reflect, to ponder over life and the things happening around us. When was the last time we sat in silence with no distractions, no phones, no people, nothing. We learn a lot when we tune in to our emotions, despite how much sadness may heart, and how much it makes us want to cry, we should always remember that this same sadness adds value to the happy moments in life. Like shadows on a painting, it gives dimension to our emotional world. + +It reminds me of this verse in the noble Quran: فَإِنَّ مَعَ ٱلْعُسْرِ يُسْرًا which means: "So, surely with hardship comes ease." The hardship we face in life always has a positive aspect to it, sometimes we become too blinded and short sighted by the trials and tribulations that we forget to look at it from another angle. + +Anyways I'll end this with this poetic touch: +> "Sadness doesn’t shout. It whispers. It sits beside you in silence. It tugs at your sleeve when the world moves too fast. And in that quiet tug, you find pieces of yourself you forgot existed." diff --git a/20250417173809-linux_moc.org b/20250417173809-linux_moc.org new file mode 100644 index 0000000..97fd272 --- /dev/null +++ b/20250417173809-linux_moc.org @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: bdb493df-db92-4c93-9558-0b10fdff3048 +:END: +#+title: linux_moc +#+filetags: :index:linux: + +- [[id:7612a9a6-ae70-4525-93a0-81bac857df39][wacom-notes]] +- [[id:bf277242-4f09-46a2-aa6b-1d75ce0025ac][systemd_services]] +- [[id:30c28e5e-0b1c-43ae-b3bd-eb31023f8b73][gpg-encryption]] +- [[id:569a4a57-1843-4821-8259-17762855985e][linux-arch-linux]] +- [[id:9d5aae0f-4ae1-49a5-a047-9099baad0a06][i3-wm]] diff --git a/20250417173809-linux_stuff.org b/20250417173809-linux_stuff.org new file mode 100644 index 0000000..c970c65 --- /dev/null +++ b/20250417173809-linux_stuff.org @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: bdb493df-db92-4c93-9558-0b10fdff3048 +:END: +#+title: linux_moc +#+filetags: :linux:moc: + +- [[id:7612a9a6-ae70-4525-93a0-81bac857df39][wacom-notes]] +- [[id:bf277242-4f09-46a2-aa6b-1d75ce0025ac][systemd_services]] +- [[id:30c28e5e-0b1c-43ae-b3bd-eb31023f8b73][gpg-encryption]] +- [[id:569a4a57-1843-4821-8259-17762855985e][linux-arch-linux]] +- [[id:9d5aae0f-4ae1-49a5-a047-9099baad0a06][i3-wm]] +- [[id:0217f537-442a-4593-8c69-d481f0d1f2a8][keyboard]] diff --git a/20250417173809-linux_stuff.org~ b/20250417173809-linux_stuff.org~ new file mode 100644 index 0000000..d503d25 --- /dev/null +++ b/20250417173809-linux_stuff.org~ @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: bdb493df-db92-4c93-9558-0b10fdff3048 +:END: +#+title: linux_moc +#+filetags: :linux:moc: + +- [[id:7612a9a6-ae70-4525-93a0-81bac857df39][wacom-notes]] +- [[id:bf277242-4f09-46a2-aa6b-1d75ce0025ac][systemd_services]] +- [[id:30c28e5e-0b1c-43ae-b3bd-eb31023f8b73][gpg-encryption]] +- [[id:569a4a57-1843-4821-8259-17762855985e][linux-arch-linux]] +- [[id:9d5aae0f-4ae1-49a5-a047-9099baad0a06][i3-wm]] diff --git a/20250417173821-wacom_notes.org b/20250417173821-wacom_notes.org new file mode 100644 index 0000000..c496e17 --- /dev/null +++ b/20250417173821-wacom_notes.org @@ -0,0 +1,50 @@ +:PROPERTIES: +:ID: 7612a9a6-ae70-4525-93a0-81bac857df39 +:END: +#+title: wacom-notes +#+filetags: :hardware:linux:wacom: + +The command: `xsetwacom --list` gave me: + +Wacom One by Wacom M Pen stylus id: 12 type: STYLUS +Wacom One by Wacom M Pen eraser id: 13 type: ERASER + +Then, in order to map the stylus to a single monitor i needed to know my monitor mappings via `xrandr`: + +Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767 +DP-0 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 600mm x 340mm + 1920x1080 60.00*+ 143.85 119.98 59.94 + 1680x1050 59.95 + 1440x900 59.89 + 1440x576 50.00 + 1440x480 59.94 + 1280x1024 75.02 60.02 + 1280x960 60.00 + 1280x720 60.00 59.94 + 1152x864 75.00 + 1024x768 75.03 70.07 60.00 + 800x600 75.00 72.19 60.32 56.25 + 720x480 59.94 + 640x480 75.00 72.81 59.94 59.93 +DP-1 disconnected (normal left inverted right x axis y axis) +HDMI-0 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 521mm x 293mm + 1920x1080 60.00*+ 59.94 50.00 + 1680x1050 59.95 + 1600x900 60.00 + 1440x900 59.89 + 1280x1024 60.02 + 1280x800 59.81 + 1280x720 60.00 59.94 50.00 + 1024x768 70.07 60.00 + 800x600 72.19 60.32 56.25 + 720x576 50.00 + 720x480 59.94 + 640x480 72.81 59.94 +DP-2 disconnected (normal left inverted right x axis y axis) +DP-3 disconnected (normal left inverted right x axis y axis) +DP-4 disconnected (normal left inverted right x axis y axis) +DP-5 disconnected (normal left inverted right x axis y axis) + +Then I simply map it via: + +`xsetwacom set "Wacom One by Wacom M Pen stylus" MapToOutput HEAD-0` diff --git a/20250417173821-wacom_notes.org~ b/20250417173821-wacom_notes.org~ new file mode 100644 index 0000000..031abd9 --- /dev/null +++ b/20250417173821-wacom_notes.org~ @@ -0,0 +1,50 @@ +:PROPERTIES: +:ID: 7612a9a6-ae70-4525-93a0-81bac857df39 +:END: +#+title: wacom-notes +#+filetags: :guide:linux:wacom: + +The command: `xsetwacom --list` gave me: + +Wacom One by Wacom M Pen stylus id: 12 type: STYLUS +Wacom One by Wacom M Pen eraser id: 13 type: ERASER + +Then, in order to map the stylus to a single monitor i needed to know my monitor mappings via `xrandr`: + +Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767 +DP-0 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 600mm x 340mm + 1920x1080 60.00*+ 143.85 119.98 59.94 + 1680x1050 59.95 + 1440x900 59.89 + 1440x576 50.00 + 1440x480 59.94 + 1280x1024 75.02 60.02 + 1280x960 60.00 + 1280x720 60.00 59.94 + 1152x864 75.00 + 1024x768 75.03 70.07 60.00 + 800x600 75.00 72.19 60.32 56.25 + 720x480 59.94 + 640x480 75.00 72.81 59.94 59.93 +DP-1 disconnected (normal left inverted right x axis y axis) +HDMI-0 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 521mm x 293mm + 1920x1080 60.00*+ 59.94 50.00 + 1680x1050 59.95 + 1600x900 60.00 + 1440x900 59.89 + 1280x1024 60.02 + 1280x800 59.81 + 1280x720 60.00 59.94 50.00 + 1024x768 70.07 60.00 + 800x600 72.19 60.32 56.25 + 720x576 50.00 + 720x480 59.94 + 640x480 72.81 59.94 +DP-2 disconnected (normal left inverted right x axis y axis) +DP-3 disconnected (normal left inverted right x axis y axis) +DP-4 disconnected (normal left inverted right x axis y axis) +DP-5 disconnected (normal left inverted right x axis y axis) + +Then I simply map it via: + +`xsetwacom set "Wacom One by Wacom M Pen stylus" MapToOutput HEAD-0` diff --git a/20250420012258-emacs_stuff_evil.org b/20250420012258-emacs_stuff_evil.org new file mode 100644 index 0000000..8eb3626 --- /dev/null +++ b/20250420012258-emacs_stuff_evil.org @@ -0,0 +1,35 @@ +:PROPERTIES: +:ID: 45CC3AF5-5E20-4B03-A36C-8D4BDD5CBB13 +:END: +#+title: emacs-stuff-evil +#+filetags: :emacs:guide: + +C-u Cc . - timestamp + +* Keybindings for moving: +** Search +To search use +Then if you want to get the hits, hit enter, then you can use 'n' for next and 'N' for previous hits. +** moving +- To move forward use 'e' and 'E' +- To move forward use 'b' and 'B' +(for beginning and end) +you can also use '{' and '}' for paragraph movement + +- To move to the next line use: 'j' +- To move to the previous line use: 'k' + +** replacement +that is a sample text +- Use 'r' To replace a single letter +- Use 'R' To enter replace mode and use ESC to exit it + +To do a replace all: +- :%s//replacement/g +thats if the '/' has stored the last search, the /g is for all. if you dont use it, itll just replace the first one in each line. you can also use /gc which will prompt for confirmation. + +- :'<,'>s//bar/g +thats if you are in visual mode + +- :s///g +thats a more generic one diff --git a/20250420012258-emacs_stuff_evil.org~ b/20250420012258-emacs_stuff_evil.org~ new file mode 100644 index 0000000..607149c --- /dev/null +++ b/20250420012258-emacs_stuff_evil.org~ @@ -0,0 +1,33 @@ +:PROPERTIES: +:ID: 45CC3AF5-5E20-4B03-A36C-8D4BDD5CBB13 +:END: +#+title: emacs-stuff-evil +#+filetags: :emacs:guide: + +* Keybindings for moving: +** Search +To search use +Then if you want to get the hits, hit enter, then you can use 'n' for next and 'N' for previous hits. +** moving +- To move forward use 'e' and 'E' +- To move forward use 'b' and 'B' +(for beginning and end) +you can also use '{' and '}' for paragraph movement + +- To move to the next line use: 'j' +- To move to the previous line use: 'k' + +** replacement +that is a sample text +- Use 'r' To replace a single letter +- Use 'R' To enter replace mode and use ESC to exit it + +To do a replace all: +- :%s//replacement/g +thats if the '/' has stored the last search, the /g is for all. if you dont use it, itll just replace the first one in each line. you can also use /gc which will prompt for confirmation. + +- :'<,'>s//bar/g +thats if you are in visual mode + +- :s///g +thats a more generic one diff --git a/20250428133236-systemd_services.org b/20250428133236-systemd_services.org new file mode 100644 index 0000000..90a5eb8 --- /dev/null +++ b/20250428133236-systemd_services.org @@ -0,0 +1,44 @@ +:PROPERTIES: +:ID: bf277242-4f09-46a2-aa6b-1d75ce0025ac +:END: +#+title: systemd_services +#+filetags: :linux:systemd: + + +* To add a systemctl + + - create a new systemd service file: + `sudo nano /etc/systemd/system/name.service` + + - example content: + [Unit] + Description=Watch TODO Directory and Update Master Task List + After=network.target + + [Service] + ExecStart=/usr/local/bin/watch-todo.sh + Restart=always + User=zaine + WorkingDirectory=/home/zaine/master-folder/org_files/todo + StandardOutput=append:/var/log/watch-todo.log + StandardError=append:/var/log/watch-todo.log + + [Install] + WantedBy=multi-user.target + + - reload and start: + sudo systemctl daemon-reload + sudo systemctl enable watch-todo.service + sudo systemctl start watch-todo.service + +* To remove a systemctl service: + + systemctl stop [servicename] + systemctl disable [servicename] + rm /etc/systemd/system/[servicename] + rm /etc/systemd/system/[servicename] # and symlinks that might be related + rm /usr/lib/systemd/system/[servicename] + rm /usr/lib/systemd/system/[servicename] # and symlinks that might be related + systemctl daemon-reload + systemctl reset-failed + diff --git a/20250428133236-systemd_services.org~ b/20250428133236-systemd_services.org~ new file mode 100644 index 0000000..64ee0ba --- /dev/null +++ b/20250428133236-systemd_services.org~ @@ -0,0 +1,44 @@ +:PROPERTIES: +:ID: bf277242-4f09-46a2-aa6b-1d75ce0025ac +:END: +#+title: systemd_services +#+filetags: :linux:guide: + + +* To add a systemctl + + - create a new systemd service file: + `sudo nano /etc/systemd/system/name.service` + + - example content: + [Unit] + Description=Watch TODO Directory and Update Master Task List + After=network.target + + [Service] + ExecStart=/usr/local/bin/watch-todo.sh + Restart=always + User=zaine + WorkingDirectory=/home/zaine/master-folder/org_files/todo + StandardOutput=append:/var/log/watch-todo.log + StandardError=append:/var/log/watch-todo.log + + [Install] + WantedBy=multi-user.target + + - reload and start: + sudo systemctl daemon-reload + sudo systemctl enable watch-todo.service + sudo systemctl start watch-todo.service + +* To remove a systemctl service: + + systemctl stop [servicename] + systemctl disable [servicename] + rm /etc/systemd/system/[servicename] + rm /etc/systemd/system/[servicename] # and symlinks that might be related + rm /usr/lib/systemd/system/[servicename] + rm /usr/lib/systemd/system/[servicename] # and symlinks that might be related + systemctl daemon-reload + systemctl reset-failed + diff --git a/20250430001952-microlise_assessment.org b/20250430001952-microlise_assessment.org new file mode 100644 index 0000000..501d2fe --- /dev/null +++ b/20250430001952-microlise_assessment.org @@ -0,0 +1,91 @@ +:PROPERTIES: +:ID: f877240e-c2c8-4087-84e5-4b1ca3fcd4ed +:END: +#+title: microlise-assessment +#+filetags: :interview:assessment: + +1. What are you most proud of doing in the last 2 years? + + + +2. What do you think you could have done better in the last two years? + + + +3. What is the most important thing you have done in the last two years? + + + +4. What books have you read recently? + + Recently, I have been reading The C Programming Language by Brian Kernighan and Dennis Ritchie to better understand low-level programming. I have been reading this book since my second year at university and have learnt many concepts that translate well into higher-level programming languages like Java. I also decided to create a GitHub repository where I store the practical applications of what was learnt from this book in an educational format so that I can share what I learnt as well test my knowledge. + + Another book I have been reading is The Science of Self-Discipline by Peter Hollins. What I took from this book is that despite perpetual distractions we are enveloped with, there are ways we can still remain disciplined. The structuring of the book is quite clever in the sense that it allows the reader to seamlessly flow from the relevant topics that surround the subject of 'self-discipline'. From this book, I got more into the GTD (getting things done) principle and has really helped with managing my to-dos. + + +5. What are the things you like about your role? + + The thing I like most about my current role is the fact that no two days are the same. As my current role is a part-time tutor, I meet students that really challenge me to explain complex concepts in simpler ways. There are many soft skills that I've picked up, such as: communication, time-management, organisation and teamworking skills. + + +6. What annoys you? + + Poor communication from peers and soiled working environments can at times be frustrating. I believe that good and innovative ideas come from open discussions, therefore I value settings where conversations flow in a respectful manner, where people can speak their thoughts and ideas regardless of their seniority. + +7. What would you like to be able to do better? + + I would like to improve my skills in DevOps, specifically the CI/CD and containerisation aspect of this. As I've worked on full-stack applications, my focus was mainly on getting the features deployed, however I want to understand more about deployment, scalability, and infrastructure. To bridge this gap, I began setting up my own homelab that hosts different services through docker-compose. I'm also looking at GitHub actions as I regularly upload to GitHub. + + *add something non-technical* + +8. If we were to ask your manager, how would they describe you? + +They’d describe me as: dependable, empathetic, and always ready to help. Someone who takes initiative in stressful situations, supports others without hesitation, and makes others smile. + + +9. What would your manager say was the best way to manage you? + + Giving me the trust and space to work independently. Being given regular feedback along with constructive performance reviews with what needs to be worked on really helps. + +10. What would your manager say you need to improve on? + + They might say I sometimes take on too much at once. I tend to get enthusiastic about new challenges, however I need to be able to set realistic expectations with both myself and the team through assessing the workload better. + +11. If we asked some of the people that worked with you, to describe you, what would + +they say? + +They'd likely say that I'm approachable, passionate about learning and well-organised. Someone who is easy to get along with and overall jolly. + + +12. If you could change something about your current role, what would it be? + + + +13. Why do you want to move on from your current role? + + + +14. What do you think you will like about this role? + + + +15. What do you think will be difficult about this role? + + + +16. Can you provide an example of where you have gone above and beyond the role to + +achieve a goal? + + + +17. Can you provide an example of where you have provided exceptional internal or + +external customer care? + + + +18. Have you done any charity work, or voluntary work to help others? If not, have you + +examples of where you have helped someone at work? diff --git a/20250430001952-microlise_assessment.org~ b/20250430001952-microlise_assessment.org~ new file mode 100644 index 0000000..8752927 --- /dev/null +++ b/20250430001952-microlise_assessment.org~ @@ -0,0 +1,90 @@ +:PROPERTIES: +:ID: f877240e-c2c8-4087-84e5-4b1ca3fcd4ed +:END: +#+title: microlise-assessment + +1. What are you most proud of doing in the last 2 years? + + + +2. What do you think you could have done better in the last two years? + + + +3. What is the most important thing you have done in the last two years? + + + +4. What books have you read recently? + + Recently, I have been reading The C Programming Language by Brian Kernighan and Dennis Ritchie to better understand low-level programming. I have been reading this book since my second year at university and have learnt many concepts that translate well into higher-level programming languages like Java. I also decided to create a GitHub repository where I store the practical applications of what was learnt from this book in an educational format so that I can share what I learnt as well test my knowledge. + + Another book I have been reading is The Science of Self-Discipline by Peter Hollins. What I took from this book is that despite perpetual distractions we are enveloped with, there are ways we can still remain disciplined. The structuring of the book is quite clever in the sense that it allows the reader to seamlessly flow from the relevant topics that surround the subject of 'self-discipline'. From this book, I got more into the GTD (getting things done) principle and has really helped with managing my to-dos. + + +5. What are the things you like about your role? + + The thing I like most about my current role is the fact that no two days are the same. As my current role is a part-time tutor, I meet students that really challenge me to explain complex concepts in simpler ways. There are many soft skills that I've picked up, such as: communication, time-management, organisation and teamworking skills. + + +6. What annoys you? + + Poor communication from peers and soiled working environments can at times be frustrating. I believe that good and innovative ideas come from open discussions, therefore I value settings where conversations flow in a respectful manner, where people can speak their thoughts and ideas regardless of their seniority. + +7. What would you like to be able to do better? + + I would like to improve my skills in DevOps, specifically the CI/CD and containerisation aspect of this. As I've worked on full-stack applications, my focus was mainly on getting the features deployed, however I want to understand more about deployment, scalability, and infrastructure. To bridge this gap, I began setting up my own homelab that hosts different services through docker-compose. I'm also looking at GitHub actions as I regularly upload to GitHub. + + *add something non-technical* + +8. If we were to ask your manager, how would they describe you? + +They’d describe me as: dependable, empathetic, and always ready to help. Someone who takes initiative in stressful situations, supports others without hesitation, and makes others smile. + + +9. What would your manager say was the best way to manage you? + + Giving me the trust and space to work independently. Being given regular feedback along with constructive performance reviews with what needs to be worked on really helps. + +10. What would your manager say you need to improve on? + + They might say I sometimes take on too much at once. I tend to get enthusiastic about new challenges, however I need to be able to set realistic expectations with both myself and the team through assessing the workload better. + +11. If we asked some of the people that worked with you, to describe you, what would + +they say? + +They'd likely say that I'm approachable, passionate about learning and well-organised. Someone who is easy to get along with and overall jolly. + + +12. If you could change something about your current role, what would it be? + + + +13. Why do you want to move on from your current role? + + + +14. What do you think you will like about this role? + + + +15. What do you think will be difficult about this role? + + + +16. Can you provide an example of where you have gone above and beyond the role to + +achieve a goal? + + + +17. Can you provide an example of where you have provided exceptional internal or + +external customer care? + + + +18. Have you done any charity work, or voluntary work to help others? If not, have you + +examples of where you have helped someone at work? diff --git a/20250516161728-gpg_encryption.org b/20250516161728-gpg_encryption.org new file mode 100644 index 0000000..22bca52 --- /dev/null +++ b/20250516161728-gpg_encryption.org @@ -0,0 +1,35 @@ +:PROPERTIES: +:ID: 30c28e5e-0b1c-43ae-b3bd-eb31023f8b73 +:END: +#+title: gpg-encryption +#+filetags: :linux:security:gpg: + +If you want to encrypt a file, use the following command: + +#+begin_src bash + + gpg -c file.txt + + # options include : + # gpg -c file.txt : for symmetric encryption + # gpg -d file.txt.gpg : to decrypt the file + # gpg --batch -c --passphrase mypassphrase file.txt : accepts passphrase right from command line + +#+end_src + +and to decrypt, use: + +#+begin_src bash + + gpg -d file.txt + + # You have to wait 10 minutes before you can get prompted for a password, before this, it will + # decrypt without the passphrase. + +#+end_src + +gpg --batch -c --passphrase Shakkal123! passwords.md + +gpg --batch -d --passphrase Shakkal123! passwords.md.gpg + +gpg --batch --output passwords.md -d --passphrase Shakkal123! passwords.md.gpg diff --git a/20250516161728-gpg_encryption.org~ b/20250516161728-gpg_encryption.org~ new file mode 100644 index 0000000..e2f916a --- /dev/null +++ b/20250516161728-gpg_encryption.org~ @@ -0,0 +1,34 @@ +:PROPERTIES: +:ID: 30c28e5e-0b1c-43ae-b3bd-eb31023f8b73 +:END: +#+title: gpg-encryption +#+filetags: :linux:security:gpg: + +If you want to encrypt a file, use the following command: + +#+begin_src bash + + gpg -c file.txt + + # options include : + # gpg -c file.txt : for symmetric encryption + # gpg -d file.txt.gpg : to decrypt the file + # gpg --batch -c --passphrase mypassphrase file.txt : accepts passphrase right from command line + +#+end_src + +and to decrypt, use: + +#+begin_src bash + + gpg -d file.txt + + # You have to wait 10 minutes before you can get prompted for a password, before this, it will + # decrypt without the passphrase. + +#+end_src + +gpg --batch -c --passphrase Shakkal123! passwords.md + +gpg --batch -d --passphrase Shakkal123! passwords.md.gpg + diff --git a/20250703183239-linux_arch_linux.org b/20250703183239-linux_arch_linux.org new file mode 100644 index 0000000..630e033 --- /dev/null +++ b/20250703183239-linux_arch_linux.org @@ -0,0 +1,16 @@ +:PROPERTIES: +:ID: 569a4a57-1843-4821-8259-17762855985e +:END: +#+title: linux-arch-linux +#+filetags: :linux:arch: + +* Links: +- https://www.geeksforgeeks.org/how-to-install-intellij-idea-on-arch-based-linux-distributionsmanjaro/ + + +#+begin_src shell + + sudo fuser -k 8000/tcp + +#+end_src + diff --git a/20250703183239-linux_arch_linux.org~ b/20250703183239-linux_arch_linux.org~ new file mode 100644 index 0000000..904695b --- /dev/null +++ b/20250703183239-linux_arch_linux.org~ @@ -0,0 +1,10 @@ +:PROPERTIES: +:ID: 569a4a57-1843-4821-8259-17762855985e +:END: +#+title: linux-arch-linux +#+filetags: :linux:arch: + +* Links: +- https://www.geeksforgeeks.org/how-to-install-intellij-idea-on-arch-based-linux-distributionsmanjaro/ + + diff --git a/20250715223949-the_clean_coder.html b/20250715223949-the_clean_coder.html new file mode 100644 index 0000000..4c1ca7a --- /dev/null +++ b/20250715223949-the_clean_coder.html @@ -0,0 +1,331 @@ + + + + + + + +The-Clean-Coder + + + + + +
+

The-Clean-Coder

+ +
+

1. Chapter 1: PROFESIONALISM

+
+
+
+

1.1. Do no harm

+
+

+No harm should be done to the function of our software. The harm comes about when there are bugs, the QA should find no bugs in the software. If the software is too complex to run without there being bugs, reduce the complexity of the software. Find ways to ensure that the code is designed so that it is easy to test. Aim for 100% test coverage, everything should be tested; automate the testing so you don't waste too much time. +

+
+
+
+

1.2. Do no harm to the structure

+
+

+It is the structure of your code that allows it to be flexible. If you compromise the structure, you compromise the future. If you want the software to be flexible, you have to flex it. This is done by making easy changes to it all the time, which is known as merciless refactoring. +

+
+
+
+

1.3. Work ethic

+
+

+Your career is your responsability and nobody else's. The 40 hours at work should be spent on the employers problems, and the extra 20 hours should be spent reading, practicing, learning, and otherwise enhancing your career. +

+
+
+
+

1.4. Know your field

+
+

+Do you know what a Nassi-Schneiderman chart is? If not, why not? Do you know the difference between a Mealy and a Moore state machine? You should. Could you write a quicksort without looking it up? Do you know what the term “Transform Analysis” means? Could you perform a functional decomposition with Data Flow Diagrams? What does the term “Tramp Data” mean? Have you heard the term “Conascence”? What is a Parnas Table? If you want to be a professional, you should know a sizable chunk of ideas, disciplines, techniques, tools, and terminologies and constantly be increasing the size of that chunk. +

+ +

+Here is a minimal list of the things that every software professional should be conversant with: +• Design patterns. You ought to be able to describe all 24 patterns in the GOF book and have a working knowledge of many of the patterns in the POSA books. +• Design principles. You should know the SOLID principles and have a good understanding of the component principles. +• Methods. You should understand XP, Scrum, Lean, Kanban, Waterfall, Structured Analysis, and Structured Design. +• Disciplines. You should practice TDD, Object-Oriented design, Structured Programming, Continuous Integration, and Pair Programming. +• Artifacts: You should know how to use: UML, DFDs, Structure Charts, Petri Nets, State Transition Diagrams and Tables, flow charts, and decision tables. +

+
+
+
+

1.5. Continuous learning

+
+

+Read books, articles, blogs, tweets. Go to conferences. Go to user groups. Participate in reading and study groups. Learn things that are outside your comfort zone. If you are a .NET programmer, learn Java. If you are a Java programmer, learn Ruby. If you are a C programmer, learn Lisp. If you want to really bend your brain, learn Prolog and Forth! +

+
+
+
+

1.6. Practice

+
+

+Doing your daily job is performance, not practice. Practice is when you specifically exercise your skills outside of the performance of your job for the sole purpose of refining and enhancing those skills. More on this later. +

+
+
+
+

1.7. Collaboration

+
+

+Make a speacial effort to practice, program, plan and design together (not for 100% of your time). +

+
+
+
+

1.8. Mentoring

+
+

+The best way to learn is to teach. +

+
+
+
+

1.9. Know your domain

+
+

+It is the responsibility of every software professional to understand the domain of the solutions they are programming. If you are writing an accounting system, you should know the accounting field. If you are writing a travel application, you should know the travel industry. When starting a project in a new domain, read a book or two on the topic. Interview your customer and users about the foundation and basics of the domain. Spend some time with the experts, and try to understand their principles and values. +

+
+
+
+

1.10. Identify with your Employer/Customer

+
+

+Put yourself in your employer’s shoes and make sure that the features you are developing are really going to address your employer’s needs. +

+
+
+
+

1.11. Humility

+
+

+Professionals know they are arrogant and are not falsely humble. A professional knows his job and takes pride in his work. A professional is confident in his abilities, and takes bold and calculated risks based on that confidence. A professional is not timid. However, a professional also knows that there will be times when he will fail, his risk calculations will be wrong, his abilities will fall short. Be your own critique and never ridicule others, accept ridicule when deserved and laugh it off when it's not. +

+
+
+
+
+
+

Author: Zaine Qayyum

+

Created: 2025-07-16 Wed 21:52

+

Validate

+
+ + diff --git a/20250715223949-the_clean_coder.org b/20250715223949-the_clean_coder.org new file mode 100644 index 0000000..fabfbf3 --- /dev/null +++ b/20250715223949-the_clean_coder.org @@ -0,0 +1,289 @@ +:PROPERTIES: +:ID: EC9D851F-3A2E-4F32-A584-76F6F7A08E30 +:TYPE: Book +:AUTHOR: Robert C. Martin +:DATE_STARTED: <2025-07-15 Tue> +:DATE_ENDED: <2025-07-27 Sun> +:END: +#+title: the_clean_coder +#+filetags: :books: + +* Links: + +[[https://medium.com/@stephanie.manwaring/biggest-takeaways-from-each-chapter-of-the-clean-coder-by-robert-c-martin-5e9d1f5ae34][Medium website]] +[[https://codingjourneyman.com/tag/uncle-bob/page/2/][Coding Journey Man]] + + +* CHAPTER 1: PROFESIONALISM + +** Do no harm +No harm should be done to the function of our software. The harm comes about when there are bugs, the QA should find no bugs in the software. If the software is too complex to run without there being bugs, reduce the complexity of the software. Find ways to ensure that the code is designed so that it is easy to test. Aim for 100% test coverage, everything should be tested; automate the testing so you don't waste too much time. + +** Do no harm to the structure +It is the structure of your code that allows it to be flexible. If you compromise the structure, you compromise the future. If you want the software to be flexible, you have to flex it. This is done by making easy changes to it all the time, which is known as *merciless refactoring*. + +** Work ethic +Your career is your responsability and nobody else's. The 40 hours at work should be spent on the employers problems, and the extra 20 hours should be spent reading, practicing, learning, and otherwise enhancing your career. + +** Know your field +Do you know what a Nassi-Schneiderman chart is? If not, why not? Do you know the difference between a Mealy and a Moore state machine? You should. Could you write a quicksort without looking it up? Do you know what the term “Transform Analysis” means? Could you perform a functional decomposition with Data Flow Diagrams? What does the term “Tramp Data” mean? Have you heard the term “Conascence”? What is a Parnas Table? If you want to be a professional, you should know a sizable chunk of ideas, disciplines, techniques, tools, and terminologies and constantly be increasing the size of that chunk. + +Here is a minimal list of the things that every software professional should be conversant with: +• Design patterns. You ought to be able to describe all 24 patterns in the GOF book and have a working knowledge of many of the patterns in the POSA books. +• Design principles. You should know the SOLID principles and have a good understanding of the component principles. +• Methods. You should understand XP, Scrum, Lean, Kanban, Waterfall, Structured Analysis, and Structured Design. +• Disciplines. You should practice TDD, Object-Oriented design, Structured Programming, Continuous Integration, and Pair Programming. +• Artifacts: You should know how to use: UML, DFDs, Structure Charts, Petri Nets, State Transition Diagrams and Tables, flow charts, and decision tables. + +** Continuous learning +Read books, articles, blogs, tweets. Go to conferences. Go to user groups. Participate in reading and study groups. Learn things that are outside your comfort zone. If you are a .NET programmer, learn Java. If you are a Java programmer, learn Ruby. If you are a C programmer, learn Lisp. If you want to really bend your brain, learn Prolog and Forth! + +** Practice +Doing your daily job is performance, not practice. Practice is when you specifically exercise your skills outside of the performance of your job for the sole purpose of refining and enhancing those skills. More on this later. + +** Collaboration +Make a speacial effort to practice, program, plan and design together (not for 100% of your time). + +** Mentoring +The best way to learn is to teach. + +** Know your domain +It is the responsibility of every software professional to understand the domain of the solutions they are programming. If you are writing an accounting system, you should know the accounting field. If you are writing a travel application, you should know the travel industry. When starting a project in a new domain, read a book or two on the topic. Interview your customer and users about the foundation and basics of the domain. Spend some time with the experts, and try to understand their principles and values. + +** Identify with your Employer/Customer +Put yourself in your employer’s shoes and make sure that the features you are developing are really going to address your employer’s needs. + +** Humility +Professionals know they are arrogant and are not falsely humble. A professional knows his job and takes pride in his work. A professional is confident in his abilities, and takes bold and calculated risks based on that confidence. A professional is not timid. However, a professional also knows that there will be times when he will fail, his risk calculations will be wrong, his abilities will fall short. Be your own critique and never ridicule others, accept ridicule when deserved and laugh it off when it's not. + +* CHAPTER 2: SAYING NO +Professionals are expected to say no. Indeed, good managers crave someone who has the guts to say no. It’s the only way you can really get anything done. (tfb) + +If you are a professional, you will pursue and defend your objectives as aggressively as you can, so will your managers/peers. The best possible outcome is the goal that you and your manager share. The trick is to find that goal, and that usually takes negotiation. + +The most important time to say no is when the stakes are highest. The higher the stakes, the more valuable no becomes. + +Make sure you have documentation (memos) for high stake deliverables/situations (CYA) + +* CHAPTER 3: SAYING YES +Say. Mean. Do. +There are three parts to making a commitment. + +1. You say you’ll do it. +2. You mean it. +3. You actually do it. + +There are certain phrases used by ourselves and our peers that show a lack of commitment. Here are some common phrases: + +• Need\should. “We need to get this done.” “I need to lose weight.” “Someone should make that happen.” +• Hope\wish. “I hope to get this done by tomorrow.” “I hope we can meet again some day.” “I wish I had time for that.” “I wish this computer was faster.” +• Let’s. (not followed by “I . . .”) “Let’s meet sometime.” “Let’s finish this thing.” + +Real commitment will have you stating a fact about something you will do with a clear end time. If you rely on someone else to get your job done, do what you can to get what you need to move forward. Don’t let them be a blocker. + +Professionals are not required to say yes to everything that is asked of them. However, they should work hard to find creative ways to make “yes” possible. + +* CHAPTER 4: CODING +If you are tired or distracted, do not code. You’ll only wind up redoing what you did. Instead, find a way to eliminate the distractions and settle your mind. + +Don’t write code when you are tired. Dedication and professionalism are more about discipline than hours. Make sure that your sleep, health, and lifestyle are tuned so that you can put in eight good hours per day. + +Spend personal time before work trying to resolve or mitigate personal issues or demands so you can focus your mental energy on being a productive problem solver at work. + +Avoid the `flow zone`, rational faculties are diminished in the name of speed. Yes, you may be able to write more code, but you are going to end up giving up the ability to have a holistic view of the problem. You are likely to make decisions that you are going to end up having to go back and reverse. + +Be prepared to be interrupted and help someone — it’s the professional thing to do. When you hit writer’s block make sure you are sleeping, eating, and exercising enough. Additionally, read science fiction (or another form of creative consumption other than surfing the internet or watching TV). Lean on other creative consumption outlets to help keep you creative on the job + +It is incumbent upon you as a professional to reduce your debugging time as close to zero as you can get. Clearly zero is an asymptotic goal, but it is the goal nonetheless. + +Software development is a marathon — not a sprint. Conserve your mental energy during the day. + +“Hope” will get you into trouble (“I hope to have it done by…”). Don’t hope. Be direct about your timelines and realistic expectations. If you must, use an estimate/range. + +Ask for help and ask to give help (mentor). + +Programming is so hard, in fact, that it is beyond the capability of one person to do it well. No matter how skilled you are, you will certainly benefit from another programmer’s thoughts and ideas. + +* CHAPTER 5: TDD + +1. You are not allowed to write any production code until you have first written a failing unit test. +2. You are not allowed to write more of a unit test than is sufficient to fail—and not compiling is failing. +3. You are not allowed to write more production code that is sufficient to pass the currently failing unit test. + +Good tests function like good documentation. +TDD is a discipline that enhances certainty, courage, defect reduction, documentation, and design. +It’s professional to use TDD. + +* CHAPTER 6: PRACTICING + +It is not your employer’s job to keep your skills sharp for you. That responsability is on YOU. + +http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata + +https://codingdojo.org/ + +A programming kata is a precise set of choreographed keystrokes and mouse movements that simulates the solving of some programming problem. You aren’t actually solving the problem because you already know the solution. Rather, you are practicing the movements and decisions involved in solving the problem. + +Many kata are recorded at http://katas.softwarecraftsmanship.org. Others can be found at http://codekata.pragprog.com. Some of my favorites are: + +• The Bowling Game: http://butunclebob.com/ArticleS.UncleBob.TheBowling-GameKata +• Prime Factors: http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactors-Kata +• Word Wrap: http://thecleancoder.blogspot.com/2010/10/craftsman-62-dark-path.html + +For a real challenge, try learning a kata so well that you can set it to music. Doing this well is hard. See: https://katas.softwarecraftsmanship.org/?p=71 + +Programmers can practice in a similar fashion (wasa) using a game known as ping-pong. The two partners choose a kata, or a simple problem. One programmer writes a unit test, and then the other must make it pass. Then they reverse roles. See: https://wiki.c2.com/?PairProgrammingPingPongPattern + +Other ways to practice: take on pro-bono work or a pet project, contribute to open source. Practice is something you do when you aren’t being paid. + +* CHAPTER 7: ACCEPTANCE TESTING +** Intro + +A company spends over **\$1 million every 6 weeks** on manual testing. +They consider cutting half the tests, risking half the product not working. +**Manual test plans are unsustainable**. Automating tests is far cheaper and more reliable. +**Acceptance tests** should be **automated** using tools like: + +FitNesse, Cucumber, Selenium, robot framework, cuke4duke, etc. +These tools make tests **readable and writable by non-programmers**. + +Writing acceptance tests is **not extra work** — it's **how you define what "done" means**. +It ensures that stakeholders and developers are **aligned on requirements**. + +** Who Writes Them and When? + +**Business Analysts (BAs)** often write "happy path" tests. +**QAs** write edge cases and "unhappy paths". +Developers may step in if others can't keep up. +Tests are best written **just before development**, typically during iteration planning. + +** Developers are responsible for: + +**Connecting** acceptance tests to the system. +**Implementing features** to make tests pass. +Negotiating unclear or flawed tests with authors. +Avoid passive-aggressive compliance; collaborate to refine faulty tests. + +** Realistic Expectations (e.g., Timing) + +Not all requirements can be absolute (e.g., "must respond in 2 seconds"). +Use **statistical assertions** (e.g., 99.5% of requests under 2 seconds). +Developers and stakeholders must **agree on testable, realistic criteria**. + +** Acceptance Tests vs Unit Tests + +| Feature | Unit Tests | Acceptance Tests | +| ------------- | -------------------------------- | ---------------------------------------- | +| Written by | Developers | Stakeholders / BAs / QA / Developers | +| Purpose | Specify and verify internal code | Specify and verify business requirements | +| Audience | Developers | Business + Developers | +| Scope | Small units (functions, classes) | Full system (API, UI, etc.) | +| Primary value | Design documentation | Requirements documentation | + +Tests are **not redundant** even if they check similar things — their **execution paths and intent differ**. + +** Testing GUIs + +GUIs are **volatile** (constantly changing), making them hard to test. +Apply **Single Responsibility Principle (SRP)**: + +Separate GUI aesthetics from business logic. +**Test through APIs** beneath the GUI whenever possible. +If GUI testing is necessary, use **IDs or abstractions**, not layout-specific logic. +Keep GUI tests **minimal**, as they’re fragile + +** Continuous Integration (CI) +Run **all tests (unit + acceptance)** multiple times per day via CI. +Trigger builds/tests **on every commit**. +A failed build/test is a **"stop everything" event**. +Never ignore broken tests; doing so can lead to **customer-facing bugs**. + +* CHAPTER 8: TESTING STRATEGIES +Having a full test automation policy is a feature of professional development teams which is not only composed by unit tests and acceptance tests. The test automation pyramid figure (https://codingjourneyman.com/2014/09/24/the-clean-coder-testing-strategies/) show every test types and their proportion. + +Unit tests are written by the programmers for the programmers to ensure that the code is working at the deepest/lowest level. They should execute in milliseconds and target a 100% code coverage (at least 90%). + +Component tests are a part of the acceptance tests and check the behavior of individual component. A component encapsulate a specific set of business rules. These kind of tests should be very quick as well because they are decoupled from the other components and should cover about half the system. + +Integration tests are required to check the communication between components in order to verify that the “plumbing” has been done correctly. They ensure that the architectural structure of the system is correct. About 20% of the system is covered by integration tests. + +System tests are executed at the highest level of the system, from the UI to check the whole application and its construction (load tests are in this category for instance). They check about 10% of the system. + +Manual/exploratory tests are done by humans to explore the application for unexpected behaviors. They need the human creativity to hunt possible hidden bugs. + +* CHAPTER 9: TIME MANAGEMENT +Attending meetings is important in order to follow the life cycle of your project but you are not required in every one of them. In this case you can politely decline the invitation if your presence is not mandatory. It’s no better to be present and play with your smart-phone because you’re bored or because you’re not involved. + +There are also some cases where you can leave a meeting. I know it might look rude to do so but it can happen that a meeting goes not as planned and take much more time that you have anticipated. In a situation like this you can politely ask if your presence is still needed and negotiate your exit. There is nothing worst than a meeting without an agenda and/or without a goal, there is no better way to waste time and energy. + +If you use an Agile methodology such as Scrum at work you certainly have to do stand-up meetings every day (mostly at the beginning of the day). Each member of the team should answer the 3 following questions : + + 1. What did I do yesterday ? + 2. What am I going to do today ? + 3. What’s in my way ? + +And no more, each person should be able to answer these questions in less than one minute. With this short and simple meeting you can easily know if your project is on track or no. + +During an iteration planning meeting a development team select and reject backlog items for the new sprint/iteration. The estimates (our next chapter) should be done for every candidate item and if possible some of the acceptance tests. The chosen tasks should be clear and ready for the development phase (coding) and this meeting aims to allow the team to briefly discuss over the items. + +Iteration retrospective meeting are designed to share what went wrong and what went right during the last iteration and to present demos to the clients/business. It should not extend 45 minutes, 20 for the retrospective and 25 for the demos which are prepared in advance. + +Uncle Bob defines two truths about meetings, finding the correct mix between them for your team can be challenging : + +- Meetings are necessary. +- Meetings are huge time wasters. + +Writing code is an intellectual exercise that requires long periods of concentration and can be exhausting for your mind. But your focus is not infinite and can be depleted, if you are familiar with Role Playing Game (RPG) see this as an empty mana pool. Unfortunately unlike in RPGs you cannot drink a potion to recharge your concentration in a blink but you can refill it. + +Sleeping is the best way to replenish your concentration, a good night of sleep (7~8 hours) can give you enough concentration for an entire day. Coffee is the developer’s best friend and can definitely help you regain a small amount of concentration for a short amount of time but don’t let this beverage send your focus in the wrong direction. + +It’s also possible to partially recharge your mana batteries by taking breaks during your day, it allows you to de-focus. If the weather permits it you can go out for a walk, have a conversation with a friends, even meditate if you want. You can also practice a physical discipline, it also demands concentration but not intellectual focus : muscle focus. This type of focus can help you increase your mental focus and give you mana. Programming is a creative discipline then exposing yourself to other people’s creativity (books, comics, movies, etc…) is also helpful to boost your own creativity. + +When producing code you will sometimes encounter “blind alleys”. It means that the path you’ve taken leads nowhere, in other word your algorithm does not what you want, your solution does not answer your need. It’s impossible to avoid every “blind alleys” but it’s important to realize when you are in one of them to back out. + +What you definitely want to avoid are software “marshes”, “bogs” or “swamps”. Unlike “blind alleys” they don’t stop you, there is always a way forward that looks shorter than the way back but that is not. Sticking to a bad software design is a typical example of a swamp, the more you advance the harder it is to advance and at the end you end up with a colossal “Technical Debt“ without noticing it. It kills a team’s productivity and can sometimes kills and entire project/company because maintenance has become overwhelming. If you discover that you are in a situation like this you should definitely turn back before it’s too late. +* CHAPTER 10: ESTIMATION + You are honor-bound to decline something you cannot commit to. Commitment is about certainty. + Professionals know the difference between estimates and commitments. + Estimates are just guesses. Estimates are ranges (not exact numbers). + Avoid the word “try”. It’s a loaded term. + Something to look into is a method like PERT to get a better estimate. + Professional software developers are very careful to set reasonable expectations despite the pressure to try to go fast. + Estimating methods: wide band delphi, flying fingers, planning poker. + +When you estimate a task, you provide three numbers. This is called trivariate analysis: +• O: Optimistic Estimate. This number is wildly optimistic. You could only get the task done this quickly if absolutely everything went right. Indeed, in order for the math to work this number should have much less than a 1% chance of occurrence. +• N: Nominal Estimate. This is the estimate with the greatest chance of success. If you were to draw a bar chart, it would be the highest bar, +• P: Pessimistic Estimate. Once again this is wildly pessimistic. It should include everything except hurricanes, nuclear war, stray black holes, and other catastrophes. Again, the math only works if this number has much less than a 1% chance of success. + +* CHAPTER 11: PRESSURE + +A professional developer is calm and decisive under pressure. As pressure grows, she adheres to disciplines knowing that they are the best way to meet the deadlines and commitments pressing on her. +Under pressure? Be sure to manage your commitments, follow disciplines, and keep code clean, communicate, and ask for help. + +The best way to stay calm under pressure is to avoid the situations that cause +pressure. That avoidance may not eliminate the pressure completely, but it +can go a long way towards minimizing and shortening the high-pressure +periods. + +* CHAPTER 12: COLLABORATION + Programmers have difficulty working closely with other programmers. That’s no excuse, though. Being a developer means working with people. + The team owns the code, not the individual + Professionals pair (and have good pairing habits). + Pairing is a great way to share knowledge so that people don’t end up in knowledge silos. + All team members should be able to play another team members’ position in a pinch and should know each other’s code. +* CHAPTER 13: TEAMS AND PROJECTS + Strive to have a “gelled” team. A gelled team is one that forms relationships, collaborates, and learn each other’s quirks and strengths. + Gelled teams can work miracles. They plan together, solve together, and get things done. +* CHAPTER 14: MENTORING, APPRENTICESHIP, AND CRAFTSMANSHIP +Developers often start out by teaching themselves (books, trial & error, copying code). + +Without mentorship, they risk missing crucial lessons—like setting expectations, meeting deadlines, and writing maintainable code. + +Good mentors matter: they correct mistakes early, model professionalism, and guide juniors through real-world practices. + +Software lacks true apprenticeships (unlike medicine, plumbing, or carpentry). New devs need hands-on oversight, not just “figure it out” work. + +Professionals should seek mentors and become mentors—help others level up, share best practices, and prevent the cycle of isolated learning. +* APPENDIX A: TOOLING + diff --git a/20250715223949-the_clean_coder.org~ b/20250715223949-the_clean_coder.org~ new file mode 100644 index 0000000..e190b88 --- /dev/null +++ b/20250715223949-the_clean_coder.org~ @@ -0,0 +1,289 @@ +:PROPERTIES: +:ID: EC9D851F-3A2E-4F32-A584-76F6F7A08E30 +:TYPE: Book +:AUTHOR: Robert C. Martin +:DATE_STARTED: <2025-07-15 Tue> +:DATE_ENDED: <2025-07-27 Sun> +:END: +#+title: The Clean Coder +#+filetags: :books: + +* Links: + +[[https://medium.com/@stephanie.manwaring/biggest-takeaways-from-each-chapter-of-the-clean-coder-by-robert-c-martin-5e9d1f5ae34][Medium website]] +[[https://codingjourneyman.com/tag/uncle-bob/page/2/][Coding Journey Man]] + + +* CHAPTER 1: PROFESIONALISM + +** Do no harm +No harm should be done to the function of our software. The harm comes about when there are bugs, the QA should find no bugs in the software. If the software is too complex to run without there being bugs, reduce the complexity of the software. Find ways to ensure that the code is designed so that it is easy to test. Aim for 100% test coverage, everything should be tested; automate the testing so you don't waste too much time. + +** Do no harm to the structure +It is the structure of your code that allows it to be flexible. If you compromise the structure, you compromise the future. If you want the software to be flexible, you have to flex it. This is done by making easy changes to it all the time, which is known as *merciless refactoring*. + +** Work ethic +Your career is your responsability and nobody else's. The 40 hours at work should be spent on the employers problems, and the extra 20 hours should be spent reading, practicing, learning, and otherwise enhancing your career. + +** Know your field +Do you know what a Nassi-Schneiderman chart is? If not, why not? Do you know the difference between a Mealy and a Moore state machine? You should. Could you write a quicksort without looking it up? Do you know what the term “Transform Analysis” means? Could you perform a functional decomposition with Data Flow Diagrams? What does the term “Tramp Data” mean? Have you heard the term “Conascence”? What is a Parnas Table? If you want to be a professional, you should know a sizable chunk of ideas, disciplines, techniques, tools, and terminologies and constantly be increasing the size of that chunk. + +Here is a minimal list of the things that every software professional should be conversant with: +• Design patterns. You ought to be able to describe all 24 patterns in the GOF book and have a working knowledge of many of the patterns in the POSA books. +• Design principles. You should know the SOLID principles and have a good understanding of the component principles. +• Methods. You should understand XP, Scrum, Lean, Kanban, Waterfall, Structured Analysis, and Structured Design. +• Disciplines. You should practice TDD, Object-Oriented design, Structured Programming, Continuous Integration, and Pair Programming. +• Artifacts: You should know how to use: UML, DFDs, Structure Charts, Petri Nets, State Transition Diagrams and Tables, flow charts, and decision tables. + +** Continuous learning +Read books, articles, blogs, tweets. Go to conferences. Go to user groups. Participate in reading and study groups. Learn things that are outside your comfort zone. If you are a .NET programmer, learn Java. If you are a Java programmer, learn Ruby. If you are a C programmer, learn Lisp. If you want to really bend your brain, learn Prolog and Forth! + +** Practice +Doing your daily job is performance, not practice. Practice is when you specifically exercise your skills outside of the performance of your job for the sole purpose of refining and enhancing those skills. More on this later. + +** Collaboration +Make a speacial effort to practice, program, plan and design together (not for 100% of your time). + +** Mentoring +The best way to learn is to teach. + +** Know your domain +It is the responsibility of every software professional to understand the domain of the solutions they are programming. If you are writing an accounting system, you should know the accounting field. If you are writing a travel application, you should know the travel industry. When starting a project in a new domain, read a book or two on the topic. Interview your customer and users about the foundation and basics of the domain. Spend some time with the experts, and try to understand their principles and values. + +** Identify with your Employer/Customer +Put yourself in your employer’s shoes and make sure that the features you are developing are really going to address your employer’s needs. + +** Humility +Professionals know they are arrogant and are not falsely humble. A professional knows his job and takes pride in his work. A professional is confident in his abilities, and takes bold and calculated risks based on that confidence. A professional is not timid. However, a professional also knows that there will be times when he will fail, his risk calculations will be wrong, his abilities will fall short. Be your own critique and never ridicule others, accept ridicule when deserved and laugh it off when it's not. + +* CHAPTER 2: SAYING NO +Professionals are expected to say no. Indeed, good managers crave someone who has the guts to say no. It’s the only way you can really get anything done. (tfb) + +If you are a professional, you will pursue and defend your objectives as aggressively as you can, so will your managers/peers. The best possible outcome is the goal that you and your manager share. The trick is to find that goal, and that usually takes negotiation. + +The most important time to say no is when the stakes are highest. The higher the stakes, the more valuable no becomes. + +Make sure you have documentation (memos) for high stake deliverables/situations (CYA) + +* CHAPTER 3: SAYING YES +Say. Mean. Do. +There are three parts to making a commitment. + +1. You say you’ll do it. +2. You mean it. +3. You actually do it. + +There are certain phrases used by ourselves and our peers that show a lack of commitment. Here are some common phrases: + +• Need\should. “We need to get this done.” “I need to lose weight.” “Someone should make that happen.” +• Hope\wish. “I hope to get this done by tomorrow.” “I hope we can meet again some day.” “I wish I had time for that.” “I wish this computer was faster.” +• Let’s. (not followed by “I . . .”) “Let’s meet sometime.” “Let’s finish this thing.” + +Real commitment will have you stating a fact about something you will do with a clear end time. If you rely on someone else to get your job done, do what you can to get what you need to move forward. Don’t let them be a blocker. + +Professionals are not required to say yes to everything that is asked of them. However, they should work hard to find creative ways to make “yes” possible. + +* CHAPTER 4: CODING +If you are tired or distracted, do not code. You’ll only wind up redoing what you did. Instead, find a way to eliminate the distractions and settle your mind. + +Don’t write code when you are tired. Dedication and professionalism are more about discipline than hours. Make sure that your sleep, health, and lifestyle are tuned so that you can put in eight good hours per day. + +Spend personal time before work trying to resolve or mitigate personal issues or demands so you can focus your mental energy on being a productive problem solver at work. + +Avoid the `flow zone`, rational faculties are diminished in the name of speed. Yes, you may be able to write more code, but you are going to end up giving up the ability to have a holistic view of the problem. You are likely to make decisions that you are going to end up having to go back and reverse. + +Be prepared to be interrupted and help someone — it’s the professional thing to do. When you hit writer’s block make sure you are sleeping, eating, and exercising enough. Additionally, read science fiction (or another form of creative consumption other than surfing the internet or watching TV). Lean on other creative consumption outlets to help keep you creative on the job + +It is incumbent upon you as a professional to reduce your debugging time as close to zero as you can get. Clearly zero is an asymptotic goal, but it is the goal nonetheless. + +Software development is a marathon — not a sprint. Conserve your mental energy during the day. + +“Hope” will get you into trouble (“I hope to have it done by…”). Don’t hope. Be direct about your timelines and realistic expectations. If you must, use an estimate/range. + +Ask for help and ask to give help (mentor). + +Programming is so hard, in fact, that it is beyond the capability of one person to do it well. No matter how skilled you are, you will certainly benefit from another programmer’s thoughts and ideas. + +* CHAPTER 5: TDD + +1. You are not allowed to write any production code until you have first written a failing unit test. +2. You are not allowed to write more of a unit test than is sufficient to fail—and not compiling is failing. +3. You are not allowed to write more production code that is sufficient to pass the currently failing unit test. + +Good tests function like good documentation. +TDD is a discipline that enhances certainty, courage, defect reduction, documentation, and design. +It’s professional to use TDD. + +* CHAPTER 6: PRACTICING + +It is not your employer’s job to keep your skills sharp for you. That responsability is on YOU. + +http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata + +https://codingdojo.org/ + +A programming kata is a precise set of choreographed keystrokes and mouse movements that simulates the solving of some programming problem. You aren’t actually solving the problem because you already know the solution. Rather, you are practicing the movements and decisions involved in solving the problem. + +Many kata are recorded at http://katas.softwarecraftsmanship.org. Others can be found at http://codekata.pragprog.com. Some of my favorites are: + +• The Bowling Game: http://butunclebob.com/ArticleS.UncleBob.TheBowling-GameKata +• Prime Factors: http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactors-Kata +• Word Wrap: http://thecleancoder.blogspot.com/2010/10/craftsman-62-dark-path.html + +For a real challenge, try learning a kata so well that you can set it to music. Doing this well is hard. See: https://katas.softwarecraftsmanship.org/?p=71 + +Programmers can practice in a similar fashion (wasa) using a game known as ping-pong. The two partners choose a kata, or a simple problem. One programmer writes a unit test, and then the other must make it pass. Then they reverse roles. See: https://wiki.c2.com/?PairProgrammingPingPongPattern + +Other ways to practice: take on pro-bono work or a pet project, contribute to open source. Practice is something you do when you aren’t being paid. + +* CHAPTER 7: ACCEPTANCE TESTING +** Intro + +A company spends over **\$1 million every 6 weeks** on manual testing. +They consider cutting half the tests, risking half the product not working. +**Manual test plans are unsustainable**. Automating tests is far cheaper and more reliable. +**Acceptance tests** should be **automated** using tools like: + +FitNesse, Cucumber, Selenium, robot framework, cuke4duke, etc. +These tools make tests **readable and writable by non-programmers**. + +Writing acceptance tests is **not extra work** — it's **how you define what "done" means**. +It ensures that stakeholders and developers are **aligned on requirements**. + +** Who Writes Them and When? + +**Business Analysts (BAs)** often write "happy path" tests. +**QAs** write edge cases and "unhappy paths". +Developers may step in if others can't keep up. +Tests are best written **just before development**, typically during iteration planning. + +** Developers are responsible for: + +**Connecting** acceptance tests to the system. +**Implementing features** to make tests pass. +Negotiating unclear or flawed tests with authors. +Avoid passive-aggressive compliance; collaborate to refine faulty tests. + +** Realistic Expectations (e.g., Timing) + +Not all requirements can be absolute (e.g., "must respond in 2 seconds"). +Use **statistical assertions** (e.g., 99.5% of requests under 2 seconds). +Developers and stakeholders must **agree on testable, realistic criteria**. + +** Acceptance Tests vs Unit Tests + +| Feature | Unit Tests | Acceptance Tests | +| ------------- | -------------------------------- | ---------------------------------------- | +| Written by | Developers | Stakeholders / BAs / QA / Developers | +| Purpose | Specify and verify internal code | Specify and verify business requirements | +| Audience | Developers | Business + Developers | +| Scope | Small units (functions, classes) | Full system (API, UI, etc.) | +| Primary value | Design documentation | Requirements documentation | + +Tests are **not redundant** even if they check similar things — their **execution paths and intent differ**. + +** Testing GUIs + +GUIs are **volatile** (constantly changing), making them hard to test. +Apply **Single Responsibility Principle (SRP)**: + +Separate GUI aesthetics from business logic. +**Test through APIs** beneath the GUI whenever possible. +If GUI testing is necessary, use **IDs or abstractions**, not layout-specific logic. +Keep GUI tests **minimal**, as they’re fragile + +** Continuous Integration (CI) +Run **all tests (unit + acceptance)** multiple times per day via CI. +Trigger builds/tests **on every commit**. +A failed build/test is a **"stop everything" event**. +Never ignore broken tests; doing so can lead to **customer-facing bugs**. + +* CHAPTER 8: TESTING STRATEGIES +Having a full test automation policy is a feature of professional development teams which is not only composed by unit tests and acceptance tests. The test automation pyramid figure (https://codingjourneyman.com/2014/09/24/the-clean-coder-testing-strategies/) show every test types and their proportion. + +Unit tests are written by the programmers for the programmers to ensure that the code is working at the deepest/lowest level. They should execute in milliseconds and target a 100% code coverage (at least 90%). + +Component tests are a part of the acceptance tests and check the behavior of individual component. A component encapsulate a specific set of business rules. These kind of tests should be very quick as well because they are decoupled from the other components and should cover about half the system. + +Integration tests are required to check the communication between components in order to verify that the “plumbing” has been done correctly. They ensure that the architectural structure of the system is correct. About 20% of the system is covered by integration tests. + +System tests are executed at the highest level of the system, from the UI to check the whole application and its construction (load tests are in this category for instance). They check about 10% of the system. + +Manual/exploratory tests are done by humans to explore the application for unexpected behaviors. They need the human creativity to hunt possible hidden bugs. + +* CHAPTER 9: TIME MANAGEMENT +Attending meetings is important in order to follow the life cycle of your project but you are not required in every one of them. In this case you can politely decline the invitation if your presence is not mandatory. It’s no better to be present and play with your smart-phone because you’re bored or because you’re not involved. + +There are also some cases where you can leave a meeting. I know it might look rude to do so but it can happen that a meeting goes not as planned and take much more time that you have anticipated. In a situation like this you can politely ask if your presence is still needed and negotiate your exit. There is nothing worst than a meeting without an agenda and/or without a goal, there is no better way to waste time and energy. + +If you use an Agile methodology such as Scrum at work you certainly have to do stand-up meetings every day (mostly at the beginning of the day). Each member of the team should answer the 3 following questions : + + 1. What did I do yesterday ? + 2. What am I going to do today ? + 3. What’s in my way ? + +And no more, each person should be able to answer these questions in less than one minute. With this short and simple meeting you can easily know if your project is on track or no. + +During an iteration planning meeting a development team select and reject backlog items for the new sprint/iteration. The estimates (our next chapter) should be done for every candidate item and if possible some of the acceptance tests. The chosen tasks should be clear and ready for the development phase (coding) and this meeting aims to allow the team to briefly discuss over the items. + +Iteration retrospective meeting are designed to share what went wrong and what went right during the last iteration and to present demos to the clients/business. It should not extend 45 minutes, 20 for the retrospective and 25 for the demos which are prepared in advance. + +Uncle Bob defines two truths about meetings, finding the correct mix between them for your team can be challenging : + +- Meetings are necessary. +- Meetings are huge time wasters. + +Writing code is an intellectual exercise that requires long periods of concentration and can be exhausting for your mind. But your focus is not infinite and can be depleted, if you are familiar with Role Playing Game (RPG) see this as an empty mana pool. Unfortunately unlike in RPGs you cannot drink a potion to recharge your concentration in a blink but you can refill it. + +Sleeping is the best way to replenish your concentration, a good night of sleep (7~8 hours) can give you enough concentration for an entire day. Coffee is the developer’s best friend and can definitely help you regain a small amount of concentration for a short amount of time but don’t let this beverage send your focus in the wrong direction. + +It’s also possible to partially recharge your mana batteries by taking breaks during your day, it allows you to de-focus. If the weather permits it you can go out for a walk, have a conversation with a friends, even meditate if you want. You can also practice a physical discipline, it also demands concentration but not intellectual focus : muscle focus. This type of focus can help you increase your mental focus and give you mana. Programming is a creative discipline then exposing yourself to other people’s creativity (books, comics, movies, etc…) is also helpful to boost your own creativity. + +When producing code you will sometimes encounter “blind alleys”. It means that the path you’ve taken leads nowhere, in other word your algorithm does not what you want, your solution does not answer your need. It’s impossible to avoid every “blind alleys” but it’s important to realize when you are in one of them to back out. + +What you definitely want to avoid are software “marshes”, “bogs” or “swamps”. Unlike “blind alleys” they don’t stop you, there is always a way forward that looks shorter than the way back but that is not. Sticking to a bad software design is a typical example of a swamp, the more you advance the harder it is to advance and at the end you end up with a colossal “Technical Debt“ without noticing it. It kills a team’s productivity and can sometimes kills and entire project/company because maintenance has become overwhelming. If you discover that you are in a situation like this you should definitely turn back before it’s too late. +* CHAPTER 10: ESTIMATION + You are honor-bound to decline something you cannot commit to. Commitment is about certainty. + Professionals know the difference between estimates and commitments. + Estimates are just guesses. Estimates are ranges (not exact numbers). + Avoid the word “try”. It’s a loaded term. + Something to look into is a method like PERT to get a better estimate. + Professional software developers are very careful to set reasonable expectations despite the pressure to try to go fast. + Estimating methods: wide band delphi, flying fingers, planning poker. + +When you estimate a task, you provide three numbers. This is called trivariate analysis: +• O: Optimistic Estimate. This number is wildly optimistic. You could only get the task done this quickly if absolutely everything went right. Indeed, in order for the math to work this number should have much less than a 1% chance of occurrence. +• N: Nominal Estimate. This is the estimate with the greatest chance of success. If you were to draw a bar chart, it would be the highest bar, +• P: Pessimistic Estimate. Once again this is wildly pessimistic. It should include everything except hurricanes, nuclear war, stray black holes, and other catastrophes. Again, the math only works if this number has much less than a 1% chance of success. + +* CHAPTER 11: PRESSURE + +A professional developer is calm and decisive under pressure. As pressure grows, she adheres to disciplines knowing that they are the best way to meet the deadlines and commitments pressing on her. +Under pressure? Be sure to manage your commitments, follow disciplines, and keep code clean, communicate, and ask for help. + +The best way to stay calm under pressure is to avoid the situations that cause +pressure. That avoidance may not eliminate the pressure completely, but it +can go a long way towards minimizing and shortening the high-pressure +periods. + +* CHAPTER 12: COLLABORATION + Programmers have difficulty working closely with other programmers. That’s no excuse, though. Being a developer means working with people. + The team owns the code, not the individual + Professionals pair (and have good pairing habits). + Pairing is a great way to share knowledge so that people don’t end up in knowledge silos. + All team members should be able to play another team members’ position in a pinch and should know each other’s code. +* CHAPTER 13: TEAMS AND PROJECTS + Strive to have a “gelled” team. A gelled team is one that forms relationships, collaborates, and learn each other’s quirks and strengths. + Gelled teams can work miracles. They plan together, solve together, and get things done. +* CHAPTER 14: MENTORING, APPRENTICESHIP, AND CRAFTSMANSHIP +Developers often start out by teaching themselves (books, trial & error, copying code). + +Without mentorship, they risk missing crucial lessons—like setting expectations, meeting deadlines, and writing maintainable code. + +Good mentors matter: they correct mistakes early, model professionalism, and guide juniors through real-world practices. + +Software lacks true apprenticeships (unlike medicine, plumbing, or carpentry). New devs need hands-on oversight, not just “figure it out” work. + +Professionals should seek mentors and become mentors—help others level up, share best practices, and prevent the cycle of isolated learning. +* APPENDIX A: TOOLING + diff --git a/20250717230336-recipes_main.org b/20250717230336-recipes_main.org new file mode 100644 index 0000000..aec7bc3 --- /dev/null +++ b/20250717230336-recipes_main.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 65F747B1-3CB2-429A-9E26-ED8BC169E689 +:END: +#+title: recipes-moc +#+filetags: :moc:recipes: + +* [[id:F7D68FF4-CAD0-4791-BAE4-AC20B84A8785][recipes-ideas]] + +* [[id:EA93341B-20C0-48A2-BD88-F24ED3C540DA][recipes-done]] diff --git a/20250717230336-recipes_main.org~ b/20250717230336-recipes_main.org~ new file mode 100644 index 0000000..aec7bc3 --- /dev/null +++ b/20250717230336-recipes_main.org~ @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 65F747B1-3CB2-429A-9E26-ED8BC169E689 +:END: +#+title: recipes-moc +#+filetags: :moc:recipes: + +* [[id:F7D68FF4-CAD0-4791-BAE4-AC20B84A8785][recipes-ideas]] + +* [[id:EA93341B-20C0-48A2-BD88-F24ED3C540DA][recipes-done]] diff --git a/20250717230336-recipes_moc.org b/20250717230336-recipes_moc.org new file mode 100644 index 0000000..864dca9 --- /dev/null +++ b/20250717230336-recipes_moc.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 65F747B1-3CB2-429A-9E26-ED8BC169E689 +:END: +#+title: recipes-main +#+filetags: :recipes: + +* [[id:F7D68FF4-CAD0-4791-BAE4-AC20B84A8785][recipes-ideas]] + +* [[id:EA93341B-20C0-48A2-BD88-F24ED3C540DA][recipes-done]] diff --git a/20250719174944-recipes_ideas.org b/20250719174944-recipes_ideas.org new file mode 100644 index 0000000..632b4e3 --- /dev/null +++ b/20250719174944-recipes_ideas.org @@ -0,0 +1,65 @@ +:PROPERTIES: +:ID: F7D68FF4-CAD0-4791-BAE4-AC20B84A8785 +:END: +#+title: recipes-ideas +#+filetags: :recipes:ideas: + +* Spiced Potato & Pea Quesadillas + +Prep time: 20 min +Ingredients: + + Boiled potatoes, mashed + + Frozen peas + + Cumin, coriander, chili flakes + + Tortilla wraps + Method: + + Mix mashed potatoes, peas, and spices. + + Spread mixture on a tortilla, top with another. + + Toast in a pan until crispy on both sides. + +* Chickpea Pilaf + +Prep time: 25 min +Ingredients: + + Cooked rice + + Canned chickpeas + + Onion, garlic, cumin, cinnamon + + Optional: raisins or almonds + Method: + + Sauté onion, garlic, spices. + + Stir in chickpeas, then rice. + + Heat through, serve with yogurt. + +* Lentil Soup with Flatbread + +Prep time: 25 min +Ingredients: + + Red lentils + + Onion, garlic, carrot + + Cumin, turmeric, black pepper + + Vegetable stock + Method: + + Sauté onion, garlic, and carrot. + + Add spices and lentils. Pour in stock. + + Simmer until soft, then blend if preferred. diff --git a/20250719174944-recipes_ideas.org~ b/20250719174944-recipes_ideas.org~ new file mode 100644 index 0000000..6547c52 --- /dev/null +++ b/20250719174944-recipes_ideas.org~ @@ -0,0 +1,64 @@ +:PROPERTIES: +:ID: F7D68FF4-CAD0-4791-BAE4-AC20B84A8785 +:END: +#+title: recipes-ideas + +* Spiced Potato & Pea Quesadillas + +Prep time: 20 min +Ingredients: + + Boiled potatoes, mashed + + Frozen peas + + Cumin, coriander, chili flakes + + Tortilla wraps + Method: + + Mix mashed potatoes, peas, and spices. + + Spread mixture on a tortilla, top with another. + + Toast in a pan until crispy on both sides. + +* Chickpea Pilaf + +Prep time: 25 min +Ingredients: + + Cooked rice + + Canned chickpeas + + Onion, garlic, cumin, cinnamon + + Optional: raisins or almonds + Method: + + Sauté onion, garlic, spices. + + Stir in chickpeas, then rice. + + Heat through, serve with yogurt. + +* Lentil Soup with Flatbread + +Prep time: 25 min +Ingredients: + + Red lentils + + Onion, garlic, carrot + + Cumin, turmeric, black pepper + + Vegetable stock + Method: + + Sauté onion, garlic, and carrot. + + Add spices and lentils. Pour in stock. + + Simmer until soft, then blend if preferred. diff --git a/20250719175023-recipes_done.org b/20250719175023-recipes_done.org new file mode 100644 index 0000000..b24fdf4 --- /dev/null +++ b/20250719175023-recipes_done.org @@ -0,0 +1,29 @@ +:PROPERTIES: +:ID: EA93341B-20C0-48A2-BD88-F24ED3C540DA +:END: +#+title: recipes-done +#+filetags: :recipes:resources: + +* Done: +** <2025-07-17 Thu> +https://spainonafork.com/healthy-creamy-tuna-wraps-recipe/ + +Instead of 1 clove fresh garlic, i used 1/4 teaspoon garlic granules. +Also used lime juice instead of lemon juice +need to work on plating (put too much salad, its better to cut the tomatos in smaller chunks and the salad in smaller pieces) + +** <2025-07-18 Fri> +https://www.youtube.com/watch?v=wiKndVvU_Ks&list=LL&index=2&ab_channel=BrownGirlsKitchen + +Dont use plastic sieve (as boiled water goes on it when extracting the potatos) + +use low heat when toasting the wraps + +served 3 large sized wraps (maybe use taco wraps next time) + +** <2025-07-19 Sat> +https://www.youtube.com/watch?v=3d6DrdOEuY4&list=LL&index=1&ab_channel=FoodFusion + +WASH HANDS AFTER TOUCHING GREEN CHILLI. + +juilienne : cutting the garlic into small strips diff --git a/20250719175023-recipes_done.org~ b/20250719175023-recipes_done.org~ new file mode 100644 index 0000000..4ba5a64 --- /dev/null +++ b/20250719175023-recipes_done.org~ @@ -0,0 +1,29 @@ +:PROPERTIES: +:ID: EA93341B-20C0-48A2-BD88-F24ED3C540DA +:END: +#+title: recipes-done +#+filetags: :recipes:references: + +* Done: +** <2025-07-17 Thu> +https://spainonafork.com/healthy-creamy-tuna-wraps-recipe/ + +Instead of 1 clove fresh garlic, i used 1/4 teaspoon garlic granules. +Also used lime juice instead of lemon juice +need to work on plating (put too much salad, its better to cut the tomatos in smaller chunks and the salad in smaller pieces) + +** <2025-07-18 Fri> +https://www.youtube.com/watch?v=wiKndVvU_Ks&list=LL&index=2&ab_channel=BrownGirlsKitchen + +Dont use plastic sieve (as boiled water goes on it when extracting the potatos) + +use low heat when toasting the wraps + +served 3 large sized wraps (maybe use taco wraps next time) + +** <2025-07-19 Sat> +https://www.youtube.com/watch?v=3d6DrdOEuY4&list=LL&index=1&ab_channel=FoodFusion + +WASH HANDS AFTER TOUCHING GREEN CHILLI. + +juilienne : cutting the garlic into small strips diff --git a/20250722221649-career_index.org~ b/20250722221649-career_index.org~ new file mode 100644 index 0000000..6dcaf66 --- /dev/null +++ b/20250722221649-career_index.org~ @@ -0,0 +1,50 @@ +:PROPERTIES: +:ID: dd04d228-fff5-402a-929d-9d113a2ec965 +:DATE_STARTED: <2025-07-22 Tue> +:END: +#+STARTUP: overview +#+title: Career Index +#+filetags: :index:career: + +* ABOUT: + +* pre-work +- [[id:2729599d-ae2b-4f22-b73d-bf22d81e0767][test-driven-development]] + +* Resources: + +** Books: +*** So Good They Can't Ignore You +Microlise recomended me to read this +**** Book Link: +- [[file:~/master-folder/pdfs/technical/so_good_they_cant_ignore_you.pdf][Book Internal PDF]] +- [[https://zserver.zapto.org/calibre/read/5/pdf][Book External PDF]] + +**** Link to org file: +- [[id:2d7f1ccc-99d7-4c45-8fe7-4b87080edb01][book-sgtciy]] + +*** Clean Coder: +Microlise recomended me to read this +**** Book Link: +- [[file:~/master-folder/pdfs/technical/The Clean Coder.pdf][Book Internal PDF]] +- [[https://zserver.zapto.org/calibre/read/10/pdf][Book External PDF]] + +**** Link to org file: +- [[id:EC9D851F-3A2E-4F32-A584-76F6F7A08E30][book-the-clean-coder]] + +*** The Manager’s Path +A Guide for Tech Leaders Navigating Growth and Change +Link: +[[https://www.amazon.com/Managers-Path-Leaders-Navigating-Growth/dp/1491973897][The Managers Path]] + +*** SICP +Book link: +- [[https://zserver.zapto.org/calibre/read/11/pdf][Online]] +- [[file:/home/zaine/master-folder/pdfs/technical/sicp.pdf][Internal]] + +** Websites: +*** Link to free software blogging course +- [[https://simpleprogrammer.com/my-free-blogging-course-is-getting-unbelievable-results/][Simple Programmer]] + + + diff --git a/20250722221649-career_moc.org b/20250722221649-career_moc.org new file mode 100644 index 0000000..f1b4845 --- /dev/null +++ b/20250722221649-career_moc.org @@ -0,0 +1,52 @@ +:PROPERTIES: +:ID: dd04d228-fff5-402a-929d-9d113a2ec965 +:DATE_STARTED: <2025-07-22 Tue> +:END: +#+STARTUP: overview +#+title: career_moc +#+filetags: :moc:career: + +[[id:ABF4A0BE-0309-48A6-92ED-76031B3D2F86][microlise_moc]] + +* Articles/Blogs: +** TODO https://forge.medium.com/a-simple-tool-for-personal-growth-dc1e822aa229 +:PROPERTIES: +:FOLLOWUP: true +*** Description: + +* pre-work +- [[id:2729599d-ae2b-4f22-b73d-bf22d81e0767][test-driven-development]] +- [[id:f9897f8e-2b63-4ad2-a55f-3787c4ac235f][job_application_cover_letters]] +- [[id:5cfd7f6f-f5ac-4f18-90f9-be9a31dd238e][java-portswrigger-test]] +- [[id:f877240e-c2c8-4087-84e5-4b1ca3fcd4ed][microlise-assessment]] +* Resources: + +** Books: +*** So Good They Can't Ignore You +Microlise recomended me to read this +**** Book Link: +- [[file:~/master-folder/pdfs/technical/so_good_they_cant_ignore_you.pdf][Book Internal PDF]] +- [[https://zserver.zapto.org/calibre/read/5/pdf][Book External PDF]] + +*** Clean Coder: +Microlise recomended me to read this +**** Book Link: +- [[file:~/master-folder/pdfs/technical/The Clean Coder.pdf][Book Internal PDF]] +- [[https://zserver.zapto.org/calibre/read/10/pdf][Book External PDF]] + +*** The Manager’s Path +A Guide for Tech Leaders Navigating Growth and Change +Link: +[[https://www.amazon.com/Managers-Path-Leaders-Navigating-Growth/dp/1491973897][The Managers Path]] + +*** SICP +Book link: +- [[https://zserver.zapto.org/calibre/read/11/pdf][Online]] +- [[file:/home/zaine/master-folder/pdfs/technical/sicp.pdf][Internal]] + +** Websites: +*** Link to free software blogging course +- [[https://simpleprogrammer.com/my-free-blogging-course-is-getting-unbelievable-results/][Simple Programmer]] + + + diff --git a/20250722221649-career_moc.org~ b/20250722221649-career_moc.org~ new file mode 100644 index 0000000..f87e0ad --- /dev/null +++ b/20250722221649-career_moc.org~ @@ -0,0 +1,48 @@ +:PROPERTIES: +:ID: dd04d228-fff5-402a-929d-9d113a2ec965 +:DATE_STARTED: <2025-07-22 Tue> +:END: +#+STARTUP: overview +#+title: career_moc +#+filetags: :moc:career: + +[[id:ABF4A0BE-0309-48A6-92ED-76031B3D2F86][microlise_moc]] + +* ABOUT: + +* pre-work +- [[id:2729599d-ae2b-4f22-b73d-bf22d81e0767][test-driven-development]] +- [[id:f9897f8e-2b63-4ad2-a55f-3787c4ac235f][job_application_cover_letters]] +- [[id:5cfd7f6f-f5ac-4f18-90f9-be9a31dd238e][java-portswrigger-test]] +- [[id:f877240e-c2c8-4087-84e5-4b1ca3fcd4ed][microlise-assessment]] +* Resources: + +** Books: +*** So Good They Can't Ignore You +Microlise recomended me to read this +**** Book Link: +- [[file:~/master-folder/pdfs/technical/so_good_they_cant_ignore_you.pdf][Book Internal PDF]] +- [[https://zserver.zapto.org/calibre/read/5/pdf][Book External PDF]] + +*** Clean Coder: +Microlise recomended me to read this +**** Book Link: +- [[file:~/master-folder/pdfs/technical/The Clean Coder.pdf][Book Internal PDF]] +- [[https://zserver.zapto.org/calibre/read/10/pdf][Book External PDF]] + +*** The Manager’s Path +A Guide for Tech Leaders Navigating Growth and Change +Link: +[[https://www.amazon.com/Managers-Path-Leaders-Navigating-Growth/dp/1491973897][The Managers Path]] + +*** SICP +Book link: +- [[https://zserver.zapto.org/calibre/read/11/pdf][Online]] +- [[file:/home/zaine/master-folder/pdfs/technical/sicp.pdf][Internal]] + +** Websites: +*** Link to free software blogging course +- [[https://simpleprogrammer.com/my-free-blogging-course-is-getting-unbelievable-results/][Simple Programmer]] + + + diff --git a/20250723171109-maven_pom_file.org b/20250723171109-maven_pom_file.org new file mode 100644 index 0000000..1cec340 --- /dev/null +++ b/20250723171109-maven_pom_file.org @@ -0,0 +1,69 @@ +:PROPERTIES: +:ID: bcd41e87-120c-455c-8898-996ddaa41f75 +:END: +#+title: maven-pom-file +#+filetags: :guide:java: + +* Doc Link +- [[https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html][Link to apache doc]] + +* Example of pom.xml +#+begin_src xml + + + 4.0.0 + com.mycompany.app + my-app + 1.0-SNAPSHOT + my-app + + http://www.example.com + + UTF-8 + 17 + + + + + org.junit + junit-bom + 5.11.0 + pom + import + + + + + + org.junit.jupiter + junit-jupiter-api + test + + + + org.junit.jupiter + junit-jupiter-params + test + + + + + ... lots of helpful plugins + + + + + #+end_src + +* Commands: + +*FOR TESTING* +#+begin_src bash + mvn clean test +#+end_src + +*COMPILING* +#+begin_src bash + mvn compile +#+end_src diff --git a/20250723171109-maven_pom_file.org~ b/20250723171109-maven_pom_file.org~ new file mode 100644 index 0000000..6d9cea2 --- /dev/null +++ b/20250723171109-maven_pom_file.org~ @@ -0,0 +1,69 @@ +:PROPERTIES: +:ID: bcd41e87-120c-455c-8898-996ddaa41f75 +:END: +#+title: maven-pom-file +#+filetags: testing, fish + +* Doc Link +- [[https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html][Link to apache doc]] + +* Example of pom.xml +#+begin_src xml + + + 4.0.0 + com.mycompany.app + my-app + 1.0-SNAPSHOT + my-app + + http://www.example.com + + UTF-8 + 17 + + + + + org.junit + junit-bom + 5.11.0 + pom + import + + + + + + org.junit.jupiter + junit-jupiter-api + test + + + + org.junit.jupiter + junit-jupiter-params + test + + + + + ... lots of helpful plugins + + + + + #+end_src + +* Commands: + +*FOR TESTING* +#+begin_src bash + mvn clean test +#+end_src + +*COMPILING* +#+begin_src bash + mvn compile +#+end_src diff --git a/20250723182408-book_sgtciy.org~ b/20250723182408-book_sgtciy.org~ new file mode 100644 index 0000000..9d762e0 --- /dev/null +++ b/20250723182408-book_sgtciy.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: 2d7f1ccc-99d7-4c45-8fe7-4b87080edb01 +:END: +#+title: book-sgtciy + diff --git a/20250723182408-so-good-they-cant-ignore-you.org b/20250723182408-so-good-they-cant-ignore-you.org new file mode 100644 index 0000000..7d7eb41 --- /dev/null +++ b/20250723182408-so-good-they-cant-ignore-you.org @@ -0,0 +1,76 @@ +:PROPERTIES: +:ID: 2d7f1ccc-99d7-4c45-8fe7-4b87080edb01 +:TYPE: Book +:AUTHOR: Cal Newport +:DATE_STARTED: <2025-05-25 Sun> +:DATE_ENDED: <2025-06-15 Sun> +:END: +#+title: so_good_they_cant_ignore_you +#+filetags: :books: + +* So good they cant ignore you +Some of these points have been inspired from this +[[https://jasonkwanhc.medium.com/book-summary-of-so-good-they-cant-ignore-you-58cb236fef0d][website]] + +* Summary + +The book focuses on the reality of how people end up loving what they do. It demystifies the concept: "follow your +passion", and details alternative strategies. + +** Rule *1: **Don’t Follow Your Passion** + +1. The Passion Hypothesis is the biggest myth in occupational happiness. It says that “The key to occupational happiness + is to first figure out what you are passionate about and then find a job that matches this passion”, the author1 + argues against this. +2. He mentions some incidents of people like Steve Jobs, proving that successful people like him (who is famous for the + concept "follow your passions") didn’t start off because he had a passion for the thing they do. + +** Rule *2: Be So Good They Can’t Ignore You (Or, the importance of skills) + +1. The traits that define great work are rare and valuable, if you want these traits, you need rare and valuable skills. + These skills are called *[[id:f9838952-9753-471b-a2cc-d72e01a53ef6][career-capital]]*. +2. Adopt the **Craftsman Mindset** where instead you focus on what you can offer the world. This is in stark contrast to + the **Passion Mindset** where you focus on what the world can offer you. The craftsman mindset focuses on becoming + better and improving the quality of what you produce. It focuses on becoming so good they can’t ignore you, + regardless of what you do for a living. +3. The concept of *[[id:d4f96bfb-b83d-449b-9f74-f602a1a3c2d3][deliberate-practice]]* is mentioned where you deliberately stretch your + abilities beyond where you're comfortable and then receive ruthless feedback on your performance. +4. 5 Steps on applying the deliberate practice in your work: + + 1. **Step 1: Decide What Type of Capital Market You’re Competing In.** There are two kinds of markets, a + *winner-take-all* market and an *auction* market. In a winner-take-all market, there's only one type of career + capital available and only one that matters. In the auction market however, there are a variety of relevant + skills that could *lead* you to getting the job, in other words, there are a variety of career capital available. + 2. **Step 2: Identify Your Capital Type**. This step makes you figure out what are the relevant skills that are + needed in order to be great at your job. In the winner-take-all market, it's pretty straightforward that it's + that one career capital, however in the auction market there's more flexibility. A useful heuristic mentioned is + the *open-gates* opportunities present. In other words, those opportunities to build capital that are already + open to you, then you work your way up. + 3. **Step 3: Define “Good”** . Having a clear view of what *good* means is important. This step forces you to think + about where you want to be and how you can achieve it using deliberate practice. This definition will be + different for different people. + 4. **Step 4: Stretch and Destroy**. Deliberate practice requires you to be uncomfortable, as it is something that is + not enjoyable. The important thing is to push beyond your comfort zone and get immediate feedback to steer you in + the right direction. + 5. **Step 5: Patience**. The acquisition of career capital will take time, therefore, it is necessary to be patient + and ensure that you pour all your effort into the capital you seek. The final sentence given in the book before + the summary is: **You stretch yourself, day after day, month after month, before finally looking up and + realising, "Hey, I've become pretty good, and people are starting to notice".** + +** Rule *3: Turn Down a Promotion (Or, the importance of control) + +1. The author here explains that once you've acquired a certain amount of career capital, your next step is to invest +in those traits that define great work. Discussion was made about control, and the common pitfalls that people fall +into. +2. The law of financial viability: when pursuing a project or career path, it's crucial to seek evidence that people + are willing to pay for it. If that evidence exists, it's a good sign to proceed; if not, it's better to reconsider or pivot. + +** Rule *4: Think Small, Act Big (Or, the importance of Mission) + +1. This rule focuses on the importance of having a mission in your work. Having a unifying focus for your career, a + sense of purpose, can make your work more meaningful and impactful. +2. A good career mission is similar to a scientific breakthrough, discovered in the adjacent possible of your field. + You will need to acquire enough career capital to be able to get into the *cutting edge* of your field. Once you + get into this cutting edge, you can then start to see these missions. +3. Think small, act big. Instead of focusing on a huge experiment with little feedback, focus on small experiments + that yield concrete feedback, and use this to guide you into the direction surrounding your general mission. diff --git a/20250723182408-so-good-they-cant-ignore-you.org~ b/20250723182408-so-good-they-cant-ignore-you.org~ new file mode 100644 index 0000000..172bb4b --- /dev/null +++ b/20250723182408-so-good-they-cant-ignore-you.org~ @@ -0,0 +1,76 @@ +:PROPERTIES: +:ID: 2d7f1ccc-99d7-4c45-8fe7-4b87080edb01 +:TYPE: Book +:AUTHOR: Cal Newport +:DATE_STARTED: <2025-05-25 Sun> +:DATE_ENDED: <2025-06-15 Sun> +:END: +#+title: So good they can't ignore you +#+filetags: :books: + +* So good they cant ignore you +Some of these points have been inspired from this +[[https://jasonkwanhc.medium.com/book-summary-of-so-good-they-cant-ignore-you-58cb236fef0d][website]] + +* Summary + +The book focuses on the reality of how people end up loving what they do. It demystifies the concept: "follow your +passion", and details alternative strategies. + +** Rule *1: **Don’t Follow Your Passion** + +1. The Passion Hypothesis is the biggest myth in occupational happiness. It says that “The key to occupational happiness + is to first figure out what you are passionate about and then find a job that matches this passion”, the author1 + argues against this. +2. He mentions some incidents of people like Steve Jobs, proving that successful people like him (who is famous for the + concept "follow your passions") didn’t start off because he had a passion for the thing they do. + +** Rule *2: Be So Good They Can’t Ignore You (Or, the importance of skills) + +1. The traits that define great work are rare and valuable, if you want these traits, you need rare and valuable skills. + These skills are called *[[id:f9838952-9753-471b-a2cc-d72e01a53ef6][career-capital]]*. +2. Adopt the **Craftsman Mindset** where instead you focus on what you can offer the world. This is in stark contrast to + the **Passion Mindset** where you focus on what the world can offer you. The craftsman mindset focuses on becoming + better and improving the quality of what you produce. It focuses on becoming so good they can’t ignore you, + regardless of what you do for a living. +3. The concept of *[[id:d4f96bfb-b83d-449b-9f74-f602a1a3c2d3][deliberate-practice]]* is mentioned where you deliberately stretch your + abilities beyond where you're comfortable and then receive ruthless feedback on your performance. +4. 5 Steps on applying the deliberate practice in your work: + + 1. **Step 1: Decide What Type of Capital Market You’re Competing In.** There are two kinds of markets, a + *winner-take-all* market and an *auction* market. In a winner-take-all market, there's only one type of career + capital available and only one that matters. In the auction market however, there are a variety of relevant + skills that could *lead* you to getting the job, in other words, there are a variety of career capital available. + 2. **Step 2: Identify Your Capital Type**. This step makes you figure out what are the relevant skills that are + needed in order to be great at your job. In the winner-take-all market, it's pretty straightforward that it's + that one career capital, however in the auction market there's more flexibility. A useful heuristic mentioned is + the *open-gates* opportunities present. In other words, those opportunities to build capital that are already + open to you, then you work your way up. + 3. **Step 3: Define “Good”** . Having a clear view of what *good* means is important. This step forces you to think + about where you want to be and how you can achieve it using deliberate practice. This definition will be + different for different people. + 4. **Step 4: Stretch and Destroy**. Deliberate practice requires you to be uncomfortable, as it is something that is + not enjoyable. The important thing is to push beyond your comfort zone and get immediate feedback to steer you in + the right direction. + 5. **Step 5: Patience**. The acquisition of career capital will take time, therefore, it is necessary to be patient + and ensure that you pour all your effort into the capital you seek. The final sentence given in the book before + the summary is: **You stretch yourself, day after day, month after month, before finally looking up and + realising, "Hey, I've become pretty good, and people are starting to notice".** + +** Rule *3: Turn Down a Promotion (Or, the importance of control) + +1. The author here explains that once you've acquired a certain amount of career capital, your next step is to invest +in those traits that define great work. Discussion was made about control, and the common pitfalls that people fall +into. +2. The law of financial viability: when pursuing a project or career path, it's crucial to seek evidence that people + are willing to pay for it. If that evidence exists, it's a good sign to proceed; if not, it's better to reconsider or pivot. + +** Rule *4: Think Small, Act Big (Or, the importance of Mission) + +1. This rule focuses on the importance of having a mission in your work. Having a unifying focus for your career, a + sense of purpose, can make your work more meaningful and impactful. +2. A good career mission is similar to a scientific breakthrough, discovered in the adjacent possible of your field. + You will need to acquire enough career capital to be able to get into the *cutting edge* of your field. Once you + get into this cutting edge, you can then start to see these missions. +3. Think small, act big. Instead of focusing on a huge experiment with little feedback, focus on small experiments + that yield concrete feedback, and use this to guide you into the direction surrounding your general mission. diff --git a/20250723182408-so_good_they_cant_ignore_you.org b/20250723182408-so_good_they_cant_ignore_you.org new file mode 100644 index 0000000..7d7eb41 --- /dev/null +++ b/20250723182408-so_good_they_cant_ignore_you.org @@ -0,0 +1,76 @@ +:PROPERTIES: +:ID: 2d7f1ccc-99d7-4c45-8fe7-4b87080edb01 +:TYPE: Book +:AUTHOR: Cal Newport +:DATE_STARTED: <2025-05-25 Sun> +:DATE_ENDED: <2025-06-15 Sun> +:END: +#+title: so_good_they_cant_ignore_you +#+filetags: :books: + +* So good they cant ignore you +Some of these points have been inspired from this +[[https://jasonkwanhc.medium.com/book-summary-of-so-good-they-cant-ignore-you-58cb236fef0d][website]] + +* Summary + +The book focuses on the reality of how people end up loving what they do. It demystifies the concept: "follow your +passion", and details alternative strategies. + +** Rule *1: **Don’t Follow Your Passion** + +1. The Passion Hypothesis is the biggest myth in occupational happiness. It says that “The key to occupational happiness + is to first figure out what you are passionate about and then find a job that matches this passion”, the author1 + argues against this. +2. He mentions some incidents of people like Steve Jobs, proving that successful people like him (who is famous for the + concept "follow your passions") didn’t start off because he had a passion for the thing they do. + +** Rule *2: Be So Good They Can’t Ignore You (Or, the importance of skills) + +1. The traits that define great work are rare and valuable, if you want these traits, you need rare and valuable skills. + These skills are called *[[id:f9838952-9753-471b-a2cc-d72e01a53ef6][career-capital]]*. +2. Adopt the **Craftsman Mindset** where instead you focus on what you can offer the world. This is in stark contrast to + the **Passion Mindset** where you focus on what the world can offer you. The craftsman mindset focuses on becoming + better and improving the quality of what you produce. It focuses on becoming so good they can’t ignore you, + regardless of what you do for a living. +3. The concept of *[[id:d4f96bfb-b83d-449b-9f74-f602a1a3c2d3][deliberate-practice]]* is mentioned where you deliberately stretch your + abilities beyond where you're comfortable and then receive ruthless feedback on your performance. +4. 5 Steps on applying the deliberate practice in your work: + + 1. **Step 1: Decide What Type of Capital Market You’re Competing In.** There are two kinds of markets, a + *winner-take-all* market and an *auction* market. In a winner-take-all market, there's only one type of career + capital available and only one that matters. In the auction market however, there are a variety of relevant + skills that could *lead* you to getting the job, in other words, there are a variety of career capital available. + 2. **Step 2: Identify Your Capital Type**. This step makes you figure out what are the relevant skills that are + needed in order to be great at your job. In the winner-take-all market, it's pretty straightforward that it's + that one career capital, however in the auction market there's more flexibility. A useful heuristic mentioned is + the *open-gates* opportunities present. In other words, those opportunities to build capital that are already + open to you, then you work your way up. + 3. **Step 3: Define “Good”** . Having a clear view of what *good* means is important. This step forces you to think + about where you want to be and how you can achieve it using deliberate practice. This definition will be + different for different people. + 4. **Step 4: Stretch and Destroy**. Deliberate practice requires you to be uncomfortable, as it is something that is + not enjoyable. The important thing is to push beyond your comfort zone and get immediate feedback to steer you in + the right direction. + 5. **Step 5: Patience**. The acquisition of career capital will take time, therefore, it is necessary to be patient + and ensure that you pour all your effort into the capital you seek. The final sentence given in the book before + the summary is: **You stretch yourself, day after day, month after month, before finally looking up and + realising, "Hey, I've become pretty good, and people are starting to notice".** + +** Rule *3: Turn Down a Promotion (Or, the importance of control) + +1. The author here explains that once you've acquired a certain amount of career capital, your next step is to invest +in those traits that define great work. Discussion was made about control, and the common pitfalls that people fall +into. +2. The law of financial viability: when pursuing a project or career path, it's crucial to seek evidence that people + are willing to pay for it. If that evidence exists, it's a good sign to proceed; if not, it's better to reconsider or pivot. + +** Rule *4: Think Small, Act Big (Or, the importance of Mission) + +1. This rule focuses on the importance of having a mission in your work. Having a unifying focus for your career, a + sense of purpose, can make your work more meaningful and impactful. +2. A good career mission is similar to a scientific breakthrough, discovered in the adjacent possible of your field. + You will need to acquire enough career capital to be able to get into the *cutting edge* of your field. Once you + get into this cutting edge, you can then start to see these missions. +3. Think small, act big. Instead of focusing on a huge experiment with little feedback, focus on small experiments + that yield concrete feedback, and use this to guide you into the direction surrounding your general mission. diff --git a/20250723183655-career_capital.org b/20250723183655-career_capital.org new file mode 100644 index 0000000..ddcc527 --- /dev/null +++ b/20250723183655-career_capital.org @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: f9838952-9753-471b-a2cc-d72e01a53ef6 +:END: +#+title: career_capital +#+filetags: :definitions: + +Career capital refers to the abilities and resources you accumulate—whether skills, credentials, connections, or +savings—that allow you to do more with your career in the future. It’s an important consideration in long-term career +planning, especially in the early stages of your career. + +Taken from: https://probablygood.org/core-concepts/career-capital/ diff --git a/20250723183655-career_capital.org~ b/20250723183655-career_capital.org~ new file mode 100644 index 0000000..4b9142b --- /dev/null +++ b/20250723183655-career_capital.org~ @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: f9838952-9753-471b-a2cc-d72e01a53ef6 +:END: +#+title: Career capital +#+filetags: :definitions: + +Career capital refers to the abilities and resources you accumulate—whether skills, credentials, connections, or +savings—that allow you to do more with your career in the future. It’s an important consideration in long-term career +planning, especially in the early stages of your career. + +Taken from: https://probablygood.org/core-concepts/career-capital/ diff --git a/20250723183755-deliberate_practice.org b/20250723183755-deliberate_practice.org new file mode 100644 index 0000000..3ca02f1 --- /dev/null +++ b/20250723183755-deliberate_practice.org @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: d4f96bfb-b83d-449b-9f74-f602a1a3c2d3 +:END: +#+title: deliberate_practice +#+filetags: :definitions: + +Deliberate practice refers to a special type of practice that is purposeful and systematic. While regular practice might +include mindless repetitions, deliberate practice requires focused attention and is conducted with the specific goal of +improving performance. + +Taken from: https://jamesclear.com/deliberate-practice-theory + diff --git a/20250723183755-deliberate_practice.org~ b/20250723183755-deliberate_practice.org~ new file mode 100644 index 0000000..7d67c67 --- /dev/null +++ b/20250723183755-deliberate_practice.org~ @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: d4f96bfb-b83d-449b-9f74-f602a1a3c2d3 +:END: +#+title: Deliberate practice +#+filetags: :definitions: + +Deliberate practice refers to a special type of practice that is purposeful and systematic. While regular practice might +include mindless repetitions, deliberate practice requires focused attention and is conducted with the specific goal of +improving performance. + +Taken from: https://jamesclear.com/deliberate-practice-theory + diff --git a/20250723184233-advanced_networking.org b/20250723184233-advanced_networking.org new file mode 100644 index 0000000..a709b2b --- /dev/null +++ b/20250723184233-advanced_networking.org @@ -0,0 +1,29 @@ +:PROPERTIES: +:ID: 3acffb66-bc1a-4661-904f-c5447b3c3488 +:END: +#+title: advanced-networking +#+filetags: :uni:networking: + +# Advanced Networking + +This module was taught in the first semester of my final year at university. There were a wide range of topics that were covered, and best efforts were made in not talking about the security aspects of networks, although it is the case that when we talk about networks we are talking about secure networks (who even needs insecure networks?). + +The following core topics were covered: + +1. Lower Layer Protocols + - Packet vs Circuit Switching, Ethernet, layer models (DoD 4/5, OSI 7). + - Network Hardware: Switches, Routers, data/control/management plane. Software defined networks. + - LAN/WAN split, Arpanet, DoD, OSI. Why OSI Failed + - Link aggregation and VLANs +2. IP Addressing + - Addressing, routing, concepts. Why IPv6 is needed + - Address allocation, bootp, DHCP, SLAAC + - NAT and Proxying +3. TCP/UDP + - UDP: applications, advantages and disadvantages + - TCP: applications, advantages and disadvantages, mechanisms and operation, sequence numbers, receive windows, slow start, window scaling, PAWS, timestamping, multipathing + - Demultiplexing, multiplexing +4. DNS + - DNS: concepts, resource records, RR sets, basic operation, recursive and authoritative servers, caching, DNSSEC +5. Higher layer protocols + - Basic operation of HTTP, FTP, SMTP diff --git a/20250723184233-advanced_networking.org~ b/20250723184233-advanced_networking.org~ new file mode 100644 index 0000000..a709b2b --- /dev/null +++ b/20250723184233-advanced_networking.org~ @@ -0,0 +1,29 @@ +:PROPERTIES: +:ID: 3acffb66-bc1a-4661-904f-c5447b3c3488 +:END: +#+title: advanced-networking +#+filetags: :uni:networking: + +# Advanced Networking + +This module was taught in the first semester of my final year at university. There were a wide range of topics that were covered, and best efforts were made in not talking about the security aspects of networks, although it is the case that when we talk about networks we are talking about secure networks (who even needs insecure networks?). + +The following core topics were covered: + +1. Lower Layer Protocols + - Packet vs Circuit Switching, Ethernet, layer models (DoD 4/5, OSI 7). + - Network Hardware: Switches, Routers, data/control/management plane. Software defined networks. + - LAN/WAN split, Arpanet, DoD, OSI. Why OSI Failed + - Link aggregation and VLANs +2. IP Addressing + - Addressing, routing, concepts. Why IPv6 is needed + - Address allocation, bootp, DHCP, SLAAC + - NAT and Proxying +3. TCP/UDP + - UDP: applications, advantages and disadvantages + - TCP: applications, advantages and disadvantages, mechanisms and operation, sequence numbers, receive windows, slow start, window scaling, PAWS, timestamping, multipathing + - Demultiplexing, multiplexing +4. DNS + - DNS: concepts, resource records, RR sets, basic operation, recursive and authoritative servers, caching, DNSSEC +5. Higher layer protocols + - Basic operation of HTTP, FTP, SMTP diff --git a/20250723184430-stanford_marshmallow_experiment.org b/20250723184430-stanford_marshmallow_experiment.org new file mode 100644 index 0000000..004af07 --- /dev/null +++ b/20250723184430-stanford_marshmallow_experiment.org @@ -0,0 +1,16 @@ +:PROPERTIES: +:ID: acba0d25-08db-4784-8cc2-fe5c437ba723 +:END: +#+title: stanford_marshmallow_experiment +#+filetags: :research: + +The Stanford marshmallow experiment, conducted in the 1960s and 1970s by psychologist Walter Mischel, explored the +ability of children to delay gratification. In the experiment, preschoolers were offered a marshmallow with the promise +of a second one if they waited a designated time (typically 15 minutes) without eating the first. The study's findings +revealed that children who waited longer to eat the marshmallow showed positive correlations with future outcomes like +higher SAT scores and better social functioning. However, later research has questioned the predictive power of the +original study, particularly when controlling for socio-economic factors. + +Source: https://jamesclear.com/delayed-gratification + + diff --git a/20250723184430-stanford_marshmallow_experiment.org~ b/20250723184430-stanford_marshmallow_experiment.org~ new file mode 100644 index 0000000..b5e1c7a --- /dev/null +++ b/20250723184430-stanford_marshmallow_experiment.org~ @@ -0,0 +1,16 @@ +:PROPERTIES: +:ID: acba0d25-08db-4784-8cc2-fe5c437ba723 +:END: +#+title: Stanford marshmallow experiment +#+filetags: :research: + +The Stanford marshmallow experiment, conducted in the 1960s and 1970s by psychologist Walter Mischel, explored the +ability of children to delay gratification. In the experiment, preschoolers were offered a marshmallow with the promise +of a second one if they waited a designated time (typically 15 minutes) without eating the first. The study's findings +revealed that children who waited longer to eat the marshmallow showed positive correlations with future outcomes like +higher SAT scores and better social functioning. However, later research has questioned the predictive power of the +original study, particularly when controlling for socio-economic factors. + +Source: https://jamesclear.com/delayed-gratification + + diff --git a/20250723185056-neuroplasticity.org b/20250723185056-neuroplasticity.org new file mode 100644 index 0000000..9341b16 --- /dev/null +++ b/20250723185056-neuroplasticity.org @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: a087da71-bcfb-4ddf-9565-b82113d5d27f +:END: +#+title: neuroplasticity +#+filetags: :definitions: + + +The ability of the brain to form and reorganize synaptic connections, especially in response to learning or +experience or following injury. + +"Neuroplasticity offers real hope to everyone from stroke victims to dyslexics" diff --git a/20250723185056-neuroplasticity.org~ b/20250723185056-neuroplasticity.org~ new file mode 100644 index 0000000..a1f8cf8 --- /dev/null +++ b/20250723185056-neuroplasticity.org~ @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: a087da71-bcfb-4ddf-9565-b82113d5d27f +:END: +#+title: Neuroplasticity +#+filetags: :definitions: + + +The ability of the brain to form and reorganize synaptic connections, especially in response to learning or +experience or following injury. + +"Neuroplasticity offers real hope to everyone from stroke victims to dyslexics" diff --git a/20250723185829-test_driven_development.org b/20250723185829-test_driven_development.org new file mode 100644 index 0000000..af0cf47 --- /dev/null +++ b/20250723185829-test_driven_development.org @@ -0,0 +1,10 @@ +:PROPERTIES: +:ID: 2729599d-ae2b-4f22-b73d-bf22d81e0767 +:END: +#+title: test_driven_development +#+filetags: :notes:coding:guide: + +Test-driven development is a way of writing code that involves writing an automated unit-level test case that fails, then writing just enough code to make the test pass, then refactoring both the test code and the production code, then repeating with another new test case. Alternative approaches to writing automated tests is to write all of the production code before starting on the test code or to write all of the test code before starting on the production code. + +One example is: +- [[id:bca8e7a6-0590-4630-ab49-210306ad21a2][bowling-kata]] diff --git a/20250723185829-test_driven_development.org~ b/20250723185829-test_driven_development.org~ new file mode 100644 index 0000000..a2f7115 --- /dev/null +++ b/20250723185829-test_driven_development.org~ @@ -0,0 +1,10 @@ +:PROPERTIES: +:ID: 2729599d-ae2b-4f22-b73d-bf22d81e0767 +:END: +#+title: Test-driven development +#+filetags: :index:coding:guide: + +Test-driven development is a way of writing code that involves writing an automated unit-level test case that fails, then writing just enough code to make the test pass, then refactoring both the test code and the production code, then repeating with another new test case. Alternative approaches to writing automated tests is to write all of the production code before starting on the test code or to write all of the test code before starting on the production code. + +One example is: +- [[id:bca8e7a6-0590-4630-ab49-210306ad21a2][bowling-kata]] diff --git a/20250723185943-bowling_kata.org b/20250723185943-bowling_kata.org new file mode 100644 index 0000000..7865e4a --- /dev/null +++ b/20250723185943-bowling_kata.org @@ -0,0 +1,13 @@ +:PROPERTIES: +:ID: bca8e7a6-0590-4630-ab49-210306ad21a2 +:END: +#+title: bowling-kata +#+filetags: :coding:docs:resources: + +- https://www.codurance.com/katas/bowling + +- http://www.butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata + +- https://codingdojo.org/kata/Bowling/ + +- https://www.bowlinggenius.com/ diff --git a/20250723185943-bowling_kata.org~ b/20250723185943-bowling_kata.org~ new file mode 100644 index 0000000..c3a58b7 --- /dev/null +++ b/20250723185943-bowling_kata.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: bca8e7a6-0590-4630-ab49-210306ad21a2 +:END: +#+title: bowling-kata + diff --git a/20250723190203-java_portswrigger_test.org b/20250723190203-java_portswrigger_test.org new file mode 100644 index 0000000..6849eff --- /dev/null +++ b/20250723190203-java_portswrigger_test.org @@ -0,0 +1,648 @@ +:PROPERTIES: +:ID: 5cfd7f6f-f5ac-4f18-90f9-be9a31dd238e +:END: +#+title: java-portswrigger-test +#+filetags: :java:notes:interview: + + +* Latest +** Java concepts: +# Java Core Language - Concise Reference Guide + +## 1. Object-Oriented Programming Concepts + +### Inheritance +- **Definition**: Mechanism where a class inherits properties and behaviors from another class +- **Syntax**: `public class Child extends Parent { }` +- **Types**: Single, Multilevel, Hierarchical +- **'super' keyword**: Refers to parent class objects/constructors +- **Method Overriding**: Child classes can provide specific implementation of methods + +### Encapsulation +- **Definition**: Bundling data and methods that operate on the data within a single unit +- **Implementation**: Using private fields with public getters/setters +- **Benefits**: Hides implementation details, controls access, reduces code coupling +```java +public class Account { + private double balance; + + public double getBalance() { + return balance; + } + + public void deposit(double amount) { + if (amount > 0) { + balance += amount; + } + } +} +``` + +### Polymorphism +- **Definition**: Ability of objects to take different forms +- **Types**: + - **Compile-time (Method Overloading)**: Multiple methods with same name but different parameters + - **Runtime (Method Overriding)**: Subclass implementing parent class method +- **Example**: +```java +class Animal { + void makeSound() { System.out.println("Animal sound"); } +} +class Dog extends Animal { + @Override + void makeSound() { System.out.println("Bark"); } +} +``` + +### Abstraction +- **Definition**: Hiding implementation details, showing only functionality +- **Implementation**: Through abstract classes and interfaces +- **Abstract Classes**: Can have both concrete and abstract methods +- **Interfaces**: Collection of abstract methods (default/static methods allowed in Java 8+) +```java +abstract class Vehicle { + abstract void start(); + void stop() { System.out.println("Stopping"); } +} + +interface Flyable { + void fly(); + default void land() { System.out.println("Landing"); } +} +``` + +## 2. Java Syntax and Language Features + +### Basic Structure +```java +package com.example; + +import java.util.List; + +public class MyClass { + // Fields + private int number; + + // Constructor + public MyClass(int number) { + this.number = number; + } + + // Methods + public void doSomething() { + // Method body + } + + // Main method + public static void main(String[] args) { + // Program execution starts here + } +} +``` + +### Access Modifiers +- **public**: Accessible from anywhere +- **protected**: Accessible within package and by subclasses +- **default (no modifier)**: Accessible only within package +- **private**: Accessible only within class + +### Non-Access Modifiers +- **static**: Belongs to class rather than instance +- **final**: Cannot be extended (class), overridden (method), or changed (variable) +- **abstract**: Cannot be instantiated (class), must be implemented (method) +- **synchronized**: Controls thread access to method/block +- **volatile**: Variable value always read from main memory + +## 3. Data Types, Variables, and Operators + +### Primitive Data Types +| Type | Size | Range | Default | +|------|------|-------|---------| +| byte | 8 bits | -128 to 127 | 0 | +| short | 16 bits | -32,768 to 32,767 | 0 | +| int | 32 bits | -2^31 to 2^31-1 | 0 | +| long | 64 bits | -2^63 to 2^63-1 | 0L | +| float | 32 bits | ~3.40282347 x 10^38 | 0.0f | +| double | 64 bits | ~1.79769313486231570 x 10^308 | 0.0d | +| char | 16 bits | 0 to 65,535 | '\u0000' | +| boolean | 1 bit | true/false | false | + +### Reference Types +- **Classes**: `String`, custom classes +- **Arrays**: `int[]`, `String[]` +- **Interfaces**: Collections interfaces +- **Wrapper Classes**: `Integer`, `Boolean`, etc. + +### Variable Declaration +```java +// Primitive types +int count = 10; +double price = 23.45; + +// Reference types +String name = "John"; +Date today = new Date(); + +// Constants +final double PI = 3.14159; +``` + +### Operators +- **Arithmetic**: `+`, `-`, `*`, `/`, `%`, `++`, `--` +- **Relational**: `==`, `!=`, `>`, `<`, `>=`, `<=` +- **Logical**: `&&`, `||`, `!` +- **Bitwise**: `&`, `|`, `^`, `~`, `<<`, `>>`, `>>>` +- **Assignment**: `=`, `+=`, `-=`, `*=`, `/=`, etc. +- **Ternary**: `condition ? expr1 : expr2` +- **instanceof**: Tests if object is instance of class/interface + +## 4. Control Flow Statements + +### Conditional Statements +```java +// if-else +if (condition) { + // code block +} else if (anotherCondition) { + // code block +} else { + // code block +} + +// switch +switch (variable) { + case value1: + // code block + break; + case value2: + // code block + break; + default: + // code block +} + +// Enhanced switch (Java 14+) +switch (variable) { + case value1 -> // code or expression; + case value2 -> // code or expression; + default -> // code or expression; +} +``` + +### Loops +```java +// for loop +for (int i = 0; i < 10; i++) { + // code block +} + +// enhanced for loop (for-each) +for (String item : itemList) { + // code block +} + +// while loop +while (condition) { + // code block +} + +// do-while loop +do { + // code block +} while (condition); +``` + +### Control Statements +- **break**: Exits loop or switch +- **continue**: Skips to next iteration +- **return**: Exits method, optionally returning value +- **yield**: Returns value from switch expression (Java 14+) + +## 5. Exception Handling + +### Exception Hierarchy +- **Throwable**: Base class for all exceptions + - **Error**: Serious problems, not typically caught + - **Exception**: Base for checked exceptions + - **RuntimeException**: Base for unchecked exceptions + +### Try-Catch-Finally +```java +try { + // code that might throw exception +} catch (ExceptionType1 e1) { + // handle exception type 1 +} catch (ExceptionType2 | ExceptionType3 e2) { + // handle multiple exception types +} finally { + // always executed code +} +``` + +### Try-With-Resources +```java +try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) { + // code that uses resource + // resource automatically closed +} +``` + +### Throwing Exceptions +```java +if (value < 0) { + throw new IllegalArgumentException("Value cannot be negative"); +} +``` + +### Creating Custom Exceptions +```java +public class CustomException extends Exception { + public CustomException() { super(); } + public CustomException(String message) { super(message); } + public CustomException(String message, Throwable cause) { super(message, cause); } +} +``` + +### Checked vs. Unchecked Exceptions +- **Checked**: Must be caught or declared (IOException, SQLException) +- **Unchecked**: Not required to be caught (RuntimeException and subclasses) + +## 6. Java Collections Framework + +### Main Interfaces +- **Collection**: Root interface + - **List**: Ordered collection (allows duplicates) + - **Set**: No duplicates + - **Queue**: Typically FIFO order +- **Map**: Key-value pairs + +### Common Implementations +- **Lists**: + - `ArrayList`: Dynamic array, fast random access + - `LinkedList`: Fast insertions/deletions + - `Vector`: Synchronized version of ArrayList +- **Sets**: + - `HashSet`: Fast operations, no order guarantee + - `LinkedHashSet`: Preserves insertion order + - `TreeSet`: Sorted set (implements SortedSet) +- **Maps**: + - `HashMap`: Fast operations, no order guarantee + - `LinkedHashMap`: Preserves insertion order + - `TreeMap`: Sorted by keys (implements SortedMap) + - `Hashtable`: Synchronized version of HashMap +- **Queues**: + - `ArrayDeque`: Resizable array implementation + - `PriorityQueue`: Elements processed by priority + +### Usage Examples +```java +// ArrayList +List names = new ArrayList<>(); +names.add("Alice"); +names.add("Bob"); +names.remove(0); +String first = names.get(0); + +// HashMap +Map ages = new HashMap<>(); +ages.put("Alice", 30); +ages.put("Bob", 25); +int aliceAge = ages.get("Alice"); +boolean containsBob = ages.containsKey("Bob"); + +// HashSet +Set uniqueNames = new HashSet<>(); +uniqueNames.add("Alice"); +uniqueNames.add("Alice"); // Ignored (duplicate) +boolean hasAlice = uniqueNames.contains("Alice"); +``` + +## 7. Generics + +### Basic Syntax +```java +// Generic class +public class Box { + private T value; + + public void set(T value) { this.value = value; } + public T get() { return value; } +} + +// Usage +Box intBox = new Box<>(); +intBox.set(10); +Integer value = intBox.get(); +``` + +### Wildcards +```java +// Unknown type (?) +void processElements(List elements) { + // Can read but not write elements +} + +// Upper bounded wildcard +void addNumbers(List numbers) { + // Can read elements knowing they are at least Number +} + +// Lower bounded wildcard +void addIntegers(List integers) { + integers.add(10); // Can write Integers +} +``` + +### Type Parameters +- **Type Parameter Naming Conventions**: + - `E`: Element + - `K`: Key + - `V`: Value + - `N`: Number + - `T`: Type + - `S`, `U`, `V`, etc.: Additional types + +### Type Erasure +- During compilation, generic type information is removed ("erased") +- Runtime doesn't have access to generic type information + +## 8. Functional Interfaces and Lambda Expressions + +### Functional Interfaces +- Interface with exactly one abstract method +- Annotated with `@FunctionalInterface` +- Common functional interfaces: + - `Predicate`: Takes T, returns boolean (`boolean test(T t)`) + - `Consumer`: Takes T, returns void (`void accept(T t)`) + - `Function`: Takes T, returns R (`R apply(T t)`) + - `Supplier`: Takes nothing, returns T (`T get()`) + - `BinaryOperator`: Takes two T, returns T (`T apply(T t1, T t2)`) + +### Lambda Expressions +```java +// Basic syntax +(parameters) -> expression +(parameters) -> { statements; } + +// Examples +Predicate isEmpty = s -> s.isEmpty(); +Consumer printer = s -> System.out.println(s); +Function lengthFinder = s -> s.length(); +Supplier random = () -> Math.random(); +BinaryOperator sum = (a, b) -> a + b; +``` + +### Method References +```java +// Static method +Function parseInt = Integer::parseInt; + +// Instance method of specific object +Consumer printer = System.out::println; + +// Instance method of arbitrary object +Function length = String::length; + +// Constructor +Supplier> listSupplier = ArrayList::new; +``` + +## 9. Streams API + +### Creating Streams +```java +// From collection +List list = Arrays.asList("a", "b", "c"); +Stream stream = list.stream(); + +// From array +String[] array = {"a", "b", "c"}; +Stream stream = Arrays.stream(array); + +// Generate/iterate +Stream numbers = Stream.iterate(0, n -> n + 1).limit(10); +Stream randoms = Stream.generate(Math::random).limit(5); +``` + +### Common Operations +- **Intermediate Operations** (return a stream): + - `filter(Predicate)`: Filters elements + - `map(Function)`: Transforms elements + - `flatMap(Function)`: Transforms and flattens + - `sorted()`: Sorts elements + - `distinct()`: Removes duplicates + - `limit(n)`: Limits size + - `skip(n)`: Skips elements +- **Terminal Operations** (produce a result): + - `forEach(Consumer)`: Processes each element + - `collect(Collector)`: Gathers elements + - `reduce(BinaryOperator)`: Reduces to single value + - `count()`: Counts elements + - `anyMatch(Predicate)`: Tests if any match + - `allMatch(Predicate)`: Tests if all match + - `noneMatch(Predicate)`: Tests if none match + - `findFirst()`, `findAny()`: Finds elements + +### Example +```java +List names = Arrays.asList("John", "Jane", "Jack", "James"); + +List filteredNames = names.stream() + .filter(name -> name.startsWith("J")) + .filter(name -> name.length() > 3) + .map(String::toUpperCase) + .sorted() + .collect(Collectors.toList()); +``` + +## 10. Multithreading and Concurrency + +### Thread Creation +```java +// Extending Thread +class MyThread extends Thread { + public void run() { + // Code to execute in thread + } +} +MyThread thread = new MyThread(); +thread.start(); + +// Implementing Runnable +class MyRunnable implements Runnable { + public void run() { + // Code to execute in thread + } +} +Thread thread = new Thread(new MyRunnable()); +thread.start(); + +// Lambda expression +Thread thread = new Thread(() -> { + // Code to execute in thread +}); +thread.start(); +``` + +### Thread Lifecycle +- **New**: Created but not started +- **Runnable**: Started, waiting for scheduler +- **Blocked**: Waiting for monitor lock +- **Waiting**: Called wait() without timeout +- **Timed Waiting**: Called sleep() or wait() with timeout +- **Terminated**: Completed execution + +### Thread Synchronization +```java +// Synchronized method +synchronized void method() { + // Thread-safe code +} + +// Synchronized block +synchronized (lockObject) { + // Thread-safe code +} + +// Lock interface +Lock lock = new ReentrantLock(); +lock.lock(); +try { + // Critical section +} finally { + lock.unlock(); +} +``` + +### Concurrent Collections +- **ConcurrentHashMap**: Thread-safe HashMap +- **CopyOnWriteArrayList**: Thread-safe ArrayList +- **BlockingQueue**: Queue with blocking operations + +### Thread Pools (ExecutorService) +```java +// Fixed thread pool +ExecutorService executor = Executors.newFixedThreadPool(5); +executor.submit(() -> { + // Task to execute +}); +executor.shutdown(); + +// CompletableFuture +CompletableFuture future = CompletableFuture.supplyAsync(() -> { + // Async computation + return "Result"; +}); +future.thenAccept(System.out::println); +``` + +### Atomic Variables +```java +AtomicInteger counter = new AtomicInteger(0); +counter.incrementAndGet(); // Thread-safe increment +``` + +### Thread Communication +- **wait()**: Causes thread to wait until notify/notifyAll +- **notify()**: Wakes up one waiting thread +- **notifyAll()**: Wakes up all waiting threads +- **join()**: Waits for thread to die + +* Original +1. Object-Oriented Programming (OOP) in Java +- Encapsulation (Access Modifiers: private, protected, public, default) +- Abstraction (abstract classes, interfaces, default methods in interfaces) +- Inheritance (extends, method overriding, super keyword, constructor chaining) +- Polymorphism (Compile-time vs. Runtime, method overloading vs. method overriding) +- Composition vs. Inheritance (Why favor composition over inheritance?) +- SOLID Principles (How they apply in Java) +- JavaBeans and POJOs (Plain Old Java Objects) + +2. Java Data Types and Memory Management +- Primitive vs. Reference Types +- Wrapper classes (Integer, Double, Boolean, etc.) +- String handling (String, StringBuilder, StringBuffer, immutability) +- Autoboxing and Unboxing +- Memory Allocation (Heap vs. Stack) +- Garbage Collection (How it works, finalize(), weak references, types of GC algorithms) + +3. Java Collections Framework (JCF) +- List Interface (ArrayList, LinkedList, Vector, Stack) +- Set Interface (HashSet, TreeSet, LinkedHashSet) +- Map Interface (HashMap, TreeMap, LinkedHashMap, Hashtable) +- Queue Interface (PriorityQueue, Deque, ArrayDeque) +- Concurrent Collections (ConcurrentHashMap, CopyOnWriteArrayList) +- Sorting and Searching in Collections (Comparable vs. Comparator) +- Big-O Complexity of Collection Operations +- Immutable Collections (List.of(), Set.of(), Map.of()) + +4. Exception Handling +- Checked vs. Unchecked Exceptions +- Custom Exceptions +- Try-Catch-Finally vs. Try-With-Resources (AutoCloseable) +- Throw vs. Throws +- Multi-catch blocks (catch (IOException | SQLException e)) +- Best Practices for Exception Handling (Avoiding Generic Exceptions) + +5. Java Multithreading and Concurrency +- Thread Lifecycle +- Creating Threads (Thread vs. Runnable, Callable, Future) +- Synchronization (synchronized keyword, locks, ReentrantLock, wait(), notify()) +- Thread Safety and Shared Resource Handling +- Executors and Thread Pools (ExecutorService, ScheduledExecutorService) +- Atomic Variables (AtomicInteger, AtomicBoolean) +- Fork-Join Framework +- Deadlocks, Race Conditions, and Livelocks + +6. Java Streams and Functional Programming +- Lambda Expressions ((a, b) -> a + b) +- Method References (Class::methodName) +- Functional Interfaces (Predicate, Consumer, Supplier, Function, BiFunction) +- Streams API (Intermediate vs. Terminal Operations) +- Stream Processing (map(), filter(), reduce(), collect()) +- Parallel Streams (parallelStream()) +- Optional Class (Optional, avoiding null) + +7. Java Input/Output (I/O) and Serialization +- Byte Streams vs. Character Streams (InputStream, OutputStream, Reader, Writer) +- File Handling (File, Files, BufferedReader, BufferedWriter) +- Object Serialization (Serializable, transient keyword) +- New I/O (NIO) (Path, Files, ByteBuffer, Channels) +- Memory-Mapped Files +- Java 11+ Features (Files.writeString(), Files.readString()) + +8. Java 8+ Features +- Default and Static Methods in Interfaces +- Optional Class +- New Date and Time API (LocalDate, LocalTime, LocalDateTime, ZonedDateTime) +- CompletableFuture (thenApply(), thenAccept(), exceptionally()) +- New Collection Methods (List.of(), Set.of(), Map.of()) +- Records (Java 14+) +- Pattern Matching (Java 17+) +- Sealed Classes (Java 17+) + +9. Java Reflection and Dynamic Class Loading +- Getting Class Information (.class, Class.forName()) +- Accessing Private Fields and Methods +- Dynamic Proxy and InvocationHandler +- Annotations and Annotation Processing + +10. Java Networking (Sockets, HTTP) +- Java Sockets (ServerSocket, Socket) +- URL and HttpURLConnection +- HTTP Clients (Java 11 HttpClient) +- Multithreaded Server Applications + +11. Java Security Basics +- Encryption and Hashing (AES, SHA, RSA) +- Java Cryptography API (MessageDigest, Cipher) +- Secure Random Numbers (SecureRandom) +- Security Manager (doPrivileged()) +- Understanding Java Classloaders and Security Policies + +12. Java Virtual Machine (JVM) Internals +- JVM Architecture (ClassLoader, Method Area, Heap, Stack, Execution Engine, Garbage Collector) +- Class Loading (ClassLoader, Bootstrap, Extensions, Application ClassLoader) +- JIT Compilation (Just-In-Time Compiler) +- Garbage Collection Algorithms (G1, ZGC, Epsilon GC) +- JVM Performance Tuning (-Xms, -Xmx, -XX:+UseG1GC) diff --git a/20250723190203-java_portswrigger_test.org~ b/20250723190203-java_portswrigger_test.org~ new file mode 100644 index 0000000..b492813 --- /dev/null +++ b/20250723190203-java_portswrigger_test.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: 5cfd7f6f-f5ac-4f18-90f9-be9a31dd238e +:END: +#+title: java-portswrigger-test + diff --git a/20250723190656-java_junit_testing.org b/20250723190656-java_junit_testing.org new file mode 100644 index 0000000..46a8acc --- /dev/null +++ b/20250723190656-java_junit_testing.org @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: 7b8de14c-a73e-4c92-a403-a9a1c419c0b3 +:END: +#+title: java-junit-testing +#+filetags: :java:coding:guides: + +https://www.geeksforgeeks.org/software-testing/introduction-to-junit-5/ diff --git a/20250723190656-java_junit_testing.org~ b/20250723190656-java_junit_testing.org~ new file mode 100644 index 0000000..612c892 --- /dev/null +++ b/20250723190656-java_junit_testing.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: 7b8de14c-a73e-4c92-a403-a9a1c419c0b3 +:END: +#+title: java-junit-testing + diff --git a/20250723190927-self_hosting.org b/20250723190927-self_hosting.org new file mode 100644 index 0000000..86c5543 --- /dev/null +++ b/20250723190927-self_hosting.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 99533f2d-a4e8-41d0-a605-c7d4cef6f995 +:END: +#+title: self_hosting +#+filetags: :networking:self-hosting:index: + +https://hub.docker.com/_/nextcloud + +[[id:56f39be4-1108-4020-be5a-1f3a0fbf96fa][nextcloud]] diff --git a/20250723190927-self_hosting.org~ b/20250723190927-self_hosting.org~ new file mode 100644 index 0000000..9a28c5c --- /dev/null +++ b/20250723190927-self_hosting.org~ @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 99533f2d-a4e8-41d0-a605-c7d4cef6f995 +:END: +#+title: Self Hosting +#+filetags: :networking:self-hosting:index: + +https://hub.docker.com/_/nextcloud + +[[id:56f39be4-1108-4020-be5a-1f3a0fbf96fa][nextcloud]] diff --git a/20250723200800-postgres.org b/20250723200800-postgres.org new file mode 100644 index 0000000..e573f54 --- /dev/null +++ b/20250723200800-postgres.org @@ -0,0 +1,64 @@ +:PROPERTIES: +:ID: 939e301b-6463-46a8-b57e-0af606e7e7ef +:END: +#+title: postgres +#+filetags: :database:index: + +#+begin_src bash + + #+end_src + +Something I've been trying to reverse proxy ahead of time. Go to https://zserver.zapto.org/nextcloud , you'll be prompted to login with a username and password: +Here's your credentials: + +Username: halima +Password: loser2104! + +Once you've logged in, I've set up your account already, so there should be a calendar already there. + +To get your phone logged in, there's two ways: +1) go to the following address: https://zserver.zapto.org/nextcloud/settings/user/security , scroll to the bottom, under devices and sessions, type in a random name (iphone), and click create new app password. You should then be able to generate a QR code (next to or under the password field), then you can scan that on your iphone app. + +2) inside the app, type the following URL: https://zserver.zapto.org/nextcloud then follow the instructions. + +Im thinking of having this as our shared calendar and file system. The only users are us 2 and its completely off the internet (self-hosted). + + +network issues resolved by: + +docker network connect postgres_network postgres + + +zaine@zaine-HP-ProDesk-400-G1-SFF [21:00:27] [~/docker-services/nextcloud] +-> % psql -h zserver.zapto.org -p 5432 -U zaine -d zxq_db +Password for user zaine: +psql (14.18 (Ubuntu 14.18-0ubuntu0.22.04.1), server 17.5 (Debian 17.5-1.pgdg120+1)) +WARNING: psql major version 14, server major version 17. + Some psql features might not work. +Type "help" for help. + +zxq_db=# \c nextcloud +psql (14.18 (Ubuntu 14.18-0ubuntu0.22.04.1), server 17.5 (Debian 17.5-1.pgdg120+1)) +WARNING: psql major version 14, server major version 17. + Some psql features might not work. +You are now connected to database "nextcloud" as user "zaine". +nextcloud=# GRANT ALL PRIVILEGES ON DATABASE nextcloud TO nextcloud; +GRANT +nextcloud=# GRANT USAGE ON SCHEMA public TO nextcloud; +GRANT CREATE ON SCHEMA public TO nextcloud; +GRANT +GRANT +nextcloud=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO nextcloud; +GRANT +nextcloud=# GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO nextcloud; +GRANT +nextcloud=# + +zaine +M22ZN-fmefj-RdF36-3BMfT-LfWo8 + +zaine +zxh123! + + + diff --git a/20250724230557-books_org_agenda.org b/20250724230557-books_org_agenda.org new file mode 100644 index 0000000..f0bef49 --- /dev/null +++ b/20250724230557-books_org_agenda.org @@ -0,0 +1,487 @@ +:PROPERTIES: +:ID: 363dbdfa-f23c-4f7e-a6f3-6d34f78984bb +:END: +#+title: books-org-agenda +#+filetags: :books:org:index: +#+DATE: 2025-05-19 +#+STARTUP: content + +* Books +** English Books +*** Teaching the Students the method of Studying +:PROPERTIES: +:Author: Sheikh Burhanul Islam Az-Zarnuji (tr. by Moulana Ebrahim Muhammad) +:Status: Read +:Group: Reading +:STARTED: <2024-07-01 Mon> +:FINISHED: <2024-07-12 Fri> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 11 +:DAYS_SINCE_FINISHED: 500 +:END: +*** A gift for nikah +:PROPERTIES: +:Author: Shaykh Abdul Raheem sahib DB +:Status: Read +:Group: Reading +:STARTED: <2024-10-28 Mon> +:FINISHED: <2024-10-29 Tue> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 1 +:DAYS_SINCE_FINISHED: 391 +:END: +*** The etiquette of Studying Hadith +:PROPERTIES: +:Author: Moulana Saleem Dhorab Sahib DB +:Status: Read +:Group: Reading +:STARTED: <2024-07-01 Mon> +:Finished: <2024-07-02 Tue> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 1 +:DAYS_SINCE_FINISHED: 510 +:END: +Read again on Tuesday 19th August 2025 + +*** The value of Time +:PROPERTIES: +:Author: Abdul Fattah Abu Ghuddah رح +:Status: Read +:Group: Reading +:STARTED: <2024-03-17 Sun> +:FINISHED: <2024-04-05 Fri> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 19 +:DAYS_SINCE_FINISHED: 598 +:END: +*** Naqshe Hayat +:PROPERTIES: +:Author: Shaykh Husain Ahmad Madani رح +:Status: Read +:Group: Reading +:STARTED: <2025-07-24 Thu> +:FINISHED: <2025-09-09 Tue> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 47 +:DAYS_SINCE_FINISHED: 76 +:END: +*** The Tafsir of Surah Nuh +:PROPERTIES: +:Author: Shaykh Abdul Raheem sahib DB +:Status: Read +:Group: Reading +:STARTED: <2024-09-24 Tue> +:FINISHED: <2025-09-10 Wed> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 351 +:DAYS_SINCE_FINISHED: 75 +:END: +*** The Path To Perfection +:PROPERTIES: +:Author: Shaikh Masihullah Khan +:Status: Read +:Group: Reading +:STARTED: <2024-07-17 Wed> +:FINISHED: <2025-09-12 Fri> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 422 +:DAYS_SINCE_FINISHED: 73 +:END: +*** An Introduction to the Science of Noble Hadith +:PROPERTIES: +:Author: Mufti Muadh Chatti DB +:Status: Reading +:Group: Reading +:STARTED: <2025-09-11 Thu> +:CATEGORY: Reading +:END: +*** Seeratul Mustafa Abridged +:PROPERTIES: +:Author: Mowlana Idrees Khandehlawi رح +:Status: Reading +:Group: Reading +:STARTED: <2025-09-12 Fri> +:CATEGORY: Reading +:END: + +*** Kanzul Bari +:PROPERTIES: +:Author: Shaykh Mufti Saiful Islam DB +:Status: Reading +:Group: Reading +:STARTED: <2025-07-24 Thu> +:CATEGORY: Reading +:END: + + +*** Hadith Scholarship in the Indian Subcontinent +:PROPERTIES: +:Author: Mawlana Muntasir Zaman +:Status: To Read +:Group: Reading +:STARTED: +:CATEGORY: To Read +:END: +*** Bidayat as-Sul Fi Tafdil ar-Rasul (The Beginning Of The Quest Of The High Esteem Of The Messenger ﷺ) +:PROPERTIES: +:Author: Imam 'Izz ibn 'Abd al-Salam رح (Translated by Aisha Bewley) +:Status: To Read +:Group: Reading +:STARTED: <2025-09-17 Wed> +:CATEGORY: To Read +:END: +*** Influence of The Noble Hadith Upon Differences of Opinion Amongst The Jurist Imams + :PROPERTIES: + :Author: Shaykh Muhammad Awwamah DB + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: +*** Muhammadﷺ: A Quranic Exposition of His Excellence and Virtues + :PROPERTIES: + :Author: Shaykh Yusuf al-Nabahani رح; Amjad Mahmood (translation) + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** Beneficial Epistle & Decisive Proof on Science of Divine Unity + :PROPERTIES: + :Author: Muhammad Salih al-Furfur رح; Amjad Mahmood (translation) + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** Seekers Aid, Manual on Creed & Hanafi Fiqh, Is'af Muridin Li +:PROPERTIES: +:Author: Abd al-Ghani al-Ghunaymi al-Maydani رح; Amjad Mahmood (translation) +:Status: To Read +:Group: Reading +:STARTED: +:CATEGORY: To Read +:END: +*** Muhammad ﷺ As If You Can See Him + :PROPERTIES: + :Author: A'id ibn 'Abdullah al-Qarni + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** How The Messenger Of Allah ﷺ Taught His Students + :PROPERTIES: + :Author: Jahangir Mahmud + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** The Life of Muhammad ﷺ + :PROPERTIES: + :Author: Imam Yahya bin Sharaf An-Nawawi رح + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** The prophet Muhammed ﷺ the best of all husbands + :PROPERTIES: + :Author: Dr. Ghazi Al-Shammari + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** The Tafsir of Surah Dahr + :PROPERTIES: + :Author: Shaykh Abdul Raheem sahib DB + :Status: To Read + :Group: Reading + :CATEGORY: To Read + :END: +*** The Tafsir of Surah Maryam + :PROPERTIES: + :Author: Shaykh Abdul Raheem sahib DB + :Status: To Read + :Group: Reading + :STARTED: <2024-10-28 Mon> + :CATEGORY: To Read + :END: +*** The Tafsir of Surah Fatiha + :PROPERTIES: + :Author: Shaykh Abdul Raheem sahib DB + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: +*** The Tafsir of Surah Yusuf +:PROPERTIES: +:Author: Shaykh Abdul Raheem sahib DB +:Status: To Read +:Group: Reading +:STARTED: +:CATEGORY: To Read +:END: +** Arabic Books +*** A المنهج المفيد لطلب علم الحديث +:PROPERTIES: +:Author: سيد عبد الماجد الغوري +:Status: Studied O +:Group: Study +:From: additional study book +:STARTED: <2024-07-20 Sat> +:Finished: <2024-08-30 Fri> +:CATEGORY: Studied O +:TOTAL_DAYS_SPENT: 41 +:DAYS_SINCE_FINISHED: 451 +:END: +*** A مختصر سيرة النبي وأصحابه العشرة +:PROPERTIES: +:Author: عبد الغني المقدسي رح +:Status: Reading +:Group: Reading +:STARTED: <2024-09-05 Thu> +:CATEGORY: Reading +:END: +*** A الإسناد من الدين وصفحة مشرقة من تاريخ سماع الحديث عند المحدثين +:PROPERTIES: +:Author: Abdul Fattah Abu Ghuddah رح +:Status: To Read +:Group: Reading +:STARTED: <2024-08-30 Fri> +:CATEGORY: To Read +:END: +** Darsi +*** A صحة ستة +**** Bukhari Shareef +:PROPERTIES: +:Author: Imam Muhammad al-Bukhari رح +:Status: To Study D +:Group: Study +:STARTED: +:CATEGORY: To Study D +:END: +**** Muslim Shareef +:PROPERTIES: +:Author: Imam Muslim ibn al-Hajjaj رح +:Status: To Study D +:Group: Study +:STARTED: +:CATEGORY: To Study D +:END: +**** Tirmizi Shareef + :PROPERTIES: + :Author: Imam al-Tirmidhi (Abu Isa Muhammad ibn Isa) رح + :Status: To Study D + :Group: Study + :STARTED: + :CATEGORY: To Study D + :END: +**** Nisai Shareef + :PROPERTIES: + :Author: Imam al-Nasa'i (Ahmad ibn Shu'ayb) رح + :Status: To Study D + :Group: Study + :STARTED: + :CATEGORY: To Study D + :END: +**** Ibn Majah Shareef + :PROPERTIES: + :Author: Imam Ibn Majah (Muhammad ibn Yazid) رح + :Status: To Study D + :Group: Study + :STARTED: + :CATEGORY: To Study D + :END: +**** Abu Dawoud Shareef + :PROPERTIES: + :Author: Imam Abu Dawood (Sulayman ibn al-Ash'ath) رح + :Status: To Study D + :Group: Study + :STARTED: + :CATEGORY: To Study D + :END: +*** A مشكاة +**** Mishkat Shareef +:PROPERTIES: +:Author: Muḥammad ibn ʻAbd Allāh Khatib Al-Tabrizi رح +:Status: Studied D +:Group: Study +:STARTED: <2024-08-12 Mon> +:FINISHED: <2025-07-18 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 340 +:DAYS_SINCE_FINISHED: 129 +:END: +**** Jalalayn +:PROPERTIES: +:Author: Tafsir al-Jalalayn by Jalal ad-Din al-Mahalli and Jalal ad-Din as-Suyuti رح +:Status: Studied D +:Group: Study +:STARTED: <2024-08-12 Mon> +:FINISHED: <2025-07-18 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 340 +:DAYS_SINCE_FINISHED: 129 +:END: +**** Hidaya 3 +:PROPERTIES: +:Author: Imam murghinani رح +:Status: Studied D +:Group: Study +:STARTED: <2024-08-12 Mon> +:FINISHED: <2025-07-18 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 340 +:DAYS_SINCE_FINISHED: 129 +:END: +**** Hidaya 4 +:PROPERTIES: +:Author: Imam murghinani رح +:Status: Studied D +:Group: Study +:STARTED: <2024-08-12 Mon> +:FINISHED: <2025-07-18 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 340 +:DAYS_SINCE_FINISHED: 129 +:END: +*** English Books +**** Tasheel Nahw +:PROPERTIES: +:Author: maulana mushtaq ahmad charthawli رح +:Status: Studied D +:Group: Study +:STARTED: <2019-07-01 Mon> +:Finished: <2022-07-01 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 1096 +:DAYS_SINCE_FINISHED: 1242 +:END: +**** Hadith Terminology and Classification, A handbook. +:PROPERTIES: +:Author: Muhammad S. ar-Rahwan +:Status: To Study O +:Group: Study +:From: additional study book +:STARTED: +:CATEGORY: To Study O +:END: + +*** References/Sharh +**** A تفسير أبي السعود +:PROPERTIES: +:Author: أبي السعود محمد العمادي رح +:Volumes: 9 +:Status: Voluminous +:Group: Study +:CATEGORY: Voluminous +:END: +**** A مرقاۃ المفاتیح شرح مشکوۃ المصابیح +:PROPERTIES: +:Author: Mullah Ali Qari رح +:Volumes: 11 +:Status: Voluminous +:Group: Study +:CATEGORY: Voluminous +:END: +**** A عمدة القاري شرح صحيح البخاري +:PROPERTIES: +:Author: Allamah Ayni رح +:Volumes: 20 +:Status: Voluminous +:Group: Study +:STARTED: <2025-05-29 Thu> +:CATEGORY: Voluminous +:END: + +** Guide +:Status: Reading | To Read | Read | Studying D | Studying O | To Study D | To Study O | Studied D | Studied O | Reference | Voluminous +:Group: Reading | Study +:Agenda: Books I am Studying (Darsi) | Books I am Studying (Outside) | Books To Study (Darsi) | Books To Study (Outside) | Books Studied (Darsi) | Books Studied (Outside) | Reference Books | Voluminous Books + +* Other Books +** The Science of Self-Discipline +:PROPERTIES: +:Author: Peter Hollins +:Status: Others Read +:Group: Other +:STARTED: <2024-12-27 Fri> +:FINISHED: <2025-05-24 Sat> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 148 +:DAYS_SINCE_FINISHED: 184 +:END: +** So good they cant ignore you +:PROPERTIES: +:Author: Cal newport +:Status: Others Read +:Group: Other +:STARTED: <2025-05-25 Sun> +:FINISHED: <2025-06-15 Sun> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 21 +:DAYS_SINCE_FINISHED: 162 +:END: +** The Clean Coder +:PROPERTIES: +:Author: Robert C. Martin +:Status: Others Read +:Group: Other +:STARTED: <2025-07-15 Tue> +:FINISHED: <2025-07-27 Sun> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 12 +:DAYS_SINCE_FINISHED: 120 +:END: +** Clean Code +:PROPERTIES: +:Author: Robert C. Martin +:Status: Others Reading +:Group: Other +:STARTED: <2025-07-28 Mon> +:CATEGORY: Reading +:END: +** The Toyota Way +:PROPERTIES: +:Author: Jeffry Liker +:Status: Others Read +:Group: Other +:STARTED: <2025-10-13 Mon> +:FINISHED: <2025-11-22 Sat> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 40 +:DAYS_SINCE_FINISHED: 2 +:END: +** Agile Testing +:PROPERTIES: +:Author: Lisa Crispin +:Status: Others Reading +:Group: Other +:STARTED: <2025-10-13 Mon> +:CATEGORY: Reading +:END: +** Ikigai +:PROPERTIES: +:Author: Héctor García and Francesc Miralles +:Status: Others Reading +:Group: Other +:STARTED: <2025-11-23 Sun> +:CATEGORY: Reading +:END: + + + + +** Guide: +:Status: Others Reading | Others Read | Others To Read +:Group: Other diff --git a/20250724230557-books_org_agenda.org~ b/20250724230557-books_org_agenda.org~ new file mode 100644 index 0000000..e126d4a --- /dev/null +++ b/20250724230557-books_org_agenda.org~ @@ -0,0 +1,478 @@ +:PROPERTIES: +:ID: 363dbdfa-f23c-4f7e-a6f3-6d34f78984bb +:END: +#+title: books-org-agenda +#+filetags: :books:org:index: +#+DATE: 2025-05-19 +#+STARTUP: content + +* Books +** English Books +*** Teaching the Students the method of Studying +:PROPERTIES: +:Author: Sheikh Burhanul Islam Az-Zarnuji (tr. by Moulana Ebrahim Muhammad) +:Status: Read +:Group: Reading +:STARTED: <2024-07-01 Mon> +:FINISHED: <2024-07-12 Fri> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 11 +:DAYS_SINCE_FINISHED: 499 +:END: +*** A gift for nikah +:PROPERTIES: +:Author: Shaykh Abdul Raheem sahib DB +:Status: Read +:Group: Reading +:STARTED: <2024-10-28 Mon> +:FINISHED: <2024-10-29 Tue> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 1 +:DAYS_SINCE_FINISHED: 390 +:END: +*** The etiquette of Studying Hadith +:PROPERTIES: +:Author: Moulana Saleem Dhorab Sahib DB +:Status: Read +:Group: Reading +:STARTED: <2024-07-01 Mon> +:Finished: <2024-07-02 Tue> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 1 +:DAYS_SINCE_FINISHED: 509 +:END: +Read again on Tuesday 19th August 2025 + +*** The value of Time +:PROPERTIES: +:Author: Abdul Fattah Abu Ghuddah رح +:Status: Read +:Group: Reading +:STARTED: <2024-03-17 Sun> +:FINISHED: <2024-04-05 Fri> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 19 +:DAYS_SINCE_FINISHED: 597 +:END: +*** Naqshe Hayat +:PROPERTIES: +:Author: Shaykh Husain Ahmad Madani رح +:Status: Read +:Group: Reading +:STARTED: <2025-07-24 Thu> +:FINISHED: <2025-09-09 Tue> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 47 +:DAYS_SINCE_FINISHED: 75 +:END: +*** The Tafsir of Surah Nuh +:PROPERTIES: +:Author: Shaykh Abdul Raheem sahib DB +:Status: Read +:Group: Reading +:STARTED: <2024-09-24 Tue> +:FINISHED: <2025-09-10 Wed> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 351 +:DAYS_SINCE_FINISHED: 74 +:END: +*** The Path To Perfection +:PROPERTIES: +:Author: Shaikh Masihullah Khan +:Status: Read +:Group: Reading +:STARTED: <2024-07-17 Wed> +:FINISHED: <2025-09-12 Fri> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 422 +:DAYS_SINCE_FINISHED: 72 +:END: +*** An Introduction to the Science of Noble Hadith +:PROPERTIES: +:Author: Mufti Muadh Chatti DB +:Status: Reading +:Group: Reading +:STARTED: <2025-09-11 Thu> +:CATEGORY: Reading +:END: +*** Seeratul Mustafa Abridged +:PROPERTIES: +:Author: Mowlana Idrees Khandehlawi رح +:Status: Reading +:Group: Reading +:STARTED: <2025-09-12 Fri> +:CATEGORY: Reading +:END: + +*** Kanzul Bari +:PROPERTIES: +:Author: Shaykh Mufti Saiful Islam DB +:Status: Reading +:Group: Reading +:STARTED: <2025-07-24 Thu> +:CATEGORY: Reading +:END: + + +*** Hadith Scholarship in the Indian Subcontinent +:PROPERTIES: +:Author: Mawlana Muntasir Zaman +:Status: To Read +:Group: Reading +:STARTED: +:CATEGORY: To Read +:END: +*** Bidayat as-Sul Fi Tafdil ar-Rasul (The Beginning Of The Quest Of The High Esteem Of The Messenger ﷺ) +:PROPERTIES: +:Author: Imam 'Izz ibn 'Abd al-Salam رح (Translated by Aisha Bewley) +:Status: To Read +:Group: Reading +:STARTED: <2025-09-17 Wed> +:CATEGORY: To Read +:END: +*** Influence of The Noble Hadith Upon Differences of Opinion Amongst The Jurist Imams + :PROPERTIES: + :Author: Shaykh Muhammad Awwamah DB + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: +*** Muhammadﷺ: A Quranic Exposition of His Excellence and Virtues + :PROPERTIES: + :Author: Shaykh Yusuf al-Nabahani رح; Amjad Mahmood (translation) + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** Beneficial Epistle & Decisive Proof on Science of Divine Unity + :PROPERTIES: + :Author: Muhammad Salih al-Furfur رح; Amjad Mahmood (translation) + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** Seekers Aid, Manual on Creed & Hanafi Fiqh, Is'af Muridin Li +:PROPERTIES: +:Author: Abd al-Ghani al-Ghunaymi al-Maydani رح; Amjad Mahmood (translation) +:Status: To Read +:Group: Reading +:STARTED: +:CATEGORY: To Read +:END: +*** Muhammad ﷺ As If You Can See Him + :PROPERTIES: + :Author: A'id ibn 'Abdullah al-Qarni + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** How The Messenger Of Allah ﷺ Taught His Students + :PROPERTIES: + :Author: Jahangir Mahmud + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** The Life of Muhammad ﷺ + :PROPERTIES: + :Author: Imam Yahya bin Sharaf An-Nawawi رح + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** The prophet Muhammed ﷺ the best of all husbands + :PROPERTIES: + :Author: Dr. Ghazi Al-Shammari + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: + +*** The Tafsir of Surah Dahr + :PROPERTIES: + :Author: Shaykh Abdul Raheem sahib DB + :Status: To Read + :Group: Reading + :CATEGORY: To Read + :END: +*** The Tafsir of Surah Maryam + :PROPERTIES: + :Author: Shaykh Abdul Raheem sahib DB + :Status: To Read + :Group: Reading + :STARTED: <2024-10-28 Mon> + :CATEGORY: To Read + :END: +*** The Tafsir of Surah Fatiha + :PROPERTIES: + :Author: Shaykh Abdul Raheem sahib DB + :Status: To Read + :Group: Reading + :STARTED: + :CATEGORY: To Read + :END: +*** The Tafsir of Surah Yusuf +:PROPERTIES: +:Author: Shaykh Abdul Raheem sahib DB +:Status: To Read +:Group: Reading +:STARTED: +:CATEGORY: To Read +:END: +** Arabic Books +*** A المنهج المفيد لطلب علم الحديث +:PROPERTIES: +:Author: سيد عبد الماجد الغوري +:Status: Studied O +:Group: Study +:From: additional study book +:STARTED: <2024-07-20 Sat> +:Finished: <2024-08-30 Fri> +:CATEGORY: Studied O +:TOTAL_DAYS_SPENT: 41 +:DAYS_SINCE_FINISHED: 450 +:END: +*** A مختصر سيرة النبي وأصحابه العشرة +:PROPERTIES: +:Author: عبد الغني المقدسي رح +:Status: Reading +:Group: Reading +:STARTED: <2024-09-05 Thu> +:CATEGORY: Reading +:END: +*** A الإسناد من الدين وصفحة مشرقة من تاريخ سماع الحديث عند المحدثين +:PROPERTIES: +:Author: Abdul Fattah Abu Ghuddah رح +:Status: To Read +:Group: Reading +:STARTED: <2024-08-30 Fri> +:CATEGORY: To Read +:END: +** Darsi +*** A صحة ستة +**** Bukhari Shareef +:PROPERTIES: +:Author: Imam Muhammad al-Bukhari رح +:Status: To Study D +:Group: Study +:STARTED: +:CATEGORY: To Study D +:END: +**** Muslim Shareef +:PROPERTIES: +:Author: Imam Muslim ibn al-Hajjaj رح +:Status: To Study D +:Group: Study +:STARTED: +:CATEGORY: To Study D +:END: +**** Tirmizi Shareef + :PROPERTIES: + :Author: Imam al-Tirmidhi (Abu Isa Muhammad ibn Isa) رح + :Status: To Study D + :Group: Study + :STARTED: + :CATEGORY: To Study D + :END: +**** Nisai Shareef + :PROPERTIES: + :Author: Imam al-Nasa'i (Ahmad ibn Shu'ayb) رح + :Status: To Study D + :Group: Study + :STARTED: + :CATEGORY: To Study D + :END: +**** Ibn Majah Shareef + :PROPERTIES: + :Author: Imam Ibn Majah (Muhammad ibn Yazid) رح + :Status: To Study D + :Group: Study + :STARTED: + :CATEGORY: To Study D + :END: +**** Abu Dawoud Shareef + :PROPERTIES: + :Author: Imam Abu Dawood (Sulayman ibn al-Ash'ath) رح + :Status: To Study D + :Group: Study + :STARTED: + :CATEGORY: To Study D + :END: +*** A مشكاة +**** Mishkat Shareef +:PROPERTIES: +:Author: Muḥammad ibn ʻAbd Allāh Khatib Al-Tabrizi رح +:Status: Studied D +:Group: Study +:STARTED: <2024-08-12 Mon> +:FINISHED: <2025-07-18 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 340 +:DAYS_SINCE_FINISHED: 128 +:END: +**** Jalalayn +:PROPERTIES: +:Author: Tafsir al-Jalalayn by Jalal ad-Din al-Mahalli and Jalal ad-Din as-Suyuti رح +:Status: Studied D +:Group: Study +:STARTED: <2024-08-12 Mon> +:FINISHED: <2025-07-18 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 340 +:DAYS_SINCE_FINISHED: 128 +:END: +**** Hidaya 3 +:PROPERTIES: +:Author: Imam murghinani رح +:Status: Studied D +:Group: Study +:STARTED: <2024-08-12 Mon> +:FINISHED: <2025-07-18 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 340 +:DAYS_SINCE_FINISHED: 128 +:END: +**** Hidaya 4 +:PROPERTIES: +:Author: Imam murghinani رح +:Status: Studied D +:Group: Study +:STARTED: <2024-08-12 Mon> +:FINISHED: <2025-07-18 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 340 +:DAYS_SINCE_FINISHED: 128 +:END: +*** English Books +**** Tasheel Nahw +:PROPERTIES: +:Author: maulana mushtaq ahmad charthawli رح +:Status: Studied D +:Group: Study +:STARTED: <2019-07-01 Mon> +:Finished: <2022-07-01 Fri> +:CATEGORY: Studied D +:TOTAL_DAYS_SPENT: 1096 +:DAYS_SINCE_FINISHED: 1241 +:END: +**** Hadith Terminology and Classification, A handbook. +:PROPERTIES: +:Author: Muhammad S. ar-Rahwan +:Status: To Study O +:Group: Study +:From: additional study book +:STARTED: +:CATEGORY: To Study O +:END: + +*** References/Sharh +**** A تفسير أبي السعود +:PROPERTIES: +:Author: أبي السعود محمد العمادي رح +:Volumes: 9 +:Status: Voluminous +:Group: Study +:CATEGORY: Voluminous +:END: +**** A مرقاۃ المفاتیح شرح مشکوۃ المصابیح +:PROPERTIES: +:Author: Mullah Ali Qari رح +:Volumes: 11 +:Status: Voluminous +:Group: Study +:CATEGORY: Voluminous +:END: +**** A عمدة القاري شرح صحيح البخاري +:PROPERTIES: +:Author: Allamah Ayni رح +:Volumes: 20 +:Status: Voluminous +:Group: Study +:STARTED: <2025-05-29 Thu> +:CATEGORY: Voluminous +:END: + +** Guide +:Status: Reading | To Read | Read | Studying D | Studying O | To Study D | To Study O | Studied D | Studied O | Reference | Voluminous +:Group: Reading | Study +:Agenda: Books I am Studying (Darsi) | Books I am Studying (Outside) | Books To Study (Darsi) | Books To Study (Outside) | Books Studied (Darsi) | Books Studied (Outside) | Reference Books | Voluminous Books + +* Other Books +** The Science of Self-Discipline +:PROPERTIES: +:Author: Peter Hollins +:Status: Others Read +:Group: Other +:STARTED: <2024-12-27 Fri> +:FINISHED: <2025-05-24 Sat> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 148 +:DAYS_SINCE_FINISHED: 183 +:END: +** So good they cant ignore you +:PROPERTIES: +:Author: Cal newport +:Status: Others Read +:Group: Other +:STARTED: <2025-05-25 Sun> +:FINISHED: <2025-06-15 Sun> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 21 +:DAYS_SINCE_FINISHED: 161 +:END: +** The Clean Coder +:PROPERTIES: +:Author: Robert C. Martin +:Status: Others Read +:Group: Other +:STARTED: <2025-07-15 Tue> +:FINISHED: <2025-07-27 Sun> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 12 +:DAYS_SINCE_FINISHED: 119 +:END: +** Clean Code +:PROPERTIES: +:Author: Robert C. Martin +:Status: Others Reading +:Group: Other +:STARTED: <2025-07-28 Mon> +:CATEGORY: Reading +:END: +** The Toyota Way +:PROPERTIES: +:Author: Jeffry Liker +:Status: Others Read +:Group: Other +:STARTED: <2025-10-13 Mon> +:FINISHED: <2025-11-22 Sat> +:CATEGORY: Read +:TOTAL_DAYS_SPENT: 40 +:DAYS_SINCE_FINISHED: 1 +:END: +** Agile Testing +:PROPERTIES: +:Author: Lisa Crispin +:Status: Others Reading +:Group: Other +:STARTED: <2025-10-13 Mon> +:CATEGORY: Reading +:END: + + + +** Guide: +:Status: Others Reading | Others Read | Others To Read +:Group: Other diff --git a/20250727120306-nextcloud.org b/20250727120306-nextcloud.org new file mode 100644 index 0000000..bd2bc22 --- /dev/null +++ b/20250727120306-nextcloud.org @@ -0,0 +1,59 @@ +:PROPERTIES: +:ID: 56f39be4-1108-4020-be5a-1f3a0fbf96fa +:END: +#+title: nextcloud +#+filetags: :self-hosting: + +* The docker file: + +#+begin_src bash + + version: '3.8' + services: + app: + image: nextcloud + restart: unless-stopped + ports: + - 8007:80 + volumes: + - nextcloud:/var/www/html + environment: + - POSTGRES_DB=nextcloud + - POSTGRES_USER=nextcloud + - POSTGRES_PASSWORD=zxq123_nextcloud + - POSTGRES_HOST=postgres + networks: + - postgres_network + + volumes: + nextcloud: + + networks: + postgres_network: + external: true + +#+end_src + +* Database related things: + +#+begin_src bash + + zxq_db=# CREATE DATABASE nextcloud; + CREATE DATABASE + zxq_db=# CREATE USER nextcloud WITH PASSWORD 'zxq123_nextcloud'; + CREATE ROLE + zxq_db=# GRANT ALL PRIVILEGES ON DATABASE nextcloud TO nextcloud; + GRANT + zxq_db=# + +#+end_src + + + + +* Config + +Location is: + +sudo nano /var/lib/docker/volumes/nextcloud_nextcloud/_data/config/config.php + diff --git a/20250727120306-nextcloud.org~ b/20250727120306-nextcloud.org~ new file mode 100644 index 0000000..49c38df --- /dev/null +++ b/20250727120306-nextcloud.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: 56f39be4-1108-4020-be5a-1f3a0fbf96fa +:END: +#+title: nextcloud + diff --git a/20250727121051-networking_moc.org b/20250727121051-networking_moc.org new file mode 100644 index 0000000..383babb --- /dev/null +++ b/20250727121051-networking_moc.org @@ -0,0 +1,8 @@ +:PROPERTIES: +:ID: 0880f089-a5ad-49cd-8ce3-f020a5941313 +:END: +#+title: networking-moc +#+filetags: :moc:networking: + +[[id:99533f2d-a4e8-41d0-a605-c7d4cef6f995][self_hosting]] + diff --git a/20250727122406-database_main.org~ b/20250727122406-database_main.org~ new file mode 100644 index 0000000..a9f09c5 --- /dev/null +++ b/20250727122406-database_main.org~ @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: e448cd99-afee-4702-947f-644bb34dc1aa +:END: +#+title: database-main +#+filetags: :database:index: + +[[id:939e301b-6463-46a8-b57e-0af606e7e7ef][postgres]] diff --git a/20250727122406-database_moc.org b/20250727122406-database_moc.org new file mode 100644 index 0000000..8d28807 --- /dev/null +++ b/20250727122406-database_moc.org @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: e448cd99-afee-4702-947f-644bb34dc1aa +:END: +#+title: database_moc +#+filetags: :database:moc: + +[[id:939e301b-6463-46a8-b57e-0af606e7e7ef][postgres]] diff --git a/20250727122406-database_moc.org~ b/20250727122406-database_moc.org~ new file mode 100644 index 0000000..3d6cc61 --- /dev/null +++ b/20250727122406-database_moc.org~ @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: e448cd99-afee-4702-947f-644bb34dc1aa +:END: +#+title: database_moc +#+filetags: :moc: + +[[id:939e301b-6463-46a8-b57e-0af606e7e7ef][postgres]] diff --git a/20250727174809-books_main.org~ b/20250727174809-books_main.org~ new file mode 100644 index 0000000..5964f1d --- /dev/null +++ b/20250727174809-books_main.org~ @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: 63314cff-3a3f-49b4-9e76-4a359c51f55f +:END: +#+title: books-main +#+filetags: :index:books: + + +* Notes for books: [[id:2706598f-e6aa-4e88-8d24-5f699bd22787][Book Notes]] + +* Recommendations for books: [[id:238ff7d8-db22-41e2-8aad-fc3c778e6248][book-recs]] + +* [[id:363dbdfa-f23c-4f7e-a6f3-6d34f78984bb][books-org-agenda]] diff --git a/20250727174809-books_moc.org b/20250727174809-books_moc.org new file mode 100644 index 0000000..3a968b4 --- /dev/null +++ b/20250727174809-books_moc.org @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: 63314cff-3a3f-49b4-9e76-4a359c51f55f +:END: +#+title: books_moc +#+filetags: :moc:books: + + +* Notes for books: [[id:2706598f-e6aa-4e88-8d24-5f699bd22787][book_notes]] + +* Recommendations for books: [[id:238ff7d8-db22-41e2-8aad-fc3c778e6248][book-recs]] + +* [[id:363dbdfa-f23c-4f7e-a6f3-6d34f78984bb][books-org-agenda]] diff --git a/20250727174809-books_moc.org~ b/20250727174809-books_moc.org~ new file mode 100644 index 0000000..b17112b --- /dev/null +++ b/20250727174809-books_moc.org~ @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: 63314cff-3a3f-49b4-9e76-4a359c51f55f +:END: +#+title: books-moc +#+filetags: :moc:books: + + +* Notes for books: [[id:2706598f-e6aa-4e88-8d24-5f699bd22787][Book Notes]] + +* Recommendations for books: [[id:238ff7d8-db22-41e2-8aad-fc3c778e6248][book-recs]] + +* [[id:363dbdfa-f23c-4f7e-a6f3-6d34f78984bb][books-org-agenda]] diff --git a/20250727174903-book_recs.org b/20250727174903-book_recs.org new file mode 100644 index 0000000..71221d4 --- /dev/null +++ b/20250727174903-book_recs.org @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: 238ff7d8-db22-41e2-8aad-fc3c778e6248 +:END: +#+title: book-recs +#+filetags: :books: + + +* [[https://www.youtube.com/watch?v=qF6LQX-9p2I&list=LL&index=1&ab_channel=EmacsElements][Link]] +- The Unix Programming Environment by Brian W. Kernighan and Rob Pike +- An Introduction to Programming in Emacs Lisp by Robert J. Chassell +- GNU Emacs Manual by Richard M, Stallman diff --git a/20250727174903-book_recs.org~ b/20250727174903-book_recs.org~ new file mode 100644 index 0000000..662be68 --- /dev/null +++ b/20250727174903-book_recs.org~ @@ -0,0 +1,11 @@ +:PROPERTIES: +:ID: 238ff7d8-db22-41e2-8aad-fc3c778e6248 +:END: +#+title: book-recs +#+filetags: :books:list: + + +* [[https://www.youtube.com/watch?v=qF6LQX-9p2I&list=LL&index=1&ab_channel=EmacsElements][Link]] +- The Unix Programming Environment by Brian W. Kernighan and Rob Pike +- An Introduction to Programming in Emacs Lisp by Robert J. Chassell +- GNU Emacs Manual by Richard M, Stallman diff --git a/20250727221512-clean_code.org b/20250727221512-clean_code.org new file mode 100644 index 0000000..c45203b --- /dev/null +++ b/20250727221512-clean_code.org @@ -0,0 +1,624 @@ +:PROPERTIES: +:ID: dd55d635-59de-4ed9-8ff0-423782c2e0ae +:TYPE: Book +:AUTHOR: Robert C. Martin +:DATE_STARTED: <2025-07-28 Mon> +:DATE_ENDED: +:END: +#+title: clean-code +#+filetags: :books: + +* Chapter 1: Clean Code + +Referenced Items: +- Implementation Patterns, Kent Beck, Addison-Wesley, 2007. +- Literate Programming, Donald E. Knuth, Center for the Study of Language and Information, Leland Stanford Junior University, 1992. + +Principles mentioned: +Single Responsibility Principle (SRP), the Open Closed Principle (OCP), and the Dependency Inversion Principle (DIP) + +* Chapter 2: Meaningful Names + +** Use intention revealing names: + +Names should reveal intent, there is no revelation in naming an integer ~d~, intending it stands for days. Instead, you should use the following names: +#+begin_src java + int elapsedTimeInDays; + int daysSinceCreation; + int daysSinceModification; + int fileAgeInDays; +#+end_src + +** Avoid disinformation + +Don't postfix the word 'list' to the name 'accounts' unless it's actually a list. This is because the reader will /assume/ the data type of accountsList is indeed a list, instead choose a name like ~accountsGroup~. + +** Make Meaningful Distinctions + +While it is possible to name by being disinformative, it is also possible to name being non informative. Consider: + +#+begin_src java + + public static void copyChars(char a1[], char a2[]) { + for (int i = 0; i < a1.length; i++) { + a2[i] = a1[i]; + } + } + +#+end_src + +What on earth does ~a[1]~ and ~a[2]~ even stand for? We are better off using names like source and destination (due to the function's intent of copying the array). + +Furthermore, noise words are redundant. We should never use the word ~variable~ when naming a variable, or ~table~ when naming a table. +** Use Pronouncable Names + +This is quite straightforward. Do not use a name like ~genymdhms~ to refer to generation date, year, month, day, hour, minute, +and second. Instead use ~generationTimeStamp~. + +** Use Searchable Names + +In modern IDE's, it is still quite difficult to search for single-lettered variables. The writer states a personal preference of using single-letter names only as local variables and inside short methods. The following principle is given: + +/The length of a name should correspond to the size of its scope/ + +** Avoid Encodings + +Don't prefix variables with letters like m_ as was done in the past. Do not type encode as well, an example of this is: ~PhoneNumber phoneString;~ we can see the reader being misled into thinking the phone number is a String. + +** Avoid Mental Mappings + +Clarity is king, don't use a name for a variable that only you know what it stands for. For example: using the letter r as the lower-cased version of the url with the host and scheme +removed. That's being smart, not professional. + +** Class Names + +#+BEGIN_QUOTE +Classes and objects should have noun or noun phrase names like Customer, WikiPage, +Account, and AddressParser. Avoid words like Manager, Processor, Data, or Info in the name +of a class. A class name should not be a verb. +#+END_QUOTE + +{{{epigraph_single(Classes and objects should have noun or noun phrase names like Customer\, WikiPage\, +Account\, and AddressParser. Avoid words like Manager\, Processor\, Data\, or Info in the name +of a class. A class name should not be a verb)}}} + +** Method Names + +Methods should have verb or verb phrase names. + +** Don't be cute/Don't use puns + +Do not use names that are only understandable to people whom you share jokes etc with. Furthermore, do not use colloquialism and slang in names. +- Example: ~HandGrenade~ instead of ~DeleteItems~ +- Example: ~whack()~ instead of ~kill()~ + +** Pick one word per concept + +If you have multiple choices for naming a concept, use one and stick with it. For instance if your options are fetch, get and retrieve, use one and stick with it throughout. + +** Solution Domain Names and Problem Domain Names + +Where possible use solution domain names, as the people that are going to be reading the code are programmers. Therefore, do not shy away from using CS terms, algorithm names, math names and so forth. + +However when it is not possible to use solution domain names (in other words, when there is no "programmer-eese" then use the name from the problem domain. The other programmers can ask the domain expert for clarification. If the code is more to do with the problem domain concepts, then the names should be drawn from them. + +** Add Meaningful Context + +Enclose names with well-named classes, functions, or namespaces. When all else fails, then prefix with something that provides more context. + +** Don't add gratuitous context + +Shorter names are better than longer ones, generally. This is so long as the context and intent is clear. Don't add redundant or irrelevant additions to the name in the for the sake of 'context'. + +* Chapter 3: Functions + +** Functions should be small + +Functions should be extremely short—ideally just a few lines, so they remain easy to understand and maintain. + +Avoid deeply nested blocks; keep indentation shallow (1–2 levels), often replacing blocks with descriptive function calls. + +A small function tells a concise, self-contained story, making it easier for readers to follow the program’s intent. + +The smaller the function, the more descriptive and accurate its name can be, improving self-documentation. + +Large functions hide complexity and mix abstraction levels, making errors and duplication more likely. + +** Do One Thing & One Level of Abstraction + +A function should do exactly one conceptual task, and all its statements should exist at the same abstraction level. + +Mixing details (like string concatenation) with high-level actions (like rendering a page) causes confusion. + +The Stepdown Rule: organise functions so they read like a top down narrative, each calling the next abstraction level. + +If you can extract a subfunction with a name that isn’t a restatement, the original function is doing too much. + +Functions that “do one thing” cannot be logically split into sections such as “initialize,” “process,” “finalize.” + +** Switch Statements + +Switch statements naturally violate “do one thing” by handling multiple cases; they also grow in size over time. + +They break the Single Responsibility Principle (multiple reasons to change) and Open-Closed Principle (must change for new cases). + +Preferred approach: hide switch statements inside a factory and dispatch behavior polymorphically through an interface. + +Allow only one visible switch in your system, used solely for object creation, then encapsulate it. + +This removes duplication and keeps high-level code unaware of concrete type distinctions. + +Example: + +#+begin_src java + public abstract class Employee { + public abstract boolean isPayday(); + public abstract Money calculatePay(); + public abstract void deliverPay(Money pay); + } + ----------------- + public interface EmployeeFactory { + public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType; + } + ----------------- + public class EmployeeFactoryImpl implements EmployeeFactory { + public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType { + switch (r.type) { + case COMMISSIONED: + return new CommissionedEmployee(r) ; + case HOURLY: + return new HourlyEmployee(r); + case SALARIED: + return new SalariedEmploye(r); + default: + throw new InvalidEmployeeType(r.type); + } + } + } + +#+end_src + +** Use Descriptive Names + +A function’s name should clearly state its purpose. Long, descriptive names beat short, cryptic ones. + +Consistent naming patterns (shared verbs/nouns) help code read like a coherent story and aid predictability. + +Descriptive names reduce the need for comments and improve comprehension without external documentation. + +Renaming functions can reveal design improvements, so try multiple options until the best emerges. + +IDE refactoring tools make renaming safe, encouraging experimentation. + +** Function Arguments + +{{{epigraph_single(The ideal number of arguments for a function is zero (niladic). Next comes one (monadic)\, followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn’t be used anyway.)}}} + +Fewer arguments = better; aim for 0–2, avoid more than 3 unless absolutely necessary. + +Flag arguments (booleans) are a red flag—they imply the function does multiple things. + +Group related parameters into objects (e.g., ~Point~ for ~x~ and ~y~) to reduce argument count and improve clarity. + +Output arguments are confusing—prefer returning values or mutating the owning object’s state. + +Match function/argument names in verb–noun or keyword style (e.g., ~writeField(name)~, ~assertExpectedEqualsActual~). + +** Have No Side Effects + +A function should do only what its name promises. Hidden state changes are misleading and dangerous. + +Side effects create temporal coupling, meaning the function must be called in a certain sequence to be safe. + +If unavoidable, make side effects explicit in the name (e.g., ~checkPasswordAndInitializeSession~). + +Clear separation of command and query functions avoids ambiguity in meaning and intent. + +Functions that modify state and return information often cause confusion and should be split. + +** Error Handling + +Error handling is a single responsibility—separate it from normal logic to keep both paths clear. + +Prefer exceptions over error codes to avoid cluttering the happy path and to reduce dependency magnets. + +Extract try/catch bodies into their own functions for cleaner structure. + +See below: + +#+begin_src java + + public void delete(Page page) { + try { + deletePageAndAllReferences(page); + } + catch (Exception e) { + logError(e); + } + } + + private void deletePageAndAllReferences(Page page) throws Exception { + deletePage(page); + registry.deleteReference(page.name); + configKeys.deleteKey(page.name.makeKey()); + } + private void logError(Exception e) { + logger.log(e.getMessage()); + } + +#+end_src + +Keep functions small enough that occasional multiple return or break statements are acceptable. + +Avoid duplication in error handling, and follow the DRY principle to ensure changes occur in one place. + +* Chapter 4: Comments + +Comments are a necessary evil—they exist because code fails to express intent clearly. + +Outdated comments are dangerous; they can mislead more than help. + +Strive to write code that explains itself; comments should be minimized. + +Truth is always in the code, not in the comments. + +** Comments Do Not Make Up for Bad Code + +Don’t use comments to excuse messy, unclear code—clean the code instead. + +Clear, expressive code with few comments > cluttered code with many comments. + +#+begin_src java + + // Check to see if the employee is eligible for full benefits + if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) + + // Better: + if (employee.isEligibleForFullBenefits()) + +#+end_src + +** Good Comments + +Only write them when unavoidable. + +** Legal Comments + +Sometimes required for copyright/licensing. + +Keep them short; refer to standard licenses rather than embedding full legal text. + +** Informative Comments + +Explain return values, formats, or patterns. + +Prefer naming/structuring code to make such comments unnecessary. + +#+begin_src java + + // format matched kk:mm:ss EEE, MMM dd, yyyy + Pattern timeMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*"); + +#+end_src + + +** Explanation of Intent + +Describe why a certain approach was chosen. + +Helps future maintainers understand reasoning behind code. + +return 1; // we are greater because we are the right type. + +** Clarification + +Translate obscure values into readable terms. + +Useful when working with unchangeable APIs/libraries, but risky if incorrect. + +** Warning of Consequences + +Alert others about performance, thread-safety, or side effects. + +// SimpleDateFormat is not thread safe, so create each instance independently. + +** \TODO\ Comments + +Mark incomplete work or planned improvements. + +Should be reviewed regularly; not an excuse for bad code. + +** Amplification + +Highlight the importance of seemingly small details. + +// the trim is real important. It removes starting spaces... + +** Javadocs in Public APIs + +Public APIs should have clear documentation. + +Javadocs can also mislead—keep them accurate and up-to-date. + +** Don’t Use a Comment When You Can Use a Function or Variable + +Replace explanatory comments with expressive variable or function names. + +Refactor code to remove comment redundancy. + +** Position Markers + +Avoid decorative banners like // Actions ///////////////////////—they add clutter. + +Use sparingly and only for meaningful grouping. + +Overuse makes them blend into background noise. + +** Closing Brace Comments + +Comments on closing braces (} // while) are unnecessary for small, well-structured functions. + +Prefer short, clear functions over brace markers. + +** Attributions and Bylines + +Don’t add personal tags like /* Added by Rick */—use version control for authorship history. + +Such comments become outdated and irrelevant over time. + +** Commented-Out Code + +Never keep old code commented out; delete it and rely on version control history. + +Commented-out code adds clutter and confuses future maintainers. + +#+begin_src java + + // Old cruft that should be deleted: + //hdrPos = bytePos; + //dataPos = bytePos; + +#+end_src + +** HTML Comments + +Avoid HTML markup inside code comments—it makes them harder to read in the editor. + +Let documentation tools (like Javadoc) handle formatting. + +** Nonlocal Information + +Comments should describe nearby code only, not unrelated parts of the system. + +Avoid embedding global/system details that the function can’t control. + +** Too Much Information + +Avoid long, unnecessary historical or technical explanations. + +Keep only relevant context (e.g., “RFC 2045” reference is fine, not the full spec). + +** Inobvious Connection + +Ensure the relationship between comment and code is clear. + +Don’t make readers guess what part of the code the comment refers to. + +#+begin_src java + + // plus filter bytes ... but which part is “filter”? + this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200]; + +#+end_src + +** Function Headers + +Short, single-purpose functions with good names don’t need header comments. + +Let the function name explain the purpose. + +** Javadocs in Nonpublic Code + +Javadocs are useful for public APIs, but excessive formality in internal code is just noise. + +Internal methods should be self-explanatory without full doc comments. + +** Example: Refactored Prime Generator + +Original code: Over-commented, with redundant explanations and irrelevant history. + +Refactored version: Only two comments remain—both explain why, not what. + +One eases the reader into the algorithm. + +One explains rationale for using the square root as a loop limit. + +* Chapter 5: Formatting +** Vertical Formatting (Clean Code, Ch.5) + +*** Vertical Formatting +- Vertical openness (blank lines) separates concepts and improves readability. +- Too much density makes code look like a muddle and harder to scan. + +*** Vertical Density +- Tightly related lines should appear vertically dense. +- Avoid useless comments that interrupt association. +- Example (bad): +#+BEGIN_SRC java + public class ReporterConfig { + /** + ,* The class name of the reporter listener + ,*/ + private String m_className; +#+END_SRC + +- Example (better): +#+BEGIN_SRC java +public class ReporterConfig { +private String m_className; +private List m_properties = new ArrayList<>(); +#+END_SRC + +*** Vertical Distance +- Related concepts should be kept close together to reduce scrolling and searching. +- Local variables → as close to use as possible, usually at top of function. +- Control variables → declared inside loop headers. +- Instance variables → declared at the top of class (common Java convention). + +#+BEGIN_SRC java +for (Test each : tests) { + count += each.countTestCases(); +} +#+END_SRC + +- Dependent functions: caller above callee for natural top-down reading. +#+BEGIN_SRC java +public Response makeResponse(...) { + String pageName = getPageNameOrDefault(request, "FrontPage"); + loadPage(pageName, context); + return makePageResponse(context); +} + +private String getPageNameOrDefault(Request request, String defaultPageName) { ... } +#+END_SRC + +*** Conceptual Affinity +- Group functions with similar naming or shared purpose. +- Example (JUnit assert methods): +#+BEGIN_SRC java +static public void assertTrue(String message, boolean condition) { ... } +static public void assertTrue(boolean condition) { ... } +static public void assertFalse(String message, boolean condition) { ... } +static public void assertFalse(boolean condition) { ... } +#+END_SRC + +*** Vertical Ordering +- Organise code top down: + - High-level concepts first (main logic). + - Lower-level details later. +- Readers can skim like a newspaper: important first, details last. +- Contrast: C/C++ require declarations before use, Java does not. + +*** Summary - vertical +- Use vertical openness to separate concepts. +- Use vertical density to group related ones. +- Keep related variables, methods, and concepts close together. +- Order code top down for natural readability. + +** Horizontal Formatting + +Keep lines short — most professional code naturally stays within ~45 characters, with ~80 as an upper bound. Lines beyond 100–120 characters are generally careless. + +Avoid shrinking font or overly wide monitors to fit more code — readability > fitting more characters. + +Example limit guideline: + +#+begin_src java + // Good (short) + int sum = a + b + c; + + // Bad (too long) + int sum = a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q; +#+end_src +** Horizontal Openness and Density + +Use spaces to separate low-precedence operators (e.g., +, -, =) and improve readability. + +Do not put spaces between function names and parentheses — they are closely related. + +Example (Quadratic formula formatting): + +#+begin_src java + return (-b + Math.sqrt(determinant)) / (2*a); +#+end_src + +Separate arguments with spaces after commas to show distinct parameters. + +** Horizontal Alignment +Avoid aligning variable declarations or assignments in columns — it draws the eye to the wrong place. + +Long aligned lists usually mean the class is too large and should be split. + +Example (preferred unaligned): + +#+begin_src java + // Prefer this: + private Socket socket; + private InputStream input; + private OutputStream output; + + //instead of: + private Socket socket; + private InputStream input; + private OutputStream output; + +#+end_src + +** Indentation + +Indent according to scope hierarchy: + +Classes → no indent + +Methods → 1 level + +Method bodies → 2 levels + +Inner blocks → +1 for each nesting + +Indentation makes scopes visually obvious; without it, code is hard to scan. + +Avoid collapsing scopes onto one line — always use braces and proper indenting. + +** Dummy Scopes + +Avoid dummy bodies in loops (e.g., empty while or for loops). + +If unavoidable, place semicolon on its own indented line to make it visible. + +#+begin_src java + while (dis.read(buf, 0, size) != -1) + ; +#+end_src + +** Team Rules + +Teams must agree on a single formatting style for consistency. + +Use IDE formatters to enforce these rules across all files. + +Consistent formatting builds trust and reduces mental load for readers. + +** Uncle Bob’s Formatting Rules (Example in CodeAnalyzer.java) + +Short, clear methods with consistent spacing and indentation. + +Use spaces around assignment and low-precedence operators, no space for high-precedence operators. + +Avoid deeply nested structures — prefer clear, flat logic. + +Example snippet: + +#+begin_src java + private void measureLine(String line) { + lineCount++; + int lineSize = line.length(); + totalChars += lineSize; + lineWidthHistogram.addLine(lineSize, lineCount); + recordWidestLine(lineSize); + } +#+end_src + +* Chapter 6: Objects and Data Structures +* Chapter 7: Error Handling +* Chapter 8: Boundaries +* Chapter 9: Unit Tests +* Chapter 10: Classes +* Chapter 11: Systems +* Chapter 12: Emergence +* Chapter 13: Concurrency +* Chapter 14: Successive Refinement +* Chapter 15: JUnit Internals +* Chapter 16: Refactoring SerialDate +* Chapter 17: Smells and Heuristics +* Apendix A: Concurrency II diff --git a/20250727221512-clean_code.org~ b/20250727221512-clean_code.org~ new file mode 100644 index 0000000..0a4e695 --- /dev/null +++ b/20250727221512-clean_code.org~ @@ -0,0 +1,612 @@ +:PROPERTIES: +:ID: dd55d635-59de-4ed9-8ff0-423782c2e0ae +:TYPE: Book +:AUTHOR: Robert C. Martin +:DATE_STARTED: <2025-07-28 Mon> +:DATE_ENDED: +:END: +#+title: clean-code +#+filetags: :books: + +* Chapter 1: Clean Code + +Referenced Items: +- Implementation Patterns, Kent Beck, Addison-Wesley, 2007. +- Literate Programming, Donald E. Knuth, Center for the Study of Language and Information, Leland Stanford Junior University, 1992. + +Principles mentioned: +Single Responsibility Principle (SRP), the Open Closed Principle (OCP), and the Dependency Inversion Principle (DIP) + +* Chapter 2: Meaningful Names + +** Use intention revealing names: + +Names should reveal intent, there is no revelation in naming an integer ~d~, intending it stands for days. Instead, you should use the following names: +#+begin_src java + int elapsedTimeInDays; + int daysSinceCreation; + int daysSinceModification; + int fileAgeInDays; +#+end_src + +** Avoid disinformation + +Don't postfix the word 'list' to the name 'accounts' unless it's actually a list. This is because the reader will /assume/ the data type of accountsList is indeed a list, instead choose a name like ~accountsGroup~. + +** Make Meaningful Distinctions + +While it is possible to name by being disinformative, it is also possible to name being non informative. Consider: + +#+begin_src java + + public static void copyChars(char a1[], char a2[]) { + for (int i = 0; i < a1.length; i++) { + a2[i] = a1[i]; + } + } + +#+end_src + +What on earth does ~a[1]~ and ~a[2]~ even stand for? We are better off using names like source and destination (due to the function's intent of copying the array). + +Furthermore, noise words are redundant. We should never use the word ~variable~ when naming a variable, or ~table~ when naming a table. +** Use Pronouncable Names + +This is quite straightforward. Do not use a name like ~genymdhms~ to refer to generation date, year, month, day, hour, minute, +and second. Instead use ~generationTimeStamp~. + +** Use Searchable Names + +In modern IDE's, it is still quite difficult to search for single-lettered variables. The writer states a personal preference of using single-letter names only as local variables and inside short methods. The following principle is given: + +/The length of a name should correspond to the size of its scope/ + +** Avoid Encodings + +Don't prefix variables with letters like m_ as was done in the past. Do not type encode as well, an example of this is: ~PhoneNumber phoneString;~ we can see the reader being misled into thinking the phone number is a String. + +** Avoid Mental Mappings + +Clarity is king, don't use a name for a variable that only you know what it stands for. For example: using the letter r as the lower-cased version of the url with the host and scheme +removed. That's being smart, not professional. + +** Class Names + +#+BEGIN_QUOTE +Classes and objects should have noun or noun phrase names like Customer, WikiPage, +Account, and AddressParser. Avoid words like Manager, Processor, Data, or Info in the name +of a class. A class name should not be a verb. +#+END_QUOTE + +{{{epigraph_single(Classes and objects should have noun or noun phrase names like Customer\, WikiPage\, +Account\, and AddressParser. Avoid words like Manager\, Processor\, Data\, or Info in the name +of a class. A class name should not be a verb)}}} + +** Method Names + +Methods should have verb or verb phrase names. + +** Don't be cute/Don't use puns + +Do not use names that are only understandable to people whom you share jokes etc with. Furthermore, do not use colloquialism and slang in names. +- Example: ~HandGrenade~ instead of ~DeleteItems~ +- Example: ~whack()~ instead of ~kill()~ + +** Pick one word per concept + +If you have multiple choices for naming a concept, use one and stick with it. For instance if your options are fetch, get and retrieve, use one and stick with it throughout. + +** Solution Domain Names and Problem Domain Names + +Where possible use solution domain names, as the people that are going to be reading the code are programmers. Therefore, do not shy away from using CS terms, algorithm names, math names and so forth. + +However when it is not possible to use solution domain names (in other words, when there is no "programmer-eese" then use the name from the problem domain. The other programmers can ask the domain expert for clarification. If the code is more to do with the problem domain concepts, then the names should be drawn from them. + +** Add Meaningful Context + +Enclose names with well-named classes, functions, or namespaces. When all else fails, then prefix with something that provides more context. + +** Don't add gratuitous context + +Shorter names are better than longer ones, generally. This is so long as the context and intent is clear. Don't add redundant or irrelevant additions to the name in the for the sake of 'context'. + +* Chapter 3: Functions + +** Functions should be small + +Functions should be extremely short—ideally just a few lines, so they remain easy to understand and maintain. + +Avoid deeply nested blocks; keep indentation shallow (1–2 levels), often replacing blocks with descriptive function calls. + +A small function tells a concise, self-contained story, making it easier for readers to follow the program’s intent. + +The smaller the function, the more descriptive and accurate its name can be, improving self-documentation. + +Large functions hide complexity and mix abstraction levels, making errors and duplication more likely. + +** Do One Thing & One Level of Abstraction + +A function should do exactly one conceptual task, and all its statements should exist at the same abstraction level. + +Mixing details (like string concatenation) with high-level actions (like rendering a page) causes confusion. + +The Stepdown Rule: organise functions so they read like a top down narrative, each calling the next abstraction level. + +If you can extract a subfunction with a name that isn’t a restatement, the original function is doing too much. + +Functions that “do one thing” cannot be logically split into sections such as “initialize,” “process,” “finalize.” + +** Switch Statements + +Switch statements naturally violate “do one thing” by handling multiple cases; they also grow in size over time. + +They break the Single Responsibility Principle (multiple reasons to change) and Open-Closed Principle (must change for new cases). + +Preferred approach: hide switch statements inside a factory and dispatch behavior polymorphically through an interface. + +Allow only one visible switch in your system, used solely for object creation, then encapsulate it. + +This removes duplication and keeps high-level code unaware of concrete type distinctions. + +Example: + +#+begin_src java + public abstract class Employee { + public abstract boolean isPayday(); + public abstract Money calculatePay(); + public abstract void deliverPay(Money pay); + } + ----------------- + public interface EmployeeFactory { + public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType; + } + ----------------- + public class EmployeeFactoryImpl implements EmployeeFactory { + public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType { + switch (r.type) { + case COMMISSIONED: + return new CommissionedEmployee(r) ; + case HOURLY: + return new HourlyEmployee(r); + case SALARIED: + return new SalariedEmploye(r); + default: + throw new InvalidEmployeeType(r.type); + } + } + } + +#+end_src + +** Use Descriptive Names + +A function’s name should clearly state its purpose. Long, descriptive names beat short, cryptic ones. + +Consistent naming patterns (shared verbs/nouns) help code read like a coherent story and aid predictability. + +Descriptive names reduce the need for comments and improve comprehension without external documentation. + +Renaming functions can reveal design improvements, so try multiple options until the best emerges. + +IDE refactoring tools make renaming safe, encouraging experimentation. + +** Function Arguments + +{{{epigraph_single(The ideal number of arguments for a function is zero (niladic). Next comes one (monadic)\, followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn’t be used anyway.)}}} + +Fewer arguments = better; aim for 0–2, avoid more than 3 unless absolutely necessary. + +Flag arguments (booleans) are a red flag—they imply the function does multiple things. + +Group related parameters into objects (e.g., ~Point~ for ~x~ and ~y~) to reduce argument count and improve clarity. + +Output arguments are confusing—prefer returning values or mutating the owning object’s state. + +Match function/argument names in verb–noun or keyword style (e.g., ~writeField(name)~, ~assertExpectedEqualsActual~). + +** Have No Side Effects + +A function should do only what its name promises. Hidden state changes are misleading and dangerous. + +Side effects create temporal coupling, meaning the function must be called in a certain sequence to be safe. + +If unavoidable, make side effects explicit in the name (e.g., ~checkPasswordAndInitializeSession~). + +Clear separation of command and query functions avoids ambiguity in meaning and intent. + +Functions that modify state and return information often cause confusion and should be split. + +** Error Handling + +Error handling is a single responsibility—separate it from normal logic to keep both paths clear. + +Prefer exceptions over error codes to avoid cluttering the happy path and to reduce dependency magnets. + +Extract try/catch bodies into their own functions for cleaner structure. + +See below: + +#+begin_src java + + public void delete(Page page) { + try { + deletePageAndAllReferences(page); + } + catch (Exception e) { + logError(e); + } + } + + private void deletePageAndAllReferences(Page page) throws Exception { + deletePage(page); + registry.deleteReference(page.name); + configKeys.deleteKey(page.name.makeKey()); + } + private void logError(Exception e) { + logger.log(e.getMessage()); + } + +#+end_src + +Keep functions small enough that occasional multiple return or break statements are acceptable. + +Avoid duplication in error handling, and follow the DRY principle to ensure changes occur in one place. + + +* Chapter 4: Comments + +Comments are a necessary evil—they exist because code fails to express intent clearly. + +Outdated comments are dangerous; they can mislead more than help. + +Strive to write code that explains itself; comments should be minimized. + +Truth is always in the code, not in the comments. + +** Comments Do Not Make Up for Bad Code + +Don’t use comments to excuse messy, unclear code—clean the code instead. + +Clear, expressive code with few comments > cluttered code with many comments. + +#+begin_src java + + // Check to see if the employee is eligible for full benefits + if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) + + // Better: + if (employee.isEligibleForFullBenefits()) + +#+end_src + +** Good Comments + +Only write them when unavoidable. + +** Legal Comments + +Sometimes required for copyright/licensing. + +Keep them short; refer to standard licenses rather than embedding full legal text. + +** Informative Comments + +Explain return values, formats, or patterns. + +Prefer naming/structuring code to make such comments unnecessary. + +#+begin_src java + + // format matched kk:mm:ss EEE, MMM dd, yyyy + Pattern timeMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*"); + +#+end_src + + +** Explanation of Intent + +Describe why a certain approach was chosen. + +Helps future maintainers understand reasoning behind code. + +return 1; // we are greater because we are the right type. + +** Clarification + +Translate obscure values into readable terms. + +Useful when working with unchangeable APIs/libraries, but risky if incorrect. + +** Warning of Consequences + +Alert others about performance, thread-safety, or side effects. + +// SimpleDateFormat is not thread safe, so create each instance independently. + +** \TODO\ Comments + +Mark incomplete work or planned improvements. + +Should be reviewed regularly; not an excuse for bad code. + +** Amplification + +Highlight the importance of seemingly small details. + +// the trim is real important. It removes starting spaces... + +** Javadocs in Public APIs + +Public APIs should have clear documentation. + +Javadocs can also mislead—keep them accurate and up-to-date. + +** Don’t Use a Comment When You Can Use a Function or Variable + +Replace explanatory comments with expressive variable or function names. + +Refactor code to remove comment redundancy. + +** Position Markers + +Avoid decorative banners like // Actions ///////////////////////—they add clutter. + +Use sparingly and only for meaningful grouping. + +Overuse makes them blend into background noise. + +** Closing Brace Comments + +Comments on closing braces (} // while) are unnecessary for small, well-structured functions. + +Prefer short, clear functions over brace markers. + +** Attributions and Bylines + +Don’t add personal tags like /* Added by Rick */—use version control for authorship history. + +Such comments become outdated and irrelevant over time. + +** Commented-Out Code + +Never keep old code commented out; delete it and rely on version control history. + +Commented-out code adds clutter and confuses future maintainers. + +#+begin_src java + + // Old cruft that should be deleted: + //hdrPos = bytePos; + //dataPos = bytePos; + +#+end_src + +** HTML Comments + +Avoid HTML markup inside code comments—it makes them harder to read in the editor. + +Let documentation tools (like Javadoc) handle formatting. + +** Nonlocal Information + +Comments should describe nearby code only, not unrelated parts of the system. + +Avoid embedding global/system details that the function can’t control. + +** Too Much Information + +Avoid long, unnecessary historical or technical explanations. + +Keep only relevant context (e.g., “RFC 2045” reference is fine, not the full spec). + +** Inobvious Connection + +Ensure the relationship between comment and code is clear. + +Don’t make readers guess what part of the code the comment refers to. + +#+begin_src java + + // plus filter bytes ... but which part is “filter”? + this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200]; + +#+end_src + +** Function Headers + +Short, single-purpose functions with good names don’t need header comments. + +Let the function name explain the purpose. + +** Javadocs in Nonpublic Code + +Javadocs are useful for public APIs, but excessive formality in internal code is just noise. + +Internal methods should be self-explanatory without full doc comments. + +** Example: Refactored Prime Generator + +Original code: Over-commented, with redundant explanations and irrelevant history. + +Refactored version: Only two comments remain—both explain why, not what. + +One eases the reader into the algorithm. + +One explains rationale for using the square root as a loop limit. + + +* Chapter 5: Formatting +** Vertical Formatting (Clean Code, Ch.5) + +*** Vertical Formatting +- Vertical openness (blank lines) separates concepts and improves readability. +- Too much density makes code look like a muddle and harder to scan. + +*** Vertical Density +- Tightly related lines should appear vertically dense. +- Avoid useless comments that interrupt association. +- Example (bad): +#+BEGIN_SRC java + public class ReporterConfig { + /** + ,* The class name of the reporter listener + ,*/ + private String m_className; +#+END_SRC + +- Example (better): +#+BEGIN_SRC java +public class ReporterConfig { +private String m_className; +private List m_properties = new ArrayList<>(); +#+END_SRC + +*** Vertical Distance +- Related concepts should be kept close together to reduce scrolling and searching. +- Local variables → as close to use as possible, usually at top of function. +- Control variables → declared inside loop headers. +- Instance variables → declared at the top of class (common Java convention). + +#+BEGIN_SRC java +for (Test each : tests) { + count += each.countTestCases(); +} +#+END_SRC + +- Dependent functions: caller above callee for natural top-down reading. +#+BEGIN_SRC java +public Response makeResponse(...) { + String pageName = getPageNameOrDefault(request, "FrontPage"); + loadPage(pageName, context); + return makePageResponse(context); +} + +private String getPageNameOrDefault(Request request, String defaultPageName) { ... } +#+END_SRC + +*** Conceptual Affinity +- Group functions with similar naming or shared purpose. +- Example (JUnit assert methods): +#+BEGIN_SRC java +static public void assertTrue(String message, boolean condition) { ... } +static public void assertTrue(boolean condition) { ... } +static public void assertFalse(String message, boolean condition) { ... } +static public void assertFalse(boolean condition) { ... } +#+END_SRC + +*** Vertical Ordering +- Organise code top down: + - High-level concepts first (main logic). + - Lower-level details later. +- Readers can skim like a newspaper: important first, details last. +- Contrast: C/C++ require declarations before use, Java does not. + +*** Summary - vertical +- Use vertical openness to separate concepts. +- Use vertical density to group related ones. +- Keep related variables, methods, and concepts close together. +- Order code top down for natural readability. + +** Horizontal Formatting + +Keep lines short — most professional code naturally stays within ~45 characters, with ~80 as an upper bound. Lines beyond 100–120 characters are generally careless. + +Avoid shrinking font or overly wide monitors to fit more code — readability > fitting more characters. + +Example limit guideline: + +#+begin_src java + // Good (short) + int sum = a + b + c; + + // Bad (too long) + int sum = a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q; +#+end_src +** Horizontal Openness and Density + +Use spaces to separate low-precedence operators (e.g., +, -, =) and improve readability. + +Do not put spaces between function names and parentheses — they are closely related. + +Example (Quadratic formula formatting): + +#+begin_src java + return (-b + Math.sqrt(determinant)) / (2*a); +#+end_src + +Separate arguments with spaces after commas to show distinct parameters. + +** Horizontal Alignment +Avoid aligning variable declarations or assignments in columns — it draws the eye to the wrong place. + +Long aligned lists usually mean the class is too large and should be split. + +Example (preferred unaligned): + +#+begin_src java + // Prefer this: + private Socket socket; + private InputStream input; + private OutputStream output; + + //instead of: + private Socket socket; + private InputStream input; + private OutputStream output; + +#+end_src + +** Indentation + +Indent according to scope hierarchy: + +Classes → no indent + +Methods → 1 level + +Method bodies → 2 levels + +Inner blocks → +1 for each nesting + +Indentation makes scopes visually obvious; without it, code is hard to scan. + +Avoid collapsing scopes onto one line — always use braces and proper indenting. + +** Dummy Scopes + +Avoid dummy bodies in loops (e.g., empty while or for loops). + +If unavoidable, place semicolon on its own indented line to make it visible. + +#+begin_src java + while (dis.read(buf, 0, size) != -1) + ; +#+end_src + +** Team Rules + +Teams must agree on a single formatting style for consistency. + +Use IDE formatters to enforce these rules across all files. + +Consistent formatting builds trust and reduces mental load for readers. + +** Uncle Bob’s Formatting Rules (Example in CodeAnalyzer.java) + +Short, clear methods with consistent spacing and indentation. + +Use spaces around assignment and low-precedence operators, no space for high-precedence operators. + +Avoid deeply nested structures — prefer clear, flat logic. + +Example snippet: + +#+begin_src java + private void measureLine(String line) { + lineCount++; + int lineSize = line.length(); + totalChars += lineSize; + lineWidthHistogram.addLine(lineSize, lineCount); + recordWidestLine(lineSize); + } +#+end_src diff --git a/20250804201706-big_o_complexity.org b/20250804201706-big_o_complexity.org new file mode 100644 index 0000000..ad11dea --- /dev/null +++ b/20250804201706-big_o_complexity.org @@ -0,0 +1,115 @@ +:PROPERTIES: +:ID: 275988a8-59d8-40c8-a8b4-47118d6eb834 +:END: +#+title: big-o-complexity +#+filetags: :leetcode:notes: +#+OPTIONS: toc:t + +* Big (O) - Time and Space Complexity +** Intro +Time Complexity: Describes the amount of time necessary to execute an algorithm + +Space Complexity: Describes the amount of memory or space utilized by an algorithm/program + +Both - asymptotically + + +** Technical Definition of Big O + +is a mathematical notation that describes the limiting behaviour of a function when the arguments tend towards a particular value or infinity. Why do we need it? it helps us understand how the performance of an algorithm changes as the size of the input grows, providing a simple way to compare and analyse different algorithms' efficiency. + +Improvement in time complexity is often more important as memory is cheap and readily available + +In Big O, there are six major types of complexities (time and space): + +- Constant: O(1) + +- Linear time: O(n) + +- Logarithmic time: O(n log n) + +- Quadratic time: O(n^2) + +- Exponential time: O(2^n) + +- Factorial time: O(n!) + + +** Big O - linear example + +Suppose we are given a problem where we have a list of `N` numbers of unknown length. We are asked to use code to find and return "True" if the number 2 is in the list and "False" otherwise. Our solution could be to go through every position in the list and check if the number at that position is equal to 2. + +[3, 10, 2, 7] + +#+begin_src python + for number in list: + if number == 2: + return True + else: + continue + return False +#+end_src + +This would take N time, we need to check every number in the list once, making this solution O(N) - linear time. This looks at the worst case scenarion, if 2 was at the start of the list we know it would take a constant time, however if it's at the end then it would take N time. + +[[~/master-folder/org_files/org_roam/assets/Big-O-Notation-3130482830.png]] + + +In the graph above focus on the tail end of the graphs because Big O is concerned with "as the input size grows what happens to the speed of the operations". + ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| Complexity | Name | Description | Common Use Cases | Performance at Scale | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(1) | Constant | Runtime unaffected by input size | Hash tables, array access | Excellent | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(log n) | Logarithmic | Runtime increases slowly | Binary search, balanced trees | Very good | +| | | (typically halved at each step) | | | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(n) | Linear | Runtime scales linearly | Linear search, array traversal | Good | +| | | (proportional) | | | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(n log n) | Linearithmic | Between linear and quadratic | Efficient sorting algorithms | Fair | +| | | (often seen in divide and conquer| | | +| | | algorithms) | | | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(n²) | Quadratic | Runtime squares with input size | Nested loops, simple sorting | Poor | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(2ⁿ) | Exponential | Runtime doubles with each input | Recursive solutions, combinatorics | Very poor | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(n!) | Factorial | Runtime grows by factorial | Permutations, traveling salesman | Terrible | +| | | (extremely slow) | | | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ + + +** Summation of complexities: + +When you have multiple operations in an algorithm that each have a linear time complexity O(n), and these operations are sequential (not nested), the overall time complexity of the algorithm remains linear, O(n). + +Here's how it works: + +1. Summing Linear Operations: If your algorithm involves several separate linear operations, such as: +• First iterating over an array of n elements, +• Then, in a separate loop, iterating over the same or another array of n elements, +• And perhaps another loop doing the same, +each operation has a complexity of O(n). If you sum these, the resulting complexity for these sequential operations is O(n) + O(n) + O(n), and so on. + +2. Simplification: According to Big O notation rules, when you add complexities of the same order, the overall complexity is dominated by the term that grows fastest as n increases. For linear operations, O(n) + O(n) + O(n) simplifies to O(n) because the growth rate in terms of the largest input size n doesn't change-it remains linear. + + +Linear time complexity, denoted as O(n), means that the time required to complete the execution of an algorithm increases linearly with the increase in the size of the input data. In essence, if you double the size of the input, you double the time it takes to process it. + +Suppose you have a task to sum the number 5, n times. The number of operations (in this case, additions) you perform directly corresponds to n. For instance: + +- If n = 1, you perform the operation 1 time: 5. +- If n = 2, you perform the operation 2 times: 5+5. +- If n = 3, you perform the operation 3 times: 5+5+5. +- And so on... + +In each of these cases, the number of addition operations you perform is exactly equal to n. The computational cost grows directly with n, which is the very definition of linear time complexity. Here's a breakdown: + +- When n = 1, the number of operations is 1. +- When n = 10, the number of operations is 10. +- When n = 100, the number of operations is 100. +- When n = 1000, the number of operations is 1000. + +In general, the total time taken for this task can be described as a function T(n) = n, where T(n) represents the total time or total number of operations, and n is the number of times you need to add 5. This function is a straight line when plotted against n, hence it is classified under linear time complexity O(n). diff --git a/20250804201706-big_o_complexity.org~ b/20250804201706-big_o_complexity.org~ new file mode 100644 index 0000000..ad11dea --- /dev/null +++ b/20250804201706-big_o_complexity.org~ @@ -0,0 +1,115 @@ +:PROPERTIES: +:ID: 275988a8-59d8-40c8-a8b4-47118d6eb834 +:END: +#+title: big-o-complexity +#+filetags: :leetcode:notes: +#+OPTIONS: toc:t + +* Big (O) - Time and Space Complexity +** Intro +Time Complexity: Describes the amount of time necessary to execute an algorithm + +Space Complexity: Describes the amount of memory or space utilized by an algorithm/program + +Both - asymptotically + + +** Technical Definition of Big O + +is a mathematical notation that describes the limiting behaviour of a function when the arguments tend towards a particular value or infinity. Why do we need it? it helps us understand how the performance of an algorithm changes as the size of the input grows, providing a simple way to compare and analyse different algorithms' efficiency. + +Improvement in time complexity is often more important as memory is cheap and readily available + +In Big O, there are six major types of complexities (time and space): + +- Constant: O(1) + +- Linear time: O(n) + +- Logarithmic time: O(n log n) + +- Quadratic time: O(n^2) + +- Exponential time: O(2^n) + +- Factorial time: O(n!) + + +** Big O - linear example + +Suppose we are given a problem where we have a list of `N` numbers of unknown length. We are asked to use code to find and return "True" if the number 2 is in the list and "False" otherwise. Our solution could be to go through every position in the list and check if the number at that position is equal to 2. + +[3, 10, 2, 7] + +#+begin_src python + for number in list: + if number == 2: + return True + else: + continue + return False +#+end_src + +This would take N time, we need to check every number in the list once, making this solution O(N) - linear time. This looks at the worst case scenarion, if 2 was at the start of the list we know it would take a constant time, however if it's at the end then it would take N time. + +[[~/master-folder/org_files/org_roam/assets/Big-O-Notation-3130482830.png]] + + +In the graph above focus on the tail end of the graphs because Big O is concerned with "as the input size grows what happens to the speed of the operations". + ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| Complexity | Name | Description | Common Use Cases | Performance at Scale | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(1) | Constant | Runtime unaffected by input size | Hash tables, array access | Excellent | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(log n) | Logarithmic | Runtime increases slowly | Binary search, balanced trees | Very good | +| | | (typically halved at each step) | | | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(n) | Linear | Runtime scales linearly | Linear search, array traversal | Good | +| | | (proportional) | | | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(n log n) | Linearithmic | Between linear and quadratic | Efficient sorting algorithms | Fair | +| | | (often seen in divide and conquer| | | +| | | algorithms) | | | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(n²) | Quadratic | Runtime squares with input size | Nested loops, simple sorting | Poor | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(2ⁿ) | Exponential | Runtime doubles with each input | Recursive solutions, combinatorics | Very poor | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ +| O(n!) | Factorial | Runtime grows by factorial | Permutations, traveling salesman | Terrible | +| | | (extremely slow) | | | ++------------+--------------+----------------------------------+------------------------------------+----------------------+ + + +** Summation of complexities: + +When you have multiple operations in an algorithm that each have a linear time complexity O(n), and these operations are sequential (not nested), the overall time complexity of the algorithm remains linear, O(n). + +Here's how it works: + +1. Summing Linear Operations: If your algorithm involves several separate linear operations, such as: +• First iterating over an array of n elements, +• Then, in a separate loop, iterating over the same or another array of n elements, +• And perhaps another loop doing the same, +each operation has a complexity of O(n). If you sum these, the resulting complexity for these sequential operations is O(n) + O(n) + O(n), and so on. + +2. Simplification: According to Big O notation rules, when you add complexities of the same order, the overall complexity is dominated by the term that grows fastest as n increases. For linear operations, O(n) + O(n) + O(n) simplifies to O(n) because the growth rate in terms of the largest input size n doesn't change-it remains linear. + + +Linear time complexity, denoted as O(n), means that the time required to complete the execution of an algorithm increases linearly with the increase in the size of the input data. In essence, if you double the size of the input, you double the time it takes to process it. + +Suppose you have a task to sum the number 5, n times. The number of operations (in this case, additions) you perform directly corresponds to n. For instance: + +- If n = 1, you perform the operation 1 time: 5. +- If n = 2, you perform the operation 2 times: 5+5. +- If n = 3, you perform the operation 3 times: 5+5+5. +- And so on... + +In each of these cases, the number of addition operations you perform is exactly equal to n. The computational cost grows directly with n, which is the very definition of linear time complexity. Here's a breakdown: + +- When n = 1, the number of operations is 1. +- When n = 10, the number of operations is 10. +- When n = 100, the number of operations is 100. +- When n = 1000, the number of operations is 1000. + +In general, the total time taken for this task can be described as a function T(n) = n, where T(n) represents the total time or total number of operations, and n is the number of times you need to add 5. This function is a straight line when plotted against n, hence it is classified under linear time complexity O(n). diff --git a/20250804212215-how_to_solve_leetcode.org b/20250804212215-how_to_solve_leetcode.org new file mode 100644 index 0000000..c22657c --- /dev/null +++ b/20250804212215-how_to_solve_leetcode.org @@ -0,0 +1,21 @@ +:PROPERTIES: +:ID: 086ca3ca-39ec-4d37-b56d-b6d9f51e6873 +:END: +#+title: how-to-solve-leetcode +#+filetags: :leetcode:notes: + +* Process: + +- Read the problem twice to understand it + +- Try think basically of different ways to solve the problem + +- Think end-to-end (e2e) of the best solutions based on complexity + +- Write the algorithm from patterns in drawing + +- Code it out + +- Try and improve it once you think you're finished + +- Go through other solutions diff --git a/20250804212215-how_to_solve_leetcode.org~ b/20250804212215-how_to_solve_leetcode.org~ new file mode 100644 index 0000000..f7c4d06 --- /dev/null +++ b/20250804212215-how_to_solve_leetcode.org~ @@ -0,0 +1,13 @@ +:PROPERTIES: +:ID: 086ca3ca-39ec-4d37-b56d-b6d9f51e6873 +:END: +#+title: how-to-solve-leetcode +#+filetags: :leetcode:notes: + +* Process: + +- Read the problem twice to understand it + +- Try think basically of different ways to solve the problem + +- diff --git a/20250804212606-leetcode_arrays.org b/20250804212606-leetcode_arrays.org new file mode 100644 index 0000000..9d04206 --- /dev/null +++ b/20250804212606-leetcode_arrays.org @@ -0,0 +1,351 @@ +:PROPERTIES: +:ID: 93a43a24-6861-40c4-b45b-581977bb55cf +:END: +#+title: leetcode-arrays +#+filetags: :leetcode:notes: + +* 217 - Contains Duplicate: + +Given an integer array `nums`, return `true` if any value appears at least twice in the array, and return false if every element is distinct. + +*Example 1:* + +Input: nums = [1,2,3,1] + +Output: true + +Explanation: The element 1 occurs at the indices 0 and 3. + +*Example 2:* + +Input: nums = [1,2,3,4] + +Output: false + +Explanation: All elements are distinct. + +*Example 3:* + +Input: nums = [1,1,1,3,3,4,3,2,4,2] + +Output: true + +*Constraints:* + +1 <= nums.length <= 105 +-109 <= nums[i] <= 109 + +** Attempt: + +Two loops +Outer loop will go through each element, inner loop will check if the element in outer loop is repeated in the array. + +#+begin_src python + class Solution(object): + def containsDuplicate(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + for i in nums: + for j in nums[i:len(nums)]: + if i == j: + return True + return False + +#+end_src + +Works? Yes, but there is a better solution + +** Solution: + +Use a [[id:3a41407c-661e-416a-80d2-4c7a137d153a][python-set]]. The reason is it does not allow for duplicates (it is unique). The solution is as follows: +We create a set from the array, then check if the length of the two are different, if they are then this indicates that there are duplicate values in the array. This is O(N) and is faster than the nested loops solution above. + +#+begin_src python + + if len(set(nums)) == len(nums): + return False + else: + return True + +#+end_src + +* 268 - Missing Number + +Given an array `nums` containing `n` distinct numbers in the range [0, n], return the only number in the range that is missing from the array. + +Example 1: +Input: nums = [3,0,1] + +Output: 2 +Explanation: n = 3 since there are 3 numbers, so all numbers are in the range [0,3]. 2 is the missing number in the range since it does not appear in nums. + +Example 2: +Input: nums = [0,1] + +Output: 2 +Explanation: n = 2 since there are 2 numbers, so all numbers are in the range [0,2]. 2 is the missing number in the range since it does not appear in nums. + +Example 3: +Input: nums = [9,6,4,2,3,5,7,0,1] + +Output: 8 +Explanation: n = 9 since there are 9 numbers, so all numbers are in the range [0,9]. 8 is the missing number in the range since it does not appear in nums. + +Constraints: + + n == nums.length + 1 <= n <= 104 + 0 <= nums[i] <= n + All the numbers of nums are unique. + +Follow up: Could you implement a solution using only O(1) extra space complexity and O(n) runtime complexity? + +** Attempt +Sort the array, loop through it and check via the incrementor + +#+begin_src python + + class Solution(object): + def missingNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + nums.sort() + for i in range(0, len(nums) + 1): + if i not in nums: + return i + +#+end_src + +Problem here is that sort operation is O(nlogn) - too slow. + +** Solution +One optimised solution: + +#+begin_src python + class Solution(object): + def missingNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + nums.sort() + n = len(nums) + total_sum = n * (n + 1) // 2 + actual_sum = sum(nums) + return total_sum - actual_sum +#+end_src + +Another: +#+begin_src python + class Solution(object): + def missingNumber(self, nums): + return sum(range(len(nums) + 1)) - sum(nums) +#+end_src + +This is O(N) +len = O(1) +Range object creation is O(1) +sum is O(N) ++1 in range(n) because n would be excluded otherwise. ie if you did range(2) you get [0,1] + +Some extra notes: +[[id:125c81dc-c14f-4b4d-93c6-0a2b157735ac][python-dictionary]] + +* 448 - Find all Numbers disappeared in an array +Given an array `nums` of `n` integers where `nums[i]` is in the range [1, n], return an array of all the integers in the range [1, n] that do not appear in nums. + +Example 1: +Input: nums = [4,3,2,7,8,2,3,1] +Output: [5,6] + +Example 2: +Input: nums = [1,1] +Output: [2] + +Constraints: + +n == nums.length +1 <= n <= 105 +1 <= nums[i] <= n + +Follow up: Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space. + +** Attempt +Create a set, loop through the set (it wont have duplicate values), if the counter is not equal to the value in the set, add it to a new list. + +#+begin_src python + class Solution(object): + def findDisappearedNumbers(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + new_set = set(nums) + print(new_set) + new_list = [] + for i in range(1, len(nums) + 1): + if i not in new_set: + new_list.append(i) + return new_list +#+end_src + +Time: O(N) as iterating through the range and appending to new list if not in given list. O(N) space. + +* 1 - Two Sum + +Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to target. + +You may assume that each input would have exactly one solution, and you may not use the same element twice. + +You can return the answer in any order. + +Example 1: +Input: nums = [2,7,11,15], target = 9 +Output: [0,1] +Explanation: Because nums[0] + nums[1] == 9, we return [0, 1]. + +Example 2: +Input: nums = [3,2,4], target = 6 +Output: [1,2] + +Example 3: +Input: nums = [3,3], target = 6 +Output: [0,1] + +Constraints: + + 2 <= nums.length <= 104 + -109 <= nums[i] <= 109 + -109 <= target <= 109 + Only one valid answer exists. + +Follow-up: Can you come up with an algorithm that is less than O(n2) time complexity? + +** Attempt +Outer loop and inner loop + +#+begin_src python + class Solution(object): + def twoSum(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + ret = [] + for i in range(0, len(nums) ): + for j in range(i + 1, len(nums) ): + if nums[i] + nums[j] == target: + ret.append(nums[i]) + ret.append(nums[j]) + return ret + +#+end_src + +Bad as its O(N^2) + +** Solution +Use a hashmap and loop once + +After looking through the logic: +#+begin_src python + class Solution(object): + def twoSum(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + hm = {} + ret = [] + for i in range(0, len(nums)): + if (target - nums[i]) not in hm: + hm.update({nums[i]: i}) + else: + ret.append(i) + ret.append(hm.get(target - nums[i])) + return ret + +#+end_src + +[[~/master-folder/org_files/org_roam/assets/swappy-20250805-152411.png]] + +Youtube solution: +#+begin_src python + + hash_map = {} + for i , v in enumerate(nums): + if target - v in hash_map: + return i, hash_map[target - v] + else: + hash_map[v] = i + +#+end_src + +#+begin_src python + + hashMap = {} + for indx, val in enumerate(nums): + diff = target - val + if diff in hashMap: + return [indx, hashMap[diff]] + hashMap[val] = indx + +#+end_src + +* 1365 - How Many Numbers Are Smaller Than the Current Number + +Given the array `nums`, for each `nums[i]` find out how many numbers in the array are smaller than it. That is, for each `nums[i]` you have to count the number of valid j's such that j != i and nums[j] < nums[i]. + +Return the answer in an array. + +Example 1: + +Input: nums = [8,1,2,2,3] +Output: [4,0,1,1,3] +Explanation: +For nums[0]=8 there exist four smaller numbers than it (1, 2, 2 and 3). +For nums[1]=1 does not exist any smaller number than it. +For nums[2]=2 there exist one smaller number than it (1). +For nums[3]=2 there exist one smaller number than it (1). +For nums[4]=3 there exist three smaller numbers than it (1, 2 and 2). + +Example 2: + +Input: nums = [6,5,4,8] +Output: [2,1,0,3] + +Example 3: + +Input: nums = [7,7,7,7] +Output: [0,0,0,0] + +Constraints: + + 2 <= nums.length <= 500 + 0 <= nums[i] <= 100 + + #+begin_src python + def smallerNumbersThanCurrent(nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + + temp = sorted(nums) + d = {} + + for i, num in enumerate(temp): + if num not in d: + d[num] = i + ret = [] + + for i in nums: + ret.append(d[i]) + return ret + + #+end_src diff --git a/20250804212606-leetcode_arrays.org~ b/20250804212606-leetcode_arrays.org~ new file mode 100644 index 0000000..21537a6 --- /dev/null +++ b/20250804212606-leetcode_arrays.org~ @@ -0,0 +1,330 @@ +:PROPERTIES: +:ID: 93a43a24-6861-40c4-b45b-581977bb55cf +:END: +#+title: leetcode-arrays +#+filetags: :leetcode:notes: + +* 217 - Contains Duplicate: + +Given an integer array `nums`, return `true` if any value appears at least twice in the array, and return false if every element is distinct. + +*Example 1:* + +Input: nums = [1,2,3,1] + +Output: true + +Explanation: The element 1 occurs at the indices 0 and 3. + +*Example 2:* + +Input: nums = [1,2,3,4] + +Output: false + +Explanation: All elements are distinct. + +*Example 3:* + +Input: nums = [1,1,1,3,3,4,3,2,4,2] + +Output: true + +*Constraints:* + +1 <= nums.length <= 105 +-109 <= nums[i] <= 109 + +** Attempt: + +Two loops +Outer loop will go through each element, inner loop will check if the element in outer loop is repeated in the array. + +#+begin_src python + class Solution(object): + def containsDuplicate(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + for i in nums: + for j in nums[i:len(nums)]: + if i == j: + return True + return False + +#+end_src + +Works? Yes, but there is a better solution + +** Solution: + +Use a [[id:3a41407c-661e-416a-80d2-4c7a137d153a][python-set]]. The reason is it does not allow for duplicates (it is unique). The solution is as follows: +We create a set from the array, then check if the length of the two are different, if they are then this indicates that there are duplicate values in the array. This is O(N) and is faster than the nested loops solution above. + +#+begin_src python + + if len(set(nums)) == len(nums): + return False + else: + return True + +#+end_src + +* 268 - Missing Number + +Given an array `nums` containing `n` distinct numbers in the range [0, n], return the only number in the range that is missing from the array. + +Example 1: +Input: nums = [3,0,1] + +Output: 2 +Explanation: n = 3 since there are 3 numbers, so all numbers are in the range [0,3]. 2 is the missing number in the range since it does not appear in nums. + +Example 2: +Input: nums = [0,1] + +Output: 2 +Explanation: n = 2 since there are 2 numbers, so all numbers are in the range [0,2]. 2 is the missing number in the range since it does not appear in nums. + +Example 3: +Input: nums = [9,6,4,2,3,5,7,0,1] + +Output: 8 +Explanation: n = 9 since there are 9 numbers, so all numbers are in the range [0,9]. 8 is the missing number in the range since it does not appear in nums. + +Constraints: + + n == nums.length + 1 <= n <= 104 + 0 <= nums[i] <= n + All the numbers of nums are unique. + +Follow up: Could you implement a solution using only O(1) extra space complexity and O(n) runtime complexity? + +** Attempt +Sort the array, loop through it and check via the incrementor + +#+begin_src python + + class Solution(object): + def missingNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + nums.sort() + for i in range(0, len(nums) + 1): + if i not in nums: + return i + +#+end_src + +Problem here is that sort operation is O(nlogn) - too slow. + +** Solution +One optimised solution: + +#+begin_src python + class Solution(object): + def missingNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + nums.sort() + n = len(nums) + total_sum = n * (n + 1) // 2 + actual_sum = sum(nums) + return total_sum - actual_sum +#+end_src + +Another: +#+begin_src python + class Solution(object): + def missingNumber(self, nums): + return sum(range(len(nums) + 1)) - sum(nums) +#+end_src + +This is O(N) +len = O(1) +Range object creation is O(1) +sum is O(N) ++1 in range(n) because n would be excluded otherwise. ie if you did range(2) you get [0,1] + +Some extra notes: +[[id:125c81dc-c14f-4b4d-93c6-0a2b157735ac][python-dictionary]] + +* 448 - Find all Numbers disappeared in an array +Given an array `nums` of `n` integers where `nums[i]` is in the range [1, n], return an array of all the integers in the range [1, n] that do not appear in nums. + +Example 1: +Input: nums = [4,3,2,7,8,2,3,1] +Output: [5,6] + +Example 2: +Input: nums = [1,1] +Output: [2] + +Constraints: + +n == nums.length +1 <= n <= 105 +1 <= nums[i] <= n + +Follow up: Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space. + +** Attempt +Create a set, loop through the set (it wont have duplicate values), if the counter is not equal to the value in the set, add it to a new list. + +#+begin_src python + class Solution(object): + def findDisappearedNumbers(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + new_set = set(nums) + print(new_set) + new_list = [] + for i in range(1, len(nums) + 1): + if i not in new_set: + new_list.append(i) + return new_list +#+end_src + +Time: O(N) as iterating through the range and appending to new list if not in given list. O(N) space. + +* 1 - Two Sum + +Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to target. + +You may assume that each input would have exactly one solution, and you may not use the same element twice. + +You can return the answer in any order. + +Example 1: +Input: nums = [2,7,11,15], target = 9 +Output: [0,1] +Explanation: Because nums[0] + nums[1] == 9, we return [0, 1]. + +Example 2: +Input: nums = [3,2,4], target = 6 +Output: [1,2] + +Example 3: +Input: nums = [3,3], target = 6 +Output: [0,1] + +Constraints: + + 2 <= nums.length <= 104 + -109 <= nums[i] <= 109 + -109 <= target <= 109 + Only one valid answer exists. + +Follow-up: Can you come up with an algorithm that is less than O(n2) time complexity? + +** Attempt +Outer loop and inner loop + +#+begin_src python + class Solution(object): + def twoSum(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + ret = [] + for i in range(0, len(nums) ): + for j in range(i + 1, len(nums) ): + if nums[i] + nums[j] == target: + ret.append(nums[i]) + ret.append(nums[j]) + return ret + +#+end_src + +Bad as its O(N^2) + +** Solution +Use a hashmap and loop once + +After looking through the logic: +#+begin_src python + class Solution(object): + def twoSum(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + hm = {} + ret = [] + for i in range(0, len(nums)): + if (target - nums[i]) not in hm: + hm.update({nums[i]: i}) + else: + ret.append(i) + ret.append(hm.get(target - nums[i])) + return ret + +#+end_src + +[[~/master-folder/org_files/org_roam/assets/swappy-20250805-152411.png]] + +Youtube solution: +#+begin_src python + + hash_map = {} + for i , v in enumerate(nums): + if target - v in hash_map: + return i, hash_map[target - v] + else: + hash_map[v] = i + +#+end_src + +#+begin_src python + + hashMap = {} + for indx, val in enumerate(nums): + diff = target - val + if diff in hashMap: + return [indx, hashMap[diff]] + hashMap[val] = indx + +#+end_src + +* 1365 - How Many Numbers Are Smaller Than the Current Number + +Given the array `nums`, for each `nums[i]` find out how many numbers in the array are smaller than it. That is, for each `nums[i]` you have to count the number of valid j's such that j != i and nums[j] < nums[i]. + +Return the answer in an array. + +Example 1: + +Input: nums = [8,1,2,2,3] +Output: [4,0,1,1,3] +Explanation: +For nums[0]=8 there exist four smaller numbers than it (1, 2, 2 and 3). +For nums[1]=1 does not exist any smaller number than it. +For nums[2]=2 there exist one smaller number than it (1). +For nums[3]=2 there exist one smaller number than it (1). +For nums[4]=3 there exist three smaller numbers than it (1, 2 and 2). + +Example 2: + +Input: nums = [6,5,4,8] +Output: [2,1,0,3] + +Example 3: + +Input: nums = [7,7,7,7] +Output: [0,0,0,0] + +Constraints: + + 2 <= nums.length <= 500 + 0 <= nums[i] <= 100 diff --git a/20250804214537-python_set.org b/20250804214537-python_set.org new file mode 100644 index 0000000..87a54db --- /dev/null +++ b/20250804214537-python_set.org @@ -0,0 +1,27 @@ +:PROPERTIES: +:ID: 3a41407c-661e-416a-80d2-4c7a137d153a +:END: +#+title: python-set +#+filetags: :python:notes: + +Sets are used to store multiple items in a single variable. + +Set is one of 4 built-in data types in Python used to store collections of data, the other 3 are List, Tuple, and Dictionary, all with different qualities and usage. + +A set is a collection which is unordered, unchangeable*, and unindexed. + +*Note: Set items are unchangeable, but you can remove items and add new items. + +Sets are written with curly brackets. +Example: + +#+begin_src python + # Create a Set: + thisset = {"apple", "banana", "cherry"} + print(thisset) +#+end_src + +Notes: + +Sets are fast, Note that empty Set cannot be created through {}, it creates a dictionary, unless you include values. +set is implemented as a hash table, so you can expect lookup, insert, delete to be O(1) on average. diff --git a/20250804214537-python_set.org~ b/20250804214537-python_set.org~ new file mode 100644 index 0000000..7ff6d84 --- /dev/null +++ b/20250804214537-python_set.org~ @@ -0,0 +1,22 @@ +:PROPERTIES: +:ID: 3a41407c-661e-416a-80d2-4c7a137d153a +:END: +#+title: python-set +#+filetags: :python:notes: + +Sets are used to store multiple items in a single variable. + +Set is one of 4 built-in data types in Python used to store collections of data, the other 3 are List, Tuple, and Dictionary, all with different qualities and usage. + +A set is a collection which is unordered, unchangeable*, and unindexed. + +*Note: Set items are unchangeable, but you can remove items and add new items. + +Sets are written with curly brackets. +Example: + +#+begin_src python + # Create a Set: + thisset = {"apple", "banana", "cherry"} + print(thisset) +#+end_src diff --git a/20250805141906-python_dictionary.org b/20250805141906-python_dictionary.org new file mode 100644 index 0000000..953e5a6 --- /dev/null +++ b/20250805141906-python_dictionary.org @@ -0,0 +1,99 @@ +:PROPERTIES: +:ID: 125c81dc-c14f-4b4d-93c6-0a2b157735ac +:END: +#+title: python-dictionary +#+filetags: :python:notes: + +Dictionaries are used to store data values in key:value pairs. + +A dictionary is a collection which is ordered*, changeable and do not allow duplicates. + +*As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier, dictionaries are unordered. + +Dictionaries are written with curly brackets, and have keys and values: + +#+begin_src python + + # Create and print a dictionary: + thisdict = { + "brand": "Ford", + "model": "Mustang", + "year": 1964 + } + print(thisdict) + +#+end_src + +Iterating: + +Iterate through Value + +To iterate through all values of a dictionary in Python using .values(), you can employ a for loop, accessing each value sequentially. This method allows you to process or display each individual value in the dictionary without explicitly referencing the corresponding keys. + +Example: In this example, we are using the values() method to print all the values present in the dictionary. + +#+begin_src python :results output + + # create a python dictionary + d = {"name": "Geeks", "topic": "dict", "task": "iterate"} + + # loop over dict values + for val in d.values(): + print(val) +#+end_src + +Iterate through keys + +In Python, just looping through the dictionary provides you its keys. You can also iterate keys of a dictionary using built-in `.keys()` method. + +#+begin_src python :results output + + # create a python dictionary + d = {"name": "Geeks", "topic": "dict", "task": "iterate"} + + # default loooping gives keys + for keys in d: + print(keys) + + # looping through keys + for keys in d.keys(): + print(keys) + +#+end_src + +Iterate through both keys and values + +You can use the built-in items() method to access both keys and items at the same time. items() method returns the view object that contains the key-value pair as tuples. + +#+begin_src python :results output + + # create a python dictionary + d = {"name": "Geeks", "topic": "dict", "task": "iterate"} + + # iterating both key and values + for key, value in d.items(): + print(f"{key}: {value}") + +#+end_src + +Sorting: + +Lambda function accesses the key (item[0]) during sorting. It offers flexibility if you want to tweak the sorting logic later. + +#+begin_src python :results output + import operator + + a = {"Gfg": 5, "is": 7, "Best": 2, "for": 9, "geeks": 8} + res = dict(sorted(a.items(), key=lambda item: item[0])) + print(res) + +#+end_src + +#+RESULTS: +: {'Best': 2, 'Gfg': 5, 'is': 7, 'geeks': 8, 'for': 9} + +Explanation: `lambda item: item[0]` sorts the dictionary by the first element of each tuple (the key). + +[[id:3bbc6099-0187-4bf2-9282-97e5fa443f72][python-sorted-function]] + +[[id:9d534e89-7f0b-494c-bff6-7b3be05b85d1][python-lambda]] diff --git a/20250805141906-python_dictionary.org~ b/20250805141906-python_dictionary.org~ new file mode 100644 index 0000000..30d0fad --- /dev/null +++ b/20250805141906-python_dictionary.org~ @@ -0,0 +1,63 @@ +:PROPERTIES: +:ID: 125c81dc-c14f-4b4d-93c6-0a2b157735ac +:END: +#+title: python-dictionary +#+filetags: :python:notes: + +Dictionaries are used to store data values in key:value pairs. + +A dictionary is a collection which is ordered*, changeable and do not allow duplicates. + +*As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier, dictionaries are unordered. + +Dictionaries are written with curly brackets, and have keys and values: + +#+begin_src python + + # Create and print a dictionary: + thisdict = { + "brand": "Ford", + "model": "Mustang", + "year": 1964 + } + print(thisdict) + +#+end_src + +Iterating: + +Iterate through Value + +To iterate through all values of a dictionary in Python using .values(), you can employ a for loop, accessing each value sequentially. This method allows you to process or display each individual value in the dictionary without explicitly referencing the corresponding keys. + +Example: In this example, we are using the values() method to print all the values present in the dictionary. + +#+begin_src python + + # create a python dictionary + d = {"name": "Geeks", "topic": "dict", "task": "iterate"} + + # loop over dict values + for val in d.values(): + +#+end_src + +Iterate through keys + +In Python, just looping through the dictionary provides you its keys. You can also iterate keys of a dictionary using built-in `.keys()` method. + +#+begin_src python + + # create a python dictionary + d = {"name": "Geeks", "topic": "dict", "task": "iterate"} + + # default loooping gives keys + for keys in d: + print(keys) + + # looping through keys + for keys in d.keys(): + print(keys) + +#+end_src + diff --git a/20250805143427-python_sorted_function.org b/20250805143427-python_sorted_function.org new file mode 100644 index 0000000..c8cfb11 --- /dev/null +++ b/20250805143427-python_sorted_function.org @@ -0,0 +1,21 @@ +:PROPERTIES: +:ID: 3bbc6099-0187-4bf2-9282-97e5fa443f72 +:END: +#+title: python-sorted-function +#+filetags: :python:notes:functions: + +Syntax + +*sorted(iterable, key=key, reverse=reverse)* + +Parameter Values + ++-----------+---------------------------------------------------------------------------------------------+ +| Parameter | Description | ++-----------+---------------------------------------------------------------------------------------------+ +| iterable | Required. The sequence to sort, list, dictionary, tuple etc. | ++-----------+---------------------------------------------------------------------------------------------+ +| key | Optional. A Function to execute to decide the order. Default is None | ++-----------+---------------------------------------------------------------------------------------------+ +| reverse | Optional. A Boolean. False will sort ascending, True will sort descending. Default is False | ++-----------+---------------------------------------------------------------------------------------------+ diff --git a/20250805143741-python_lambda.org b/20250805143741-python_lambda.org new file mode 100644 index 0000000..650a085 --- /dev/null +++ b/20250805143741-python_lambda.org @@ -0,0 +1,36 @@ +:PROPERTIES: +:ID: 9d534e89-7f0b-494c-bff6-7b3be05b85d1 +:END: +#+title: python-lambda +#+filetags: :python:notes:functions: + +A lambda function is a small anonymous function. + +A lambda function can take any number of arguments, but can only have one expression. + +Syntax: + +*lambda arguments : expression* + +The expression is executed and the result is returned: + +#+begin_src python :results output + + # Add 10 to argument a, and return the result: + x = lambda a : a + 10 + print(x(5)) + + # Multiply argument a with argument b and return the result: + y = lambda a, b : a * b + print(y(5, 6)) + + # Summarize argument a, b, and c and return the result: + z = lambda a, b, c : a + b + c + print(z(5, 6, 2)) + +#+end_src + +#+RESULTS: +: 15 +: 30 +: 13 diff --git a/20250805143741-python_lambda.org~ b/20250805143741-python_lambda.org~ new file mode 100644 index 0000000..ac29fa9 --- /dev/null +++ b/20250805143741-python_lambda.org~ @@ -0,0 +1,6 @@ +:PROPERTIES: +:ID: 9d534e89-7f0b-494c-bff6-7b3be05b85d1 +:END: +#+title: python-lambda +#+filetags: :python:notes:functions: + diff --git a/20250806111925-non_technical_moc.org b/20250806111925-non_technical_moc.org new file mode 100644 index 0000000..e6463ad --- /dev/null +++ b/20250806111925-non_technical_moc.org @@ -0,0 +1,8 @@ +:PROPERTIES: +:ID: 565eaccd-8cf6-4dbb-bc66-a4b37367ce6b +:END: +#+title: non_technical_moc +#+filetags: :moc: + +[[id:65F747B1-3CB2-429A-9E26-ED8BC169E689][recipes-moc]] +[[id:63314cff-3a3f-49b4-9e76-4a359c51f55f][books-moc]] diff --git a/20250806111925-non_technical_moc.org~ b/20250806111925-non_technical_moc.org~ new file mode 100644 index 0000000..5baa1c2 --- /dev/null +++ b/20250806111925-non_technical_moc.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: 565eaccd-8cf6-4dbb-bc66-a4b37367ce6b +:END: +#+title: non_technical_moc + diff --git a/20250806155335-emacs_stuff_org_publish.org b/20250806155335-emacs_stuff_org_publish.org new file mode 100644 index 0000000..87bea7c --- /dev/null +++ b/20250806155335-emacs_stuff_org_publish.org @@ -0,0 +1,168 @@ +:PROPERTIES: +:ID: 7d2e867e-f091-4362-a583-453f732207fe +:END: +#+title: emacs-stuff-org-publish +#+filetags: :org:notes: + + +* How to insert footnotes: + +The Org website[fn:1] now looks a lot better than it used to. + +[fn:1] The link is: https://orgmode.org + +* Resources: +https://ogbe.net/blog/blogging_with_org + +https://systemcrafters.net/publishing-websites-with-org-mode/building-the-site/ + +https://orgmode.org/manual/Publishing-options.html + +https://www.orgroam.com/manual.html#Configuration + +https://www.reddit.com/r/emacs/comments/1j7febh/my_static_website_is_generated_from_org_mode_and/?chainedPosts=t3_116yit2 + +https://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html + +https://taingram.org/blog/org-mode-blog.html + +https://karthinks.com/software/emacs-window-management-almanac/ + +https://gongzhitaao.org/orgcss/ + +https://ogbe.net/blog/emacs_org_static_site + +https://edwardtufte.github.io/tufte-css/ + +https://zilongli.org/code/org-tufte-example + + +* Extra snippets of code: + +#+begin_src emacs-lisp + ;; Commented out things: + + ;; (defvar z-head + ;; " + ;; ") + + ;; (setq org-html-validation-link nil + ;; org-html-head-include-scripts nil + ;; org-html-head-include-default-style nil + ;; org-html-head z-head) + + ;; (type-of (car '(rose violet daisy buttercup))) + ;; (cadr (assoc "FILETAGS" (org-collect-keywords '("FILETAGS")))) + + ;; (let ((list '(("post1.org") ("post2.org")))) + ;; (mapconcat (lambda (entry) + ;; (format "- [[file:%s]]" (car entry))) + ;; list + ;; "\n")) + + + ;; ("website" + ;; :components ("org-main" "org-categories-sitemap" "org-assets" "org-posts" "org-blogs" "org-static")) + ;; :html-head " + ;; + ;; + ;; + ;; " + + + (defun z/write-tag-pages () + "Generate tags/*.org pages listing posts for each tag." + (let* ((site-root (expand-file-name "~/master-folder/org_files/org_web/")) + (tags-dir (expand-file-name "tags" site-root))) + (unless (file-directory-p tags-dir) + (make-directory tags-dir t)) + (let ((idx (z/gather-tag-index))) + (maphash + (lambda (tag items) + (let* ((slug (z/tag-slug tag)) + (outfile (expand-file-name (format "%s.org" slug) tags-dir))) + (with-temp-file outfile + (insert (format "#+TITLE: Tag: %s\n#+OPTIONS: toc:nil num:nil title:nil \n\n* Posts tagged %s\n" + tag tag)) + ;; sort newest first if DATE present + (setq items (sort items (lambda (a b) (string> (nth 2 a) (nth 2 b))))) + (dolist (it items) + (let* ((file (nth 0 it)) + (title (nth 1 it)) + (rel (file-relative-name file tags-dir))) + ;; link to the source .org; org-publish will rewrite to the .html + (insert (format "- [[file:%s][%s]]\n" rel title))))))) + idx) + ;; Also write an index page listing all tag pages + ;; (let* ((all ())) + ;; (maphash (lambda (tag _items) (push tag all)) (z/gather-tag-index)) + ;; (with-temp-file (expand-file-name "index.org" (expand-file-name "tags" site-root)) + ;; (insert "#+TITLE: All Tags\n#+OPTIONS: toc:nil num:nil\n\n* Tags\n") + ;; (dolist (tag (sort all #'string-lessp)) + ;; (insert (format "- [[file:%s.org][%s]]\n" (z/tag-slug tag) tag))))) + + ))) + + +#+end_src + +* Options stuff: + +In Org mode, you can control per-file publishing behavior using special keywords (known as **file-local metadata**) at the top of the file. These are written like: + +```org +#+KEYWORD: value +``` + +--- + +Here are **useful options** you can set **per file**: + +| Keyword | Purpose | +| -------------------- | ----------------------------------------------------- | +| `#+TITLE:` | Title of the document | +| `#+AUTHOR:` | Author name | +| `#+EMAIL:` | Email address | +| `#+DATE:` | Date | +| `#+OPTIONS:` | Control export behavior (e.g. toc, num, author, etc.) | +| `#+HTML_HEAD:` | Custom HTML for `` (like styles or scripts) | +| `#+HTML_HEAD_EXTRA:` | Extra HTML inserted in `` | +| `#+HTML_PREAMBLE:` | Whether to include the preamble (`t`, `nil`, or HTML) | +| `#+HTML_POSTAMBLE:` | Same but for postamble | +| `#+LANGUAGE:` | Language used for export | +| `#+DESCRIPTION:` | Adds a `` tag | +| `#+KEYWORDS:` | Adds a `` tag | + +--- + +### ✅ Example: Disable TOC and Section Numbers *for one file* + +You can use the `#+OPTIONS:` line like so: + +```org +#+OPTIONS: toc:nil num:nil +``` + +This disables the Table of Contents and section numbers **just for that file**. + +Your updated file might look like this: + +#+BEGIN_SRC emacs-lisp +#+TITLE: Welcome to My Org Website +#+OPTIONS: toc:nil num:nil +#+HTML_HEAD: +#+HTML_HEAD: +#+END_SRC + +Here's a reference for some values you can tweak via `#+OPTIONS:`: + +| Option | Meaning | Example | +| ------------- | -------------------------------- | ---------------- | +| `toc:` | Table of contents (`t` or `nil`) | `toc:nil` | +| `num:` | Section numbering | `num:nil` | +| `author:` | Show author name | `author:nil` | +| `creator:` | Show Emacs/Org creator info | `creator:nil` | +| `date:` | Show date | `date:nil` | +| `html-style:` | Disable default style | `html-style:nil` | + + diff --git a/20250806155335-emacs_stuff_org_publish.org~ b/20250806155335-emacs_stuff_org_publish.org~ new file mode 100644 index 0000000..5c0b9c0 --- /dev/null +++ b/20250806155335-emacs_stuff_org_publish.org~ @@ -0,0 +1,158 @@ +:PROPERTIES: +:ID: 7d2e867e-f091-4362-a583-453f732207fe +:END: +#+title: emacs-stuff-org-publish +#+filetags: :org:notes: + + +* How to insert footnotes: + +The Org website[fn:1] now looks a lot better than it used to. + +[fn:1] The link is: https://orgmode.org + +* Resources: +https://ogbe.net/blog/blogging_with_org + +https://systemcrafters.net/publishing-websites-with-org-mode/building-the-site/ + +https://orgmode.org/manual/Publishing-options.html + +https://www.orgroam.com/manual.html#Configuration + +https://www.reddit.com/r/emacs/comments/1j7febh/my_static_website_is_generated_from_org_mode_and/?chainedPosts=t3_116yit2 + +https://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html + +https://taingram.org/blog/org-mode-blog.html + + +* Extra snippets of code: + +#+begin_src emacs-lisp + ;; Commented out things: + + ;; (defvar z-head + ;; " + ;; ") + + ;; (setq org-html-validation-link nil + ;; org-html-head-include-scripts nil + ;; org-html-head-include-default-style nil + ;; org-html-head z-head) + + ;; (type-of (car '(rose violet daisy buttercup))) + ;; (cadr (assoc "FILETAGS" (org-collect-keywords '("FILETAGS")))) + + ;; (let ((list '(("post1.org") ("post2.org")))) + ;; (mapconcat (lambda (entry) + ;; (format "- [[file:%s]]" (car entry))) + ;; list + ;; "\n")) + + + ;; ("website" + ;; :components ("org-main" "org-categories-sitemap" "org-assets" "org-posts" "org-blogs" "org-static")) + ;; :html-head " + ;; + ;; + ;; + ;; " + + + (defun z/write-tag-pages () + "Generate tags/*.org pages listing posts for each tag." + (let* ((site-root (expand-file-name "~/master-folder/org_files/org_web/")) + (tags-dir (expand-file-name "tags" site-root))) + (unless (file-directory-p tags-dir) + (make-directory tags-dir t)) + (let ((idx (z/gather-tag-index))) + (maphash + (lambda (tag items) + (let* ((slug (z/tag-slug tag)) + (outfile (expand-file-name (format "%s.org" slug) tags-dir))) + (with-temp-file outfile + (insert (format "#+TITLE: Tag: %s\n#+OPTIONS: toc:nil num:nil title:nil \n\n* Posts tagged %s\n" + tag tag)) + ;; sort newest first if DATE present + (setq items (sort items (lambda (a b) (string> (nth 2 a) (nth 2 b))))) + (dolist (it items) + (let* ((file (nth 0 it)) + (title (nth 1 it)) + (rel (file-relative-name file tags-dir))) + ;; link to the source .org; org-publish will rewrite to the .html + (insert (format "- [[file:%s][%s]]\n" rel title))))))) + idx) + ;; Also write an index page listing all tag pages + ;; (let* ((all ())) + ;; (maphash (lambda (tag _items) (push tag all)) (z/gather-tag-index)) + ;; (with-temp-file (expand-file-name "index.org" (expand-file-name "tags" site-root)) + ;; (insert "#+TITLE: All Tags\n#+OPTIONS: toc:nil num:nil\n\n* Tags\n") + ;; (dolist (tag (sort all #'string-lessp)) + ;; (insert (format "- [[file:%s.org][%s]]\n" (z/tag-slug tag) tag))))) + + ))) + + +#+end_src + +* Options stuff: + +In Org mode, you can control per-file publishing behavior using special keywords (known as **file-local metadata**) at the top of the file. These are written like: + +```org +#+KEYWORD: value +``` + +--- + +Here are **useful options** you can set **per file**: + +| Keyword | Purpose | +| -------------------- | ----------------------------------------------------- | +| `#+TITLE:` | Title of the document | +| `#+AUTHOR:` | Author name | +| `#+EMAIL:` | Email address | +| `#+DATE:` | Date | +| `#+OPTIONS:` | Control export behavior (e.g. toc, num, author, etc.) | +| `#+HTML_HEAD:` | Custom HTML for `` (like styles or scripts) | +| `#+HTML_HEAD_EXTRA:` | Extra HTML inserted in `` | +| `#+HTML_PREAMBLE:` | Whether to include the preamble (`t`, `nil`, or HTML) | +| `#+HTML_POSTAMBLE:` | Same but for postamble | +| `#+LANGUAGE:` | Language used for export | +| `#+DESCRIPTION:` | Adds a `` tag | +| `#+KEYWORDS:` | Adds a `` tag | + +--- + +### ✅ Example: Disable TOC and Section Numbers *for one file* + +You can use the `#+OPTIONS:` line like so: + +```org +#+OPTIONS: toc:nil num:nil +``` + +This disables the Table of Contents and section numbers **just for that file**. + +Your updated file might look like this: + +#+BEGIN_SRC emacs-lisp +#+TITLE: Welcome to My Org Website +#+OPTIONS: toc:nil num:nil +#+HTML_HEAD: +#+HTML_HEAD: +#+END_SRC + +Here's a reference for some values you can tweak via `#+OPTIONS:`: + +| Option | Meaning | Example | +| ------------- | -------------------------------- | ---------------- | +| `toc:` | Table of contents (`t` or `nil`) | `toc:nil` | +| `num:` | Section numbering | `num:nil` | +| `author:` | Show author name | `author:nil` | +| `creator:` | Show Emacs/Org creator info | `creator:nil` | +| `date:` | Show date | `date:nil` | +| `html-style:` | Disable default style | `html-style:nil` | + + diff --git a/20250819174119-naqshe_hayat.org b/20250819174119-naqshe_hayat.org new file mode 100644 index 0000000..9794fec --- /dev/null +++ b/20250819174119-naqshe_hayat.org @@ -0,0 +1,10 @@ +:PROPERTIES: +:ID: 4426cc9a-1568-4fc8-9242-269654c43a3b +:TYPE: Book +:AUTHOR: Shaykh Husain Ahmad Madani RH +:DATE_STARTED: <2025-07-24 Thu> +:DATE_ENDED: +:END: +#+title: naqshe-hayat +#+filetags: :books: + diff --git a/20250819174119-naqshe_hayat.org~ b/20250819174119-naqshe_hayat.org~ new file mode 100644 index 0000000..12d97f1 --- /dev/null +++ b/20250819174119-naqshe_hayat.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: 4426cc9a-1568-4fc8-9242-269654c43a3b +:END: +#+title: naqshe-hayat + diff --git a/20250918120519-misc_moc.org b/20250918120519-misc_moc.org new file mode 100644 index 0000000..f59d3f1 --- /dev/null +++ b/20250918120519-misc_moc.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 08415f5c-986e-45a6-8ea1-f3bedcc996f0 +:END: +#+title: misc_moc +#+filetags: :misc:moc: + +* [[id:c1de3972-e932-48fd-8065-3d89dad58007][wedding_moc]] + +* [[id:8CE93986-280B-45BD-9DF2-5D06586DDDE7][workflow-moc]] diff --git a/20250918120519-misc_moc.org~ b/20250918120519-misc_moc.org~ new file mode 100644 index 0000000..ce85933 --- /dev/null +++ b/20250918120519-misc_moc.org~ @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: 08415f5c-986e-45a6-8ea1-f3bedcc996f0 +:END: +#+title: misc_moc +#+filetags: :misc:moc: + +* [[id:c1de3972-e932-48fd-8065-3d89dad58007][wedding_moc]] diff --git a/20250918120706-wedding_moc.org b/20250918120706-wedding_moc.org new file mode 100644 index 0000000..1d68c47 --- /dev/null +++ b/20250918120706-wedding_moc.org @@ -0,0 +1,77 @@ +:PROPERTIES: +:ID: c1de3972-e932-48fd-8065-3d89dad58007 +:END: +#+title: wedding_moc +#+filetags: :wedding:moc: + +* Important dates +** Engagement Day: <2025-10-26 Sun> 3pm-6pm +** Nikah / Barat: <2026-08-02 Sun> +** Walima: + +* Walimah Venues + +** Requirements +- 250 to 350 people +- Segregated +- External / Internal Catering (halal) +- Timing (Saturday evening) +- Prayer Facility +- Early July (or similar) +- Deposit + +** Hadley Hall +*** Details + +Bearwood Road, Birmingham, United Kingdom B66 4ES + +https://www.instagram.com/hadley.hall/?hl=en +https://www.facebook.com/p/Hadley-Hall-Banqueting-Suite-100063467019018/?locale=en_GB + +Contact Details: +- 0121 601 0955 +- 07522257044 (insta) + +Distance: 18 Minutes Drive / 51 Minutes Bus + +2 Suites. One is 200 people, the other is 450 people +Segregated Yes with 300 people +Catering is £10ph +Timing is 6-11pm (and morning too). +Prayer facility included. +Early July is good time +Deposit £500 + +Roughly £6500 (3k food, 3.5k everything else) + +<2025-09-28 Sun> : Went to view the hall, 2 halls are given for the price of 3.5k. +** Bab al Hara +*** Details +500 people segregated suite. one large hall. instagram has all details. 9.5k with catering, 6.2k without for 300 people. + +<2025-09-30 Tue> : Went to view +** Mayfair suite +9.3k with food +6k without food +<2025-10-01 Wed>: Went to view + +** Bia Lounge +*** Details + +45-47 Golden Hillock Rd, Birmingham B10 0JU + +http://www.bialoungeweddinghall.co.uk/ + +Contact Details: + +Tel: 0121 772 7576 +Mob: 07901 553 350 + +Distance: 5 Min Drive / 27 Min Bus + +400 people +Segregated yes +Catering (in house basic is 10-12ph) +Early July yes (some dates available) +Prayer Facility included +Deposit minimum 500 diff --git a/20250918120706-wedding_moc.org~ b/20250918120706-wedding_moc.org~ new file mode 100644 index 0000000..7db65e4 --- /dev/null +++ b/20250918120706-wedding_moc.org~ @@ -0,0 +1,70 @@ +:PROPERTIES: +:ID: c1de3972-e932-48fd-8065-3d89dad58007 +:END: +#+title: wedding_moc +#+filetags: :wedding:moc: + +* Important dates + +* Walimah Venues + +** Requirements +- 250 to 350 people +- Segregated +- External / Internal Catering (halal) +- Timing (Saturday evening) +- Prayer Facility +- Early July (or similar) +- Deposit + +** Hadley Hall +*** Details + +Bearwood Road, Birmingham, United Kingdom B66 4ES + +https://www.instagram.com/hadley.hall/?hl=en +https://www.facebook.com/p/Hadley-Hall-Banqueting-Suite-100063467019018/?locale=en_GB + +Contact Details: +- 0121 601 0955 +- 07522257044 (insta) + +Distance: 18 Minutes Drive / 51 Minutes Bus + +2 Suites. One is 200 people, the other is 450 people +Segregated Yes with 300 people +Catering is £10ph +Timing is 6-11pm (and morning too). +Prayer facility included. +Early July is good time +Deposit £500 + +Roughly £6500 (3k food, 3.5k everything else) + +<2025-09-28 Sun> : Went to view the hall, 2 halls are given for the price of 3.5k. +** Bab al Hara +*** Details +500 people segregated suite. one large hall. instagram has all details. 9.5k with catering, 6.2k without for 300 people. + +<2025-09-30 Tue> : Went to view + +** Bia Lounge +*** Details + +45-47 Golden Hillock Rd, Birmingham B10 0JU + +http://www.bialoungeweddinghall.co.uk/ + +Contact Details: + +Tel: 0121 772 7576 +Mob: 07901 553 350 + +Distance: 5 Min Drive / 27 Min Bus + +400 people +Segregated yes +Catering (in house basic is 10-12ph) +Early July yes (some dates available) +Prayer Facility included +Deposit minimum 500 diff --git a/20250926151524-workflow_moc.org b/20250926151524-workflow_moc.org new file mode 100644 index 0000000..825af12 --- /dev/null +++ b/20250926151524-workflow_moc.org @@ -0,0 +1,12 @@ +:PROPERTIES: +:ID: 8CE93986-280B-45BD-9DF2-5D06586DDDE7 +:END: +#+title: workflow-moc +#+filetags: :workflow:moc: + +What are the use cases of the macbook and the pc: + +* Macbook +** + +* PC diff --git a/20250926151524-workflow_moc.org~ b/20250926151524-workflow_moc.org~ new file mode 100644 index 0000000..ae1d805 --- /dev/null +++ b/20250926151524-workflow_moc.org~ @@ -0,0 +1,6 @@ +:PROPERTIES: +:ID: 8CE93986-280B-45BD-9DF2-5D06586DDDE7 +:END: +#+title: workflow-moc +#+filetags: :workflow:moc: + diff --git a/20251002154125-microlise_moc.org b/20251002154125-microlise_moc.org new file mode 100644 index 0000000..3cc0abd --- /dev/null +++ b/20251002154125-microlise_moc.org @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: ABF4A0BE-0309-48A6-92ED-76031B3D2F86 +:END: +#+title: microlise_moc +#+filetags: :career:work: + +* [[id:2BFB84B2-2129-4AE3-8E69-290CA5BF9747][pre_work_prep_microlise]] diff --git a/20251002154125-microlise_moc.org~ b/20251002154125-microlise_moc.org~ new file mode 100644 index 0000000..2b4155b --- /dev/null +++ b/20251002154125-microlise_moc.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: ABF4A0BE-0309-48A6-92ED-76031B3D2F86 +:END: +#+title: microlise_moc + diff --git a/20251002154204-pre_work_prep_microlise.org b/20251002154204-pre_work_prep_microlise.org new file mode 100644 index 0000000..5bd6fcf --- /dev/null +++ b/20251002154204-pre_work_prep_microlise.org @@ -0,0 +1,27 @@ +:PROPERTIES: +:ID: 2BFB84B2-2129-4AE3-8E69-290CA5BF9747 +:END: +#+title: pre_work_prep_microlise +#+filetags: :work: +#+AUTHOR: Zaine +#+DATE: <2025-10-02 Thu> +#+OPTIONS: toc:t +#+STARTUP: overview + +* Clothing + +* Bag(s) +** If going directly from work to mosque: +** If going back home: + +* Timings +<2025-10-06 Mon>: 9:15pm arrival + +* Petrol/Transport +Taking two cars: +- mine 2 days a week (friday and wednesday) +- Bajis car on the rest of the week + +* Documents + +* diff --git a/20251002154204-pre_work_prep_microlise.org~ b/20251002154204-pre_work_prep_microlise.org~ new file mode 100644 index 0000000..1bb7fce --- /dev/null +++ b/20251002154204-pre_work_prep_microlise.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: 2BFB84B2-2129-4AE3-8E69-290CA5BF9747 +:END: +#+title: pre_work_prep_microlise + diff --git a/20251019114736-server_moc.org b/20251019114736-server_moc.org new file mode 100644 index 0000000..c2d3911 --- /dev/null +++ b/20251019114736-server_moc.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: f09cb4ed-1407-4187-9002-de2c5db13a8f +:END: +#+title: server_moc +#+filetags: :moc:server: + +[[id:2c2d8df4-ad36-40ab-9f30-8a047b372956][old_nextcloud_server_code]] + +[[id:a9829b5d-690d-4a21-ba94-ac8beac4d439][old_nginx_code]] diff --git a/20251019114736-server_moc.org~ b/20251019114736-server_moc.org~ new file mode 100644 index 0000000..75f7c57 --- /dev/null +++ b/20251019114736-server_moc.org~ @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: f09cb4ed-1407-4187-9002-de2c5db13a8f +:END: +#+title: server_moc +#+filetags: :moc:server: + +[[id:2c2d8df4-ad36-40ab-9f30-8a047b372956][old_server_code]] diff --git a/20251019114758-old_nextcloud_server_code.org b/20251019114758-old_nextcloud_server_code.org new file mode 100644 index 0000000..fe5ad8c --- /dev/null +++ b/20251019114758-old_nextcloud_server_code.org @@ -0,0 +1,71 @@ +:PROPERTIES: +:ID: 2c2d8df4-ad36-40ab-9f30-8a047b372956 +:END: +#+title: old_nextcloud_server_code +#+filetags: :server:self-hosting: + +* wg +Shakkal123! + +docker run ghcr.io/wg-easy/wg-easy:14 node -e 'const bcrypt = require("bcryptjs"); const hash = bcrypt.hashSync("Shakkal123!", 10); console.log(hash.replace(/\$/g, "$$$$"));' + +Unable to find image 'ghcr.io/wg-easy/wg-easy:14' locally +14: Pulling from wg-easy/wg-easy +Digest: sha256:5f26407fd2ede54df76d63304ef184576a6c1bb73f934a58a11abdd852fab549 +Status: Downloaded newer image for ghcr.io/wg-easy/wg-easy:14 + +$$2a$$10$$E1lkGe/IH5EnFrQLhDH2M.yKk3Q7KlgRuu.fzf/76CbWoAMy4G83u + +* nextcloud: + +# Allow unauthenticated access to /nextcloud +location ^~ /nextcloud/ { + auth_basic off; + + proxy_pass http://localhost:8007/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + client_max_body_size 512M; + client_body_buffer_size 512k; + + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; +} + + + # iOS and calendar/carddav fixes + location ^~ /.well-known/carddav { + return 301 $scheme://$host/nextcloud/remote.php/dav; + } + + location ^~ /.well-known/caldav { + return 301 $scheme://$host/nextcloud/remote.php/dav; + } + + location ^~ /.well-known { + return 301 $scheme://$host/nextcloud/index.php$uri; + } + +* technitium + location /technitium/ { + proxy_pass http://localhost:5380/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Rewrite path for base URL + rewrite ^/technitium/(.*)$ /$1 break; + } + + curl -X GET "https://zserver.zapto.org/portainer/api/endpoints/3/docker/containers/json?all=true" -H "X-API-Key: ptr_KFQqKse9K4Nc9M5jnpc61fpAvGzdTOXTzswz9CwOF74=" -u "admin:shakkal123" diff --git a/20251019114758-old_nextcloud_server_code.org~ b/20251019114758-old_nextcloud_server_code.org~ new file mode 100644 index 0000000..96473f2 --- /dev/null +++ b/20251019114758-old_nextcloud_server_code.org~ @@ -0,0 +1,71 @@ +:PROPERTIES: +:ID: 2c2d8df4-ad36-40ab-9f30-8a047b372956 +:END: +#+title: old_cloudflare_server_code +#+filetags: :server:self-hosting: + +* wg +Shakkal123! + +docker run ghcr.io/wg-easy/wg-easy:14 node -e 'const bcrypt = require("bcryptjs"); const hash = bcrypt.hashSync("Shakkal123!", 10); console.log(hash.replace(/\$/g, "$$$$"));' + +Unable to find image 'ghcr.io/wg-easy/wg-easy:14' locally +14: Pulling from wg-easy/wg-easy +Digest: sha256:5f26407fd2ede54df76d63304ef184576a6c1bb73f934a58a11abdd852fab549 +Status: Downloaded newer image for ghcr.io/wg-easy/wg-easy:14 + +$$2a$$10$$E1lkGe/IH5EnFrQLhDH2M.yKk3Q7KlgRuu.fzf/76CbWoAMy4G83u + +* nextcloud: + +# Allow unauthenticated access to /nextcloud +location ^~ /nextcloud/ { + auth_basic off; + + proxy_pass http://localhost:8007/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + client_max_body_size 512M; + client_body_buffer_size 512k; + + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; +} + + + # iOS and calendar/carddav fixes + location ^~ /.well-known/carddav { + return 301 $scheme://$host/nextcloud/remote.php/dav; + } + + location ^~ /.well-known/caldav { + return 301 $scheme://$host/nextcloud/remote.php/dav; + } + + location ^~ /.well-known { + return 301 $scheme://$host/nextcloud/index.php$uri; + } + +* technitium + location /technitium/ { + proxy_pass http://localhost:5380/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Rewrite path for base URL + rewrite ^/technitium/(.*)$ /$1 break; + } + + curl -X GET "https://zserver.zapto.org/portainer/api/endpoints/3/docker/containers/json?all=true" -H "X-API-Key: ptr_KFQqKse9K4Nc9M5jnpc61fpAvGzdTOXTzswz9CwOF74=" -u "admin:shakkal123" diff --git a/20251019114758-old_server_code.org~ b/20251019114758-old_server_code.org~ new file mode 100644 index 0000000..e08e219 --- /dev/null +++ b/20251019114758-old_server_code.org~ @@ -0,0 +1,71 @@ +:PROPERTIES: +:ID: 2c2d8df4-ad36-40ab-9f30-8a047b372956 +:END: +#+title: old_server_code +#+filetags: :server:self-hosting: + +* wg +Shakkal123! + +docker run ghcr.io/wg-easy/wg-easy:14 node -e 'const bcrypt = require("bcryptjs"); const hash = bcrypt.hashSync("Shakkal123!", 10); console.log(hash.replace(/\$/g, "$$$$"));' + +Unable to find image 'ghcr.io/wg-easy/wg-easy:14' locally +14: Pulling from wg-easy/wg-easy +Digest: sha256:5f26407fd2ede54df76d63304ef184576a6c1bb73f934a58a11abdd852fab549 +Status: Downloaded newer image for ghcr.io/wg-easy/wg-easy:14 + +$$2a$$10$$E1lkGe/IH5EnFrQLhDH2M.yKk3Q7KlgRuu.fzf/76CbWoAMy4G83u + +* nextcloud: + +# Allow unauthenticated access to /nextcloud +location ^~ /nextcloud/ { + auth_basic off; + + proxy_pass http://localhost:8007/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + client_max_body_size 512M; + client_body_buffer_size 512k; + + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; +} + + + # iOS and calendar/carddav fixes + location ^~ /.well-known/carddav { + return 301 $scheme://$host/nextcloud/remote.php/dav; + } + + location ^~ /.well-known/caldav { + return 301 $scheme://$host/nextcloud/remote.php/dav; + } + + location ^~ /.well-known { + return 301 $scheme://$host/nextcloud/index.php$uri; + } + +* technitium + location /technitium/ { + proxy_pass http://localhost:5380/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Rewrite path for base URL + rewrite ^/technitium/(.*)$ /$1 break; + } + + curl -X GET "https://zserver.zapto.org/portainer/api/endpoints/3/docker/containers/json?all=true" -H "X-API-Key: ptr_KFQqKse9K4Nc9M5jnpc61fpAvGzdTOXTzswz9CwOF74=" -u "admin:shakkal123" diff --git a/20251101123637-backlog.org b/20251101123637-backlog.org new file mode 100644 index 0000000..ed1c736 --- /dev/null +++ b/20251101123637-backlog.org @@ -0,0 +1,9 @@ +:PROPERTIES: +:ID: 580cc3a5-af8e-4cbe-b5ad-5b06680e6c37 +:END: +#+title: backlog +#+filetags: :backlog: + +* To sort: + +- https://forge.medium.com/a-simple-tool-for-personal-growth-dc1e822aa229 diff --git a/20251101123637-backlog.org~ b/20251101123637-backlog.org~ new file mode 100644 index 0000000..1b7726c --- /dev/null +++ b/20251101123637-backlog.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: 580cc3a5-af8e-4cbe-b5ad-5b06680e6c37 +:END: +#+title: backlog + diff --git a/20251109205925-old_nginx_code.org b/20251109205925-old_nginx_code.org new file mode 100644 index 0000000..63e422c --- /dev/null +++ b/20251109205925-old_nginx_code.org @@ -0,0 +1,262 @@ +:PROPERTIES: +:ID: a9829b5d-690d-4a21-ba94-ac8beac4d439 +:END: +#+title: old_nginx_code +#+filetags: :server: + + + +-> % cat /etc/nginx/sites-available/zserver + + +server { + server_name zainezq.com; + + access_log /var/log/nginx/zserver.access.log combined; + error_log /var/log/nginx/zserver.error.log warn; + # Basic authentication for the entire server + auth_basic "Restricted Access"; + auth_basic_user_file /etc/nginx/.htpasswd; + + # Root location + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + + root /home/zaine/master-folder/org_files/org_web/output; + index index.html index.htm; + try_files $uri $uri/ =404; + } + +location /nginx_status { + stub_status; + } + +location /dockge/ { + proxy_pass http://127.0.0.1:5021/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; +} + + + +location /guac/ { + proxy_pass http://127.0.0.1:3003/guacamole/; + proxy_http_version 1.1; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; +} + + # PGAdmin4 location + location /pgadmin4/ { + proxy_set_header X-Script-Name /pgadmin4; + proxy_set_header Host $host; + proxy_pass http://127.0.0.1:5050; + proxy_redirect off; + } + + location /pdf/ { + proxy_pass http://127.0.0.1:8002/pdf/; + proxy_set_header X-Script-Name /pdf; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_redirect off; + } + + location /calibre { + proxy_bind $server_addr; + proxy_pass http://127.0.0.1:8083; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Script-Name /calibre; # IMPORTANT: path has NO trailing slash + # This rewrites Calibre-Web's internal paths + proxy_redirect off; + proxy_http_version 1.1; + client_max_body_size 100M; + } + + + location /codeserver/ { + proxy_pass http://localhost:8441/; + rewrite ^/codeserver(/.*)$ $1 break; + + proxy_set_header Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Accept-Encoding gzip; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /filebrowser { + # prevents 502 bad gateway error + proxy_buffers 8 32k; + proxy_buffer_size 64k; + + client_max_body_size 75M; + + # redirect all HTTP traffic to localhost:8088; + proxy_pass http://127.0.0.1:9991; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + #proxy_set_header X-NginX-Proxy true; + + # enables WS support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_read_timeout 999999999; + } + + + # Miniflux location + location /miniflux/ { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://127.0.0.1:9433/miniflux/; + proxy_redirect off; + } + + # Jupyter location + location /jupyter/ { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://127.0.0.1:8888/jupyter/; + proxy_redirect off; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } + + location /portainer/ { + proxy_pass https://localhost:9443/; + proxy_ssl_verify off; # Because Portainer uses a self-signed cert by default + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Authorization ""; + # Required for WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Rewrite URL base path + rewrite ^/portainer(/.*)$ $1 break; + } + +location /wireguard/ { + proxy_pass http://127.0.0.1:124/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Rewrite assets for subpath compatibility + proxy_set_header Accept-Encoding ""; + sub_filter 'href="/' 'href="/wireguard/'; + sub_filter 'src="/' 'src="/wireguard/'; + sub_filter_types text/css application/javascript; + sub_filter_once off; +} + +# /password -> /password/ +location = /password { return 301 /password/; } + +# Main app/API (disable inherited basic auth here) +location ^~ /password/ { + auth_basic off; + + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # WebSockets + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Keep the /password prefix upstream (NO trailing slash here) + proxy_pass http://127.0.0.1:8006; +} + +# (Optional but tidy) If you keep a dedicated WS block, disable auth there too +location ^~ /password/notifications/hub { + auth_basic off; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + + proxy_pass http://127.0.0.1:8006; +} + + + # Optional: Add a custom error page + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + # Optional: Cache static assets for performance (add this new block) +# location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot|svg|html|htm)$ { +# root /home/zaine/master-folder/org_files/org_web/output; +# expires 30d; +# access_log off; +# } + + # Optional: Deny access to hidden files + location ~ /\. { + deny all; + } + + listen 443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/zainezq.com-0001/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/zainezq.com-0001/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot + + + + + +} + + +server { + if ($host = zserver.zapto.org) { + return 301 https://$host$request_uri; + } # managed by Certbot + + listen 80; + server_name zserver.zapto.org; + return 404; # managed by Certbot +} + diff --git a/20251109205925-old_nginx_code.org~ b/20251109205925-old_nginx_code.org~ new file mode 100644 index 0000000..f020b83 --- /dev/null +++ b/20251109205925-old_nginx_code.org~ @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: a9829b5d-690d-4a21-ba94-ac8beac4d439 +:END: +#+title: old_nginx_code + + +server { server_name zainezq.com; access_log /var/log/nginx/zserver.access.log combined; error_log /var/log/nginx/zserver.error.log warn; # Basic authentication for the entire server auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd; # Root location location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; root /home/zaine/master-folder/org_files/org_web/output; index index.html index.htm; try_files $uri $uri/ =404; } location /nginx_status { stub_status; } location /dockge/ { proxy_pass http://127.0.0.1:5021/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /guac/ { proxy_pass http://127.0.0.1:3003/guacamole/; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } # PGAdmin4 location location /pgadmin4/ { proxy_set_header X-Script-Name /pgadmin4; proxy_set_header Host $host; proxy_pass http://127.0.0.1:5050; proxy_redirect off; } location /pdf/ { proxy_pass http://127.0.0.1:8002/pdf/; proxy_set_header X-Script-Name /pdf; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; } location /calibre { proxy_bind $server_addr; proxy_pass http://127.0.0.1:8083; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Scheme $scheme; proxy_set_header X-Script-Name /calibre; # IMPORTANT: path has NO trailing slash # This rewrites Calibre-Web's internal paths proxy_redirect off; proxy_http_version 1.1; client_max_body_size 100M; } location /codeserver/ { proxy_pass http://localhost:8441/; rewrite ^/codeserver(/.*)$ $1 break; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Accept-Encoding gzip; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /filebrowser { # prevents 502 bad gateway error proxy_buffers 8 32k; proxy_buffer_size 64k; client_max_body_size 75M; # redirect all HTTP traffic to localhost:8088; proxy_pass http://127.0.0.1:9991; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #proxy_set_header X-NginX-Proxy true; # enables WS support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 999999999; } # Miniflux location location /miniflux/ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:9433/miniflux/; proxy_redirect off; } # Jupyter location location /jupyter/ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:8888/jupyter/; proxy_redirect off; # WebSocket support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } location /portainer/ { proxy_pass https://localhost:9443/; proxy_ssl_verify off; # Because Portainer uses a self-signed cert by default proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Authorization ""; # Required for WebSocket support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # Rewrite URL base path rewrite ^/portainer(/.*)$ $1 break; } location /wireguard/ { proxy_pass http://127.0.0.1:124/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Rewrite assets for subpath compatibility proxy_set_header Accept-Encoding ""; sub_filter 'href="/' 'href="/wireguard/'; sub_filter 'src="/' 'src="/wireguard/'; sub_filter_types text/css application/javascript; sub_filter_once off; } # /password -> /password/ location = /password { return 301 /password/; } # Main app/API (disable inherited basic auth here) location ^~ /password/ { auth_basic off; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSockets proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # Keep the /password prefix upstream (NO trailing slash here) proxy_pass http://127.0.0.1:8006; } # (Optional but tidy) If you keep a dedicated WS block, disable auth there too location ^~ /password/notifications/hub { auth_basic off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8006; } # Optional: Add a custom error page error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # Optional: Cache static assets for performance (add this new block) # location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot|svg|html|htm)$ { # root /home/zaine/master-folder/org_files/org_web/output; # expires 30d; # access_log off; # } # Optional: Deny access to hidden files location ~ /\. { deny all; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/zainezq.com-0001/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/zainezq.com-0001/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = zserver.zapto.org) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name zserver.zapto.org; return 404; # managed by Certbot } diff --git a/20251122223053-keyboard.org b/20251122223053-keyboard.org new file mode 100644 index 0000000..e9ce438 --- /dev/null +++ b/20251122223053-keyboard.org @@ -0,0 +1,203 @@ +:PROPERTIES: +:ID: 0217f537-442a-4593-8c69-d481f0d1f2a8 +:END: +#+title: keyboard +#+filetags: :hardware:linux: + +* Keyboard inputs + +This all comes from the fact that a "key press" isn't one thing --- it's +a stack of specs and translations from *keyboard hardware → USB/HID → +Linux kernel → userspace (XKB/Wayland) → Hyprland binds*. + + +** 1. Big picture: what happens when you press a key? +:PROPERTIES: +:CUSTOM_ID: big-picture-what-happens-when-you-press-a-key +:END: +When you hit a key (like your "lock" key), roughly this happens: + +#+begin_src text +Physical switch on keyboard + ↓ +Keyboard firmware → USB HID "usage" (e.g. 0x07:0xE3 = Left GUI) + ↓ +Linux kernel input subsystem (evdev) → KEY_LEFTMETA (code 125) + ↓ +libinput / xkbcommon → keysyms (like Super_L, L, etc.) + ↓ +Hyprland → your `bind = SUPER, L, exec, ...` +#+end_src + +The "topic" we've been poking at is basically *understanding each layer +in that stack*. + +-------------- + +** 2. USB HID: where =700e3= comes from +:PROPERTIES: +:CUSTOM_ID: usb-hid-where-700e3-comes-from +:END: +Modern USB keyboards follow the *USB HID (Human Interface Device) +specification*. This spec defines *Usage Tables*: numerical codes for +things like keys, buttons, axes, etc. + +- The keyboard page is *Usage Page 0x07 (Keyboard/Keypad)*. + +- In your =evtest= output, =MSC_SCAN value 700e3= means: + + - =0x07= (Keyboard page) + - =0xE3= (Left GUI / "Windows/Super" key) + +You can see the official tables here (PDF): + +- *HID Usage Tables (includes Keyboard/Keypad page 0x07)* + [[https://usb.org/sites/default/files/hut1_21.pdf]] + ([[https://usb.org/sites/default/files/hut1_21.pdf?utm_source=chatgpt.com][USB + Implementers Forum]]) + +If you scroll to the *Keyboard/Keypad Page (0x07)* section, it lists all +the key usages: A, B, C, modifiers, function keys, etc. There's also a +standalone Keyboard/Keypad-page extract people mirror, like this PDF +snippet: +([[https://d1.amobbs.com/bbs_upload782111/files_47/ourdev_692986N5FAHU.pdf?utm_source=chatgpt.com][d1.amobbs.com]]) + +So: + +- =700e3= = Page =0x07=, Usage =0xE3= → /Keyboard Left GUI/ +- =7000f= = Page =0x07=, Usage =0x0F= → /Keyboard L/ key + +That's how we knew your lock key was sending *Super + L*. + +-------------- + +** 3. Linux input subsystem: =EV_MSC=, =EV_KEY=, =KEY_LEFTMETA= +:PROPERTIES: +:CUSTOM_ID: linux-input-subsystem-ev_msc-ev_key-key_leftmeta +:END: +Linux has a dedicated *input subsystem* in the kernel (=drivers/input=, +=drivers/hid= etc.) that takes those HID usages and turns them into a +unified stream of *input events*. +([[https://docs.kernel.org/input/input.html?utm_source=chatgpt.com][Linux +Kernel Documentation]]) + +Key ideas: + +- Devices expose =/dev/input/eventX= nodes. + +- Each event is a struct with: + + - =type= (e.g. =EV_KEY=, =EV_MSC=, =EV_REL=, =EV_SYN=) + - =code= (e.g. =KEY_L=, =KEY_LEFTMETA=) + - =value= (pressed = 1, released = 0, repeat = 2) + +Docs worth bookmarking: + +- *Linux input subsystem overview* + [[https://docs.kernel.org/input/input.html]] + ([[https://docs.kernel.org/input/input.html?utm_source=chatgpt.com][Linux + Kernel Documentation]]) + +- *Input event types and codes (=event-codes.txt=)* + [[https://www.kernel.org/doc/Documentation/input/event-codes.txt]] + ([[https://www.kernel.org/doc/Documentation/input/event-codes.txt?utm_source=chatgpt.com][Kernel.org]]) + +The *keycode definitions* (=KEY_L=, =KEY_LEFTMETA=, etc.) live in: + +- =include/uapi/linux/input-event-codes.h= in the kernel source Example + mirror: + [[https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/input-event-codes.h]] + ([[https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/input-event-codes.h?utm_source=chatgpt.com][GitHub]]) + +When =evtest= prints: + +#+begin_src text +type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e3 +type 1 (EV_KEY), code 125 (KEY_LEFTMETA), value 0 +#+end_src + +that means: + +- =EV_MSC / MSC_SCAN= → "Here is the raw hardware scancode" (from USB + HID). +- =EV_KEY / KEY_LEFTMETA= → "Linux mapped that scancode to logical key + LEFTMETA". + +-------------- + +** 4. XKB / xkbcommon: mapping to actual characters & modifiers +:PROPERTIES: +:CUSTOM_ID: xkb-xkbcommon-mapping-to-actual-characters-modifiers +:END: +Above the kernel, you've got an extra mapping layer that says: + +#+begin_quote +For keycode N, with this layout, when Shift is held, produce this +character/symbol. +#+end_quote + +On X11 this is handled by *XKB (X Keyboard Extension)*; on Wayland +compositors (including Hyprland) the same ideas are implemented via +*xkbcommon*. + +Docs: + +- *X Keyboard Extension (XKB) protocol spec* + [[https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html]] + ([[https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html?utm_source=chatgpt.com][X.Org]]) + +- *Arch Wiki: X keyboard extension* (good high-level intro) + [[https://wiki.archlinux.org/title/X_keyboard_extension]] + ([[https://wiki.archlinux.org/title/X_keyboard_extension?utm_source=chatgpt.com][ArchWiki]]) + +- A nice "practical" walkthrough of XKB concepts: + [[https://medium.com/@damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450][https://medium.com/[cite/t:@damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450]]] + ([[https://medium.com/%40damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450?utm_source=chatgpt.com][Medium]]) + +Hyprland, Sway, etc. all use libinput + xkbcommon under the hood to +interpret those keycodes and translate them into keysyms and modifiers. + +-------------- + +** 5. Hyprland / your config: where the bindings fit in +:PROPERTIES: +:CUSTOM_ID: hyprland-your-config-where-the-bindings-fit-in +:END: +Hyprland sits at the top of this stack: + +- It listens to the input events (via libinput). +- It sees keysyms/modifiers (e.g. =Super=, =L=). +- It matches them against your config: + +#+begin_src ini +bind = SUPER, L, exec, hyprlock +#+end_src + +So your keyboard's "lock" key: + +1. Firmware sends HID usages =0xE3= (Left GUI) and =0x0F= (L). +2. Linux maps them to =KEY_LEFTMETA= (125) and =KEY_L= (38). +3. xkbcommon maps that to =Super= + =L=. +4. Hyprland says: "Ah, SUPER+L → run =hyprlock=". + +The "topic" you stumbled into is just *peeling back each abstraction +layer*. + +-------------- + +** 6. Handy tools & libraries if you want to go deeper +:PROPERTIES: +:CUSTOM_ID: handy-tools-libraries-if-you-want-to-go-deeper +:END: +- =evtest=, =libinput debug-events=, =showkey= → To watch what your + keyboard is actually sending. + +- *Python-evdev* -- Python bindings to read =/dev/input/event*= + yourself: [[https://python-evdev.readthedocs.io/]] + ([[https://python-evdev.readthedocs.io/?utm_source=chatgpt.com][python-evdev.readthedocs.io]]) + +- Linux input subsystem docs again: + [[https://docs.kernel.org/driver-api/input.html]] + ([[https://docs.kernel.org/driver-api/input.html?utm_source=chatgpt.com][Linux + Kernel Documentation]]) + diff --git a/20251122223053-keyboard.org~ b/20251122223053-keyboard.org~ new file mode 100644 index 0000000..b07615d --- /dev/null +++ b/20251122223053-keyboard.org~ @@ -0,0 +1,5 @@ +:PROPERTIES: +:ID: 0217f537-442a-4593-8c69-d481f0d1f2a8 +:END: +#+title: keyboard + diff --git a/20251214210526-useful_c_imports.org b/20251214210526-useful_c_imports.org new file mode 100644 index 0000000..086b118 --- /dev/null +++ b/20251214210526-useful_c_imports.org @@ -0,0 +1,7 @@ +:PROPERTIES: +:ID: d939e477-d1e9-43ea-960e-8727246d12a3 +:END: +#+title: useful-c-imports +#+filetags: :coding:notes: + +- SDL2 [[https://wiki.libsdl.org/SDL2/FrontPage][See this]] diff --git a/20251214210526-useful_c_imports.org~ b/20251214210526-useful_c_imports.org~ new file mode 100644 index 0000000..e8c39fc --- /dev/null +++ b/20251214210526-useful_c_imports.org~ @@ -0,0 +1,6 @@ +:PROPERTIES: +:ID: d939e477-d1e9-43ea-960e-8727246d12a3 +:END: +#+title: useful-c-imports +#+filetags: :coding:notes: + diff --git a/assets/Big-O-Notation-3130482830.png b/assets/Big-O-Notation-3130482830.png new file mode 100644 index 0000000000000000000000000000000000000000..eaa37ad3bab70a1ae95b84eeb5ad7d0e7e9d119a GIT binary patch literal 237551 zcmeFYWn5Kn*Di`8pp;63gi1daQo6glySpT%yOAzo(H(m(_5Zxj^X`4l zhjaG%boTrq&Nb&f?=|ib*SN;GCxJ3j!btEq@K8`tNTMR2<)EP8#-N~HtiOZ>uB_`h z^8^3AvJp|Whk`=>4*B;imIC=5aFHG)r~(qOwzM>~0zo<3u^X^|<`XiPv$7X;GGJwA zqBLV?VrHgg0}d8CN)S6e11%Fh8!fZwGX4rM|C6bL3P?p#f?eO*l3LfmTF;Q$+0q7> z77EG)1hQeLp|P_6dmR`-R{_nwQXJEuG_gU!gP~a06>EGF%oSdkg7^to7jA`fq5ou`YY3S*xfDu&oE><92 zXDTauLSUxOEv?T|H|D5Em)wzefEL$w2>KUt{B7XYu<>4D@LX zEes*LvIiDI_a9Ok=(B@NK^BJpO>jO7(0{vPVG3CZyM?ZmF&C*bm4Ts=u7d@Ll$+nw z_`URdDQl4KZ_%jU({a*3Vganxan!>8K`KPsOZ@^Y5v=-f7y`p?+rm`kf;H-5d#ye5xqVw z6(cL75f!769wU`5t-c|Z5i<)L9SgmlAuA)G?EiS=f0{{1515FFo{65BiH(ktj)jeh zmG)oH{J!}=J)&Ukpl(Vdno-*FWO@r&|9v8QSLGg6cm)7PtY} zm*GF`3tVI8a{!rG+i?q9+nBx=wzks+qRm2=ljh%U{kP@)zjsCeG5*67f5Xkc!^*$A z3^17ex4&51DOg)ua0}>KIRf(i_sjoxLjDVXe(M+jpnvmSntuTpcOH%I2^4gais)xP z1?QAs^PR6c-a~bC%stGaf0yPEf&r8C^XQk~K!6x>#JfEr|2c#Df{L~K_cY?`KNn;F z&l%MJN(YJ_fU2IJe$9V{sO(F|Lm}p;&=>4~^+z=J?9W*S%0DWVc?J4=v*2ID6rSV# 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∾U^cx*Dnu&3N3-8X%oS>)msUvw-331 zu^i2w-xO1Ocza2hXE&iV$)dOUFx(Khi!aWcx;TBNo+#oP)(dQFwL+($%E^+13l7Y` z6L!uJU+L@(##YeXV1T2`hCj$JhBhwLfaSMNDv9>YQkTrJVJS!!9C#U>o$A`^Mtj%W0eZ!j5ivSKaE}00 zyrJH)I`ZWMw8;8;YMWxJpwJh-72HK+g$Ht+6}bsG)7qjy6$N^e_%cASf zph{gUiyW}!xvUJq@;Z;7Zi7Z1)70V%SrZ8$d0Lhw$tG;x&yXR}R( zO9a#WFYve_p12~gF=qPX;|E0&IEc_j)D&dxqNIHYcEnMXuK5R#Mkq6r8JMq6=Z zis;9^c%N!Hva_*WT#i)(KolZU!V)c}Mi>a_ExPUA=9ir*D2&Z8%>s5L}=q zEppy7#}iWN*dD7`Libi-&m16rFWx!cSeTk{O0~`FmiBYQx1ImOTX;CT*~fr90|R4~ zKu$$SbbH#|nHmJvvSD2-b$MXA@!A-u+N43n#tx&cwF1d8bo>=w#u?(23hjD%E0&}+ zmY=t?IQGZ_c9sX8lg638Mh}X0Dc9A-;vpz<5a%G*gtc&pb4A#^!Dd?L72TiIL=27(d&)Zkx1ND`&FGsdVqS>=!T*h{nB&mLKyerJUb%B~2%H zZI7X<*vT1~Ig9*$Q`W^+su8BsA@08 zil?`IZ26-^9wj7qpqn{k{*w%vA^O?s6+9=b=8=+H zZD-A%2`S%%y!KmNcIdz@GHltUT1*$aDQcIwV)wkA{{Dw{Z*qx|e{w8+eY2Na^#uh5 z%e9#G?6Hw;9sf4vv^+78YdK zGFJWB7=Vc+{8AoZM z$$Hx{85PeHn;O1P##xO_Izh0h4A4BwTUgO*`BW?26ywG1@6NJi5@lhUYZYEb@tRBm zbN6pZT72)mT%pjWv9g3{pAz*@mvi)52@aEqD4!jsSYeP+a*N3Dh(=5j%rdFHwQYNE zSbq_eE}~{)DtIs3UchNBLe{UyiTEv5|HW1a%vq%HeirNL%;+1;~sq{I||mufB) zx!#7g06UECv8kG9>%H7g;T-9tIjwR#qSN&TKIF5$4 zW=_<@>69OpL%sg*$DyF9F#--Rm zwe2^flN(^LqlyxBm_PgblZ68ln59%t5Zk2#|K3TBE6}-84SE)9j*9#jT53H?Opqpi z9g({iBe;BxCV3Cf&beFV_))t-aoS?q#x=ALH$Nb2ypTvs6jC`QB0jr#YKTV+5iPiU zdyymdB8WYTZUBH79E`Crr=ytKz_IX`7-b( zb3CX59hRG4^O3lchl%4GrMQp{Y9q`?C*YQev44X<@_L^K!j*7U^b& z(?EN08*b6FRil1H`Asy4i1f04s&gHpbovtG@cJ?~{|{@gNMvn9j2J2DAb|A5-dYb}Cq0Lc|M#w*^UI7a&H`-KO|n z!p`i{&KwYCX4>}FYG@TEHp$)!Pd(*mx!{Vtl1=L;moBNtA+HPo>6z0rG?6IO3%7it z0wg9zN&rRayx6Hb*yJ9MXGxt`;uy8+4%2DhSN`0+?S(RoA!e3J5qA=4F}X>@i#3(Y zR>=E|UDo3y=ZdJr|H+1fjiHvImXNi8Wo5BvF-Z+=pY=Cgiw^MsNI+|dQuE+R-u~#j@jlj!lJ0^^5sWun{$D;pc1KYdEGs2y%~JO5arqpxrL$=xl+0vL;i zwH;_`q+PUdU*Ub0NIPtL@i1t#{t{^O{eJSq#h!H#mM}%9&k$0h5Yl)EhhB;+fmwog zb(C_|EE7hnfQc2$X#;kdGza&sz(S0C(Z9A;3q7^h=emo2{ng(uIyfi`<=N~OC`NVy zutIXDAUQO)=Vcz~U>*rGQCA9#*X6aq6IECjr@JT5_#`)U2&n*zinZAq%&Xl1A1bK@&n3Vm7eDvVC-&aW3^{kA1Z)qCC0aFW zcdu5N=`NP%zXV;HzOgpmO<_4#6&ZL?!v$;VX<$m1Q%Zsa+`rKW-t&_M-h*~k$!W6I z5+*-A%>PgV%!a8HUW5isH>lsR1zdk%g|iT=u_v&*SUt-|)C$eS^u2y47cRR1e?!9f zo>}V@{f9RE0+a^9HCew(*E_oGE~ZSxG{yoI;sQg2$>2KP+=MD^pQ?;Am6bMQM$cCq zcjC3cgEciMevm7ATtO<#lC;B)W!h=-Mt_kJiVJ6vk%9Im=eq~;|0@f4Zw&pDT|4BI zo>tzS+PdVwkLGgs@|s&-Rv?6*KSn!SZy$Obgbxjc;m?>vF$G5cTx_E>D^j)!&5I7^ zm{W9h=c<|UV}M()ISgUMy=>q5ySn{8;wGCo!B?o4FKlc^jL z<^M!TL*N&Ml_i`xOjM^ zoz*Y~EP@%LJuxt-9h`Obj0}1S`=D1q_Z=I$oiorK!9s#=zo5OCLtk7<@@)1 zxJ7woot@b`J4G=3NO@}kpV_(hDLo?t7_7AR^^NK35`BDpJUBltZg0=#K;;m1_uFmY zZ7v7I?K+L`(PlF?oIy&=5wQ^*YdD4Gbtc~fZs@@F&FXRRvcVsbXQI=gv!^iKJuR-HmFt9NGDtv6{uwkf zjK!Ct9>(jkICX4u~`*_Q_n|eE+Ax!?QCw#97ZRif(CNXYb5<>nToQ z;r{!3{vX{5l2n^j#La7&`H;{nh=BWF%BaSlRaJF$bpQo@DKj^_&p-)RHV4owT#`As zgq2NA&tI54A>~U)Yc1X>zIW-iJjB z0b!P>j8KqU{N?A&v5aa=8LV)>JO|!TbZEOqLBN%3f=k`DP{N^sAZm=68Hk5N4eRU2 zCnjg+R{Q36X}P%(#KX?c*rErv<(QUb!T=B_@8~C|^|paH621zpO5nH;4h=CRBmn$C z6(9(B2!~70(B=2JMl?1yK4sZeGJ@6pVf-#nr=#9C>Nv%dX=E%r``;U7Kpy#AC!L9^ zXrD}5s8i|U<&qRbz&@jY)Gr`czihR2Mhy&M@2)f+U*Fuh{QZN9^K_fkZ<`SWq+W5^ ze64;D$T3PvESrX(?d*~-_vyG1&=aR1h<$%)cA!0>Uw{uAcZ24%)-f_+SpSoSy}q?| zV0f6LxVRXYRsMH@yu1i<$;dEFKeXiszLxfgk``b%mGdAC zF^Fxz?f1~@MmNkbr;^Z@cptpQo6 zpjxa&TqHz7GhxsMHiL+;l1Y7!RqS)dhDA8qq5pkogCo6T^hnQis&$=&Av!5JEB+oW zmG;mxwL}}TjGcV=m-|26eLz@oZu!5M!t=2u@ZMRJJH)Zk05GFKOh~IBS(s?;;GX*W z8W2MHOF%BC|6g)I(Rqzsrk1}Aw0gEWpj+N3IyB{mNzjs$B%@AbZ)^Zu`uCHjEx%5{`fNrWKokKhcE2MAEMv;2$(R73 z5sLx<9K`!-qWSAf9N)qDd0DYuzkw1ath-0)!f*zgDG)4N8R+s2#gpx+z3w8A3i+fO zvBhXc^Q-FVwTz9icjxGQ#K35lvX}C9OBvH;bGupbIAdeM9758-oz-WWnOmQ@UG!Wz z3iuR`Lclf+c%t723{zrnq}^{%n{@eOP>HliVE%mqV5=-JwS1R4mhGV11i%(8flKJM z;SKut`2nf{FnoFI8O|T|P#<{1F2ErIH)_^3KJeEw=*?Slts$-J696E}f4(lmMTP@x zHG@YQ$I5iHWm8jAi_ZWN^V5VH=;L&Ju#C|F8sB4++>Fs&0uVd=ig|? z%5ejm=|Ghe=4Lx+W3Ar|b4|4xO)Hh^sA1W)15CW`==$@Kf&F!cS8k3UQO1#_^aL+3Qw{#^D2 zxA1GNh4DvtPFMYe!J}Hnw))rR`@g~zq?-S0-d&`I?Lf22s%hozra%AiYNk*ZfY1e^ z8o;Y#1y4?@%F4+eoE}mkhTJac>e?{L^WI05l9B?Zz>@|BWU7ohN0;j%-+nhI z;0z@cH_{hGX4AO{Ff65@S8wRc5r%XZm|gq#4G?$;pj$ismd6L6|x6PWq>@P zx9h?sgo6?l8aunDt!-53yaOQMY`1Sd05gTs)Ij$dkk@~GI&Bv4y(Nv44fPY9sx6ii zaND;nVkl7`uCJ>b2OI?y5C#EGGB5CKdHtP#yQaCLN8FN$Z*KQ}%v-h*o1CuKlGE7p z6#?7d{cLAI^9AC!1_M@rJ_sZ!b416cMP%nr^dVE3>&Uj+uScUy&RqcZPBZHKx#!#x zEQ6WMU#JOoeVQcO@VjEw(Mdl%IVouej!7Ol5IzC$nY}dNU0Tl=d}P75`CvGI^g&im z4j7j&n%6EW*0MOebp+t$tT}GLg=<)B2bQ(h)OPjc3SD(vj58c6=v+Y1#k=|zp0KJrAqO$l?2P`oDYd{18}tX0G&9K@ zSuK~2l>DJF`@T(qlxBhH;#v3x1E^25Ng&c1%t&gSP?S84lrc_{NmKB`Rdz`;`K|gAxIVrJuWeDUjTV3uki2g$hE+Z$n#3B8Ew2vBk{!%(}ZDj zdDjI#Fl3!?W8C&_P(radwWmNqnle`XL0CeK&(17zZBA|Op-hYt7+y|QJoP*UPG~n= zZgKgfxx*AslP~gz%^1y)3btZ{Ra<#7n+CV?{$M0boT7-lkcx8}5pMarU^O;mEo4sk z5zj(F*#Z}gy(9I_powsvezvBmy|f5rBxEUDC?9h~Jdf`Zom_WQ^=ToL(p+%EcUyvT zJ-h0;ecw2|#O#_m=bH<<&=!M73zWm8*KOf^zP;s=8vHL+T~+$8NMD9a=*Tfx0Bk|E zE3L0MXDxFCFC%HeVGS)V@-mMx11fO1*QU@|E-*QFz)@2=`;ZF}C( zqr|S`=fl%7hwKO0_rx(;?hGu&1;j?c|6h!APkniu|A>l)HnYAka4^hao#&m^{gU0i z(>oCJFVJUQrx`7AT=ZHgLXjkl0Eo!|ofIe&iH=3#3=t6$iZc&f&*PqV-H`|06;ogh zaWXSAuNj)q&D+)lulwcsYmK^{uP3#4ff6?=Bg&Qr?^#Ue%c)jZ$`a8`LDg`q>PWs1p z^M%d1^M%*B`vo0|Y9rdYb^{zHx1M~X)jQUBM6&}Nsw!-1i=xHy;naU%4|aSqPf z1j#~iGgJaLlikLp4FI7MKT!JqGdk&?D0*^h0OwLMqTt%fVvY+i-t~?3&HepzDc=y75)11*u+a!A7971OCN6yX^%+=>7|jS zZLzHp;o*nHyhFz4TQJn_Fl+G*D}Z@)(CBeBkX>Nuo6ux-E7f&G&`8&uUSXivqykNn zK&!lv)a|gu_yNOKzbK%&&4fdb-ZKH+ECDg8lG4SOo!@$B)DI-$gyCJ#tVtqiDUpg$ z56te=6fNa#DXiMb*EHma2nB;lU#RSEAvM=*KR1KImkQJsD>tE{1YNiTLykmp0yvOS z8Ay=WvF+69of)QN*Rq&?8gh>s8bcM%GBT;7~WR?B@e)WSX61ksaNI2qO#{2f@og8AEVd5N*M$*9}5yZ+|>KvA*9~Z|!}v zpbL=QZPRYM{IA`;QpQfT8kg7gSK13tAj|o=c9m+3!8(eZ92~zcEQjtxH{WfesvoA2h{2z|cI zX5$wiMng?Nb$fk=+jp7*;2xuZ7)aA6P8r zhd!slVzEL1E^|`(7j-Ao0+C&wY_WvJ+)icV{$O18^Fe9%&`Q|Fg^S78Ex6Z8u{XDn z+wuLB1d#}jcp&cpkb8>;OlhOeuk~*p^Du9a`fj;(j2ST}8=G&NzFTm4zydyWWwldL zQviuk!I!0F|DkHLrRUe5cmF=AfZqY-({0>2c{`9wR~faA0!H#R@OJXHIf^D>CqHw& zaq0Gv@dH0Bq!1HCi7g(Y6QW+l{&jl&r5WUYcUF=zJ#$o5NI>>p0D7+wfsvN6s@7|% zoqLYpI4rEUQ6v$OgW{o7q`khWL+I+|rOUMI{!(c&PXxwlQ!b0iY3)8j%(zvuU1Vad zR)Ed4tDoZS?~^fP`uOIHaR!ezkOidy_z!~o9MOq~tIy7R1%|I;u~a@Cs@8{e0rO=x zsJ%q{5d@dt?1*ktjo-!;_yP+8{iD7-;0wlb1VNW%^fANlqQ@qQ35Ko`*M}T{#wjH{ z0%>2TnAW>r-|*~a!TghyGrH;yb74I1uA^74372dj&%4SmZM^Ln(Ih zvb7PKhrd-hHlQ-n0qsB+GXU;LipodNPg(FCo;fLouo%vC;Hjd9ys{(Jdh7djnLU2v~{ z-o?_ZEgs(Z#PVkAgKp;Mt59vF7Q?|FixTmeh>TdiI+FOS`uWgg=D`-C3<>ETic@`0Ck zuq;175?2n86Oz9(zEeoXmeJ5rPyDW|s_J^S1`U*1p8Qd2KVb*$v?wbpe|f$a1_U+- z2d6|PnXK;s*2Dn+KD{|+hPW74;1dIe8ygN%9xp$9baAnkS}rBu%JW{&2G`-EU}rTx z(VEfV=@9>HPr=_Tv`g-K-1vs1J+9uygklOVJGYdciEP?to$0NQVe%udJ+Lq|!)g@Y zua~_Q^I0h?7g)qR+1Hp^*oO#}lZ%ANk{4F{nVG}*(ht_3Bfj3C|5%m#PAo@qDN7Yg z1=lYRPZr4hy3=J>XO@W%^yvg?Jfq?sK;_nX+V=K+Aks0CZ7JsVWQI3i&gkBq`V z5=Ne)-$9RsKkYZJHpgrKclKD)?@-$4IY@&HAy6T zxXNmTVTN?%(=((2JZvzk2UY*Hs+Kd#`SRcD4bmjdZGN`+)YTAylNvdSfB?Ua0U)+5 z*Y?tVLZSL%1du7qbt+NeVHWv#BYSNsv8d})5Re0c4-aht)w2AIQ0|?iqN_=~Vr%UA z)3uL(o@ZV%?MRc%Q_R)!Sra)jFleYzy->bn2U{BSjFP=HV3G8>UZK%oja zBNhIdn3N#sy{~sf?VLUgj)nJNi(=jT%NT zTT<98re&n33N|I&DMF$-O}4zz?@go}mbFHf4w4BHna#t3>`;zAew&0*zNc-6&jl?% z$2bq`7?(x1fDT0lh1+9@9D+8bwdgS$kr+PIJ?L!^)meOv(_}QTc5zsi9jbb+JAv4t zuEwm84ZNhAssTG6665=cWViJHbM_v-+#~&Wg!RrVXDJu*aM!8!!zdhD9g&vWO(z|X zVPyUER@p0|3^M*)(+TW2a#wq+@xATN%3K$z@AUQgZhh*Rc-n-`n29|=yRRHHEWTHk z_vQTcFD|r!O+Eyqa-iBa zX2D7%vV3mOFwAA_dfaSsOt}KWV}#9A&hlde&1UJ;D-g=8o3$HaZGvT+$Viqv zYRFw&^%bLzy{%?#XDe{4j_C@I4BmGfOoG&SQ5nEGfyp+de}xmeUIP?Mu@`9!_K>NP z;b<)!vGN-z6Q&F4P-z+#zvd}b=uxMsin!L=F5_2akggi6`c4$59J2yz;ONQggG|8N z1nZkg3#TD9x89|Z#a8t_27K>;G&d^_UZPA2SLXS)xlB(_k8=Hm40&c7z|T+w7t^ok z)_$m!Wkcg#8$Wo;DQUlD7P_6npC+jO$rq99;85ccQ?oWFB3rd;=*Pw!{l@=kjw!>1 zo}RJm89B2LR6|c+1B$3o6p1{0;^^aOLMWt;6g&X-2wHEwf;a++vFxQuLpR0Sy%|o! zMuR6r*Us}A3S9|9=+=A)M4kl3^W}_Q1e7}-cA>9T$v(5woSF7lE&VzK<`>A z4DZ)VE)W&?L@2t~i*%}IZFtoUl6W#w3Uv7{Q?6yFk?}w_V9azF*G9`;coMHCvFBwF z`(qs2Ly7-O(dC`Kr|6?S?@1BCAAa&>qj(2iCAySB&T}=?J`U8KObclDK8`#e1!SWMfAX7id~J=iOx1rB5a52dT7KKx`vecqwC=rNA?54VY0~-f ztyBkh;64Dv5l!9_cGmPwjW+;=WemWf1E=nfAtHdpE8(^kubx0qbAmjgx>NmXV#yiO zvQ}WcFaq`m)Ht9p?ylsx1?yp0>Ut6QRjjPI89S`fWsF&j$N?>#B$W1zCJR-m)H>^m z?%-M$6860<;qNl_C-4`MH@r`VCSI1|&p*Q5nqz`rB0Y~t&Z`Zo&+#LR2)pN~qLa=1 zfvAB4F**HYJ?Y&@^>L4xV45PgdIivow9FNCWBKDQ&RKi_6Sl^uPU*OWSXYUM$@Ya2 z+?f7qm~;l)zrf_un5C5xMF^IFLJl6@caf8=ePTvjg*})eUSBuEni${C2N(eTL+$`= z&`3`@#bI1BNV_7@=iz-vv0M!TLdubwKsV@^wML#1LwDh3iZOkBo0U@&d%=6V*;D&Tf1t`F(=;u`q}#7# zJpxRLxCv+;@-*#aPC7@J6GqfdWWHMmK0*HHKGZWpyvl0S^W?t-K>6Z+CLutYE_;vS z?MZC*5LT;FJ1g$o2ni^gI5=9_0rSh{pu!_Vx1= z9Yu1+xrxxLE{W+SbBEJ*&5^}lPp=G)Z=%o9z+0uM{PCfu!14;elb))^6atdougSL; zw-NZ;=7a!&e;DHGjsl^;l*Mw~JfDPG8o5!tnBL2SADOa{dU_pNgI`{krs{UrR3AR; zRtk1p1th7l4v%Mkz`y&6W*FI6dWkN!GndRUqLcC`Hn{WQWvP8wKg3-6(H}rEU>Br{ z&5TT9E+9X&F-xD;SNbUn(pBK`fZR4GtA{yI(D;saR*7azWY}-A!8!o`P!(iT8Xb7b zbb~`NEf5${K12Dvog)eRJ?qa=%4JA=(#D6VzfJeUA=XK=<+3S%Us0L61M&we)Mk|2 z%3B4BDr^&Z6$co=ST+rjhw|a&TEiV4q>$elgv(JPbt%`Axx>ovwc3K^gb^1{hK_R^ z20{D6EGD6)$LjeJ`>0$tQq$reoQuO{u?pQ|OFu}4E68}3p{vqm!gU#gCnYm>Y9OXm z2=T%4G&#_1Jh!`D2^pYK(cx5ep*$FRI1!x0%7W&rDX;8l19}Jppl&}BbpM$jNjR8L z@Zn0t`k*;qTZHaON_)|Yuh7gyiyUlnYz~J%a(wY)Q-C&*coCxJfN9@eFtnhiiwE<S>x0HkZ_PZoQfgZ)H{R58fZE7({`0mGSVvGyR7@vchwZt|3czxnEsbw908h#ftEG9NwZN;x>QL`Yloj=G4_<$T$b;p*wUh zhXICcyM%=6*UGCwKJv>Qsq2M@?R3W-_rCc!)?HmM=@Nm-!T3KG8s>iX*Bl&6%z z2AnCx%B$aL8?zAiE*?6kxW%j%p*cT)x86Q2QhE|%i^dCL7m);DI}oG|5h!E;m0AT{ z8GG%$%2l#d&G}VU{Cxs`-!tK>tE-NO{bN!Azuk(BAT#lXx{yEsZ_o=}L{eZ+Ih%#4 z(var6!yFe+UG(7nJZJrv-9%#E5HW4s+#P|b1OuQ*9boFPWozYUqftzugQ;Q>o!5$9 zG2Y~_c2ZztV#*hs*d+@}eyx5`eNE_6yNz3_9s3mKnEf=OlXx;L#g}ytRGDA5sVCeZ zHl`i&?#Jk=?NCh0sw>BYthnfZ_O4pwFm}iUgW9e6HmVdlq7%vK0leBlY&d-!qTo*F>fB7O1cL=n*M}#fuNf=Ni$U3i71?8lhX5 zTg`iC9{PT!uKjzm+FzbrOq;RK{&-a5_D3JZVSuE}2Rv9t(J^NI_KXAHNAf%|gWvfO z={iYg2`aIQEVU?6m5oKBYWFqdsZ|sdMr0HZIf;+p3gE+<#zzN9_Smxy7&Q#f?|sa1 z1W9WQADq2hqa`FOW@||O$K{dz*X88}-DJ*p_aOyaskVTQ1?3r|wAavj`x-HqlSd@A z5cLd9_GkCT2iyjtNCof&ib(C(v|DmfQ)F==^5t+nFPvBy}>X~6Av|x zlsVaDF1NzDhfgC>R_}Orxgs5)n*Ng7;K7#Lr5$YW%ruhpfBc9jD9>8cNV^~=ezun( zf4T`8|EzrTz%A<~*gwV$yHvH4FRTDrYjujH#x$VRw6)@tvwJhSJSV01_)D2?d)57r z3jAofPBwtFGP8@mwa%Xt_0Jky=DuI5-a4>KiIt^fLCT9sQ%D)b8;Olg3OM!s%HAF3 zb&q))zhwnq>HSPHI42`>%stV^OYJ}z0^imcWW(0G2KP-QL9aE+s1>e!*FQFu^1T6~ zdoxWOKDId?rYE`iDq^Kj7Tp|3HLZP% zJf^L4W@7#zJC4U!aXpp(s2t=(2ppx=RHSLNzOSBO?F^-`RB3bRMxD}ShoV%2d;}-M zf~^?#u0LWgWpCpc0e|VA2lC&DfKDbVIEq~Uk%Yi!OEy23B!+l>!*(acur$S$(LjIs z4q`KModoHS0z+584xd)du~Th_N&6&2 z^t1tv%moc|#nO)jKELxu1#?Lb0f7;Ww`&BW_JGjM=Y5gsM8#4<60%QL?qP=&wr46T z7h7@^7ssY=+<@V+--J~DxC&%HF1=B^KI)1ZnkX}MoXU46kZ1d(5ViCBWUV#DawwjY zTWBosrTZ-pFky7rrOnOCRHkOOwow%owgHdz`4<=T`9NzI&~eto$r|4b_jZOm*8PC# zf5%3x^K(P0ZpX4kEebWEz zJK~Ey2dz|mj2wXL-=?f#6~ZrW^VEwIO_%Y9x%|r>_SdMc+YcKX`Q~cQppc~= zY~%_a$tuyo!hu-asoH*lB|WVxtfG$% zJ+4;Vbr8%_*Y4%<|DLo&0p?GHgWUEWs`qwyUmA6G9vewc2+2PKds~3@5SYoXt>bx} zzAeC*0KIA+ZJMe^#Whgbt#!J1c>fo&$hKI{k%)FtSEKfymvRBrx$yR7bh<~sU{4-RpXc)73E^$d-_2&hrcJ2+giZwmIYYx1$4$J4p3jAT&=b94YXcCT7B=x z**ou{|39wIGOWt(Y5RgmH%NDPNq0Ar(p}OaCDPp`-7O+5-O?ZplADn3?tYi||M~QO z;y6TV?`zGPIp>_;U~Oz*BZjPA;SlJ_H6HnaO}9>W3z*T00bI#x!7 zrv@Ume%yZSBy0MNPf+iG^d&&i!s$~xuYimb%|H#@Jx0UA=~=monCOz-`f7{RM(y}% zXOq9ppMcG~33&_jX3UkG_Dw^dMIdcbjJVoTvo!zxEyQup6S5Mf~5fh4Zu|UIsjwcf6pM7RsQfb9QsZdG>r}_>Siq z4etZ5ht5rIMW%}s{x8FqVA2mQW(+T86#auTB4$-%Vlb86XkU`Zx8%Tmr#BBT5OnMZ zbsv`xcb)G=J7IWpG4A^NBc9wmaUc85$a>C(rev{SY=4{o<7w} zM}s>qndV&PX4Bfwg*OP}0<9qa!3#397vXP%Gu#E%bC4x?^D z91Bbh8|C#nM%fkFb=oD6{U`Rh>59)DL~wJ?32K!_$~P@v*|f?H;;5-BH~xCEIG0zG z3V3nrgd>UF99ZzkDzgZ%sgTcPV;M0e11dX*$ivwjT>`-4l`^N85wY&GQkB~2FMH3W8KKLQWu2Sz187(BS)AFjqjMg^hZUh#&?bN^OWP`#6dGWg#$I@VA)8z?HU86v^3 zWO-x+OmB+f54j|oq_3j7pY@uu-P)?7Uxs$-L^?(Pe1A=#CA;)2oYf;!gLWjbePNuQ zK0E&PyKbT99%f9OpTYsp36^0C@)ayWfb{z1htpUR>W6l)SNV?MxR;J1apkbb*WEhC zfirw(TgUSzRb$nQG(~G-c(}Lr-Dfp3>xc>H3bP3ULZ|aLKOH-z?(65A+)>w%(M-@# zY1W$U7vTu|)x~Tjv8e*?eiQdjp=h^cz-(nRz{Hq0cux3_A&N`Uf#CtT>0@7}& zP`Ym8Y*tVde5_@!J8fUwyp6{yapmM<5imDA9on*<1Lf{y<{Vz$9f@h=|`i z{4rZl?RSyIL#We7;QjgM(;?1XSisl(@!>HR4LV5^85#L>_H09g;c4@y4v;YRjt;1& zD{`1!m_cvgO^XWWa6^-p_wuHS5Qk=2yE5f!Vi&glw?N zP%Sbb0P&boHwcNohB+!AKn!?$_`p_}Q^7`vp`ps)&d|=eRRujZBD}GU4dPqIA2SSK zyN_x9;EIn|8eZ<--^q-&P%YT!dKE_@=<~5kHQMH@EA1NhU>gCm86@sm2jT1WUU3d4 z92$*CqPTEe-Pi4f276%d1|{nza8iIa*4J}2G=sQ<7VzQ#Kac0y-3~r6ao-oohc$q= zS5`(##KN+@3A-{2lP?x;*0=QZOwYq|x?1FNSZR|3%?wRMaE_E>?pseTyC#mBq99Y$>Qxt8d#K0RaKfJ~k!R&l%t8fj z#(Yy}StDMFtMwvEA58-fJYw;Li6jWaAmUnkKeA`Dc8HFTnYwxXfM>4p@{;R3B}z{< z`Xx|}R;ICZNa=S?7ZPixQ6H&Wim9Z8wbY_?G1r-YR%S#I_^JS&YJQo8tJ}RAQAj(4 z$bnnJ#yogQ&+)6UFHu=1uFjz2bp;3VMj4e*E;;Jg=Iv~P0(GfdE~`28VIH8*^(la= z1i?AJEffjKHA^3k0%76^d2uN3h;wnwKN(g4NvL&lOK3MhV)wVN>yKB4&u0Q^C>!{= z0}Q2>G~fRACuN0y#VXIu(MIVeoe!#5;C-W1?)F3P=@!Gt%=;aoZzZ8`xw-wQEUGD_ z#6a(xW)<*{I1&ASk2!1N5F5L&bdC1kU(ZiXu|4xAY_zw3yMi81ULY^>wKL+cfLZM_ zN!}Jr2FHP?)3Mzx3oP>D7xSMbfHXMUWj@P`1ic2Rl&eptzo33Dzv9jvhcec~p-5hb z6S+0JK7kDPZo*U^2>)!?Vn|-!N;NY5>6PxvuVmzSqU&|i6#(_T-1*Q5h7M?G`<)GN zhrjSf?;kN=%<2tzo`v966aRCcDJ$dCQ&%2T`>h&2AB#LQH`u=u7LGmOhbPCw`~J_7 zHgP5(cWb~D?;~lvGtbSDxLrSIXklf=W^HXmXRI@HeRxde@wyTwNQzmb$vk;n?+NguhflHSk>D13bOOC^Z_9(xXla~xOc(8JsHe0@ec=dJa$ym#3 zrz5G~jfY>9nSi2V^oE$kne6d3OkstPCik3z@#>6{>E)t$!I2NAn z3p>36IS=gWmn-t5Ho7WbCT@MpBQvNppR(1+S4=ZUX{=DDOf%#mc>@8VKPI))OH>WW z7XuGC|C0bai2q4|XMbFX!hlZzM3)PW%Y1IrT+O=l z@^wWMIf67TO+V@V7kX+n`Rk+Q;f{8%&U0-$h$WzQO(rDB7%B_r?#xdX8hK@ceLbx- zw4`^pc1)QSExtpt~`I%oWYI`MWdw#nYu^WGR z!SeFw{Aw@C@r$pi`_#;sYcEx^yyu8DI1OD9N57R?Zm2bpcHR&|-PPp>_mbpV7;z zqCZP&!J2tZI!B|57c}z)Mrm33eTw|sEw%17tv$Q%gdFpMVeN>B{AmePt*zCJKC)g1 z%bktPC@nMM^|~-OCs>NBB|hs^&qK=a4$I_C0wGl5`%QXu3^niY&AG!27&efP$R7F+ z%nf}I99JEdvIVp=qs;L7XY<|E=thiRw_r*#`+zE+K=;?HjvhRO|4Dr{*=e6CF?fC zFY6YMjC1e@C@P3m0%%;=IKLGr<)zG7;No_nP3&0t;Sq3g&&IP$&Q@O%W*tSO#z)Aj z!Or=R{;BxI+NejPr?=@R?UC;UgR2jjJzrK*TApMI({;KJcuI3_!}o_0gI!!CFD}AU z;?N_ttu$}W;UV3Snjlb}6&ZSCoXo2N^m%y~qNZ@CMQ$$g#=|E$^+MGVomCf+Zo`HFJq0ELB7S0cPQftQ_jnUVT(5 z%G7Un7O#H=?|`>p8tu_S@Xg4{@Bi{D)_(`m5VEg!w83Gp<7f`pom0j#8 znYIQCmH+F`@Hwwjl?XpYzkay6=tdf^1?9ey@Og!te>!3NXx}K!c&|YWgeZV)RfcltbgM&8Wj;5&Z+978`+QdP`ua^$Pm|SA2P^aC?x+5xE5jQJz z4WEH1TsQ9kj9>HzI+_7T@u?#P>u|I6QtL&LJA~1j)q&hh%IY_|j776ex``yj)HhYW zlG`zJ&aki}PwQy1Jej@2!x}GpB}~t8q?Cjx=7nO_b4IkM5V_%#D7-1md&l$89iZ^fIZWOErHWC{o$B}!Gbk^PFBP0U zoFKcF+vq+%o2y@cWoYM8N7Y1Y08=HwLOGEyN^4({OXf2K+8mN@=g(`~? z4MM>d{K|O!9%F4nUs}=*m;O8H)c>7yJY{|U?EVIOAUFDTcLl*&H$v(l!r6HeC0Oz2 zf@-DMd#;g+{G)?|@F_`Y@80y+GPDT9ysXFs-+Y@$5T&SbRkSgN-|0)0Jy~jA2)m7M z(k=8kMtZzR4L?9hnt&09f@Y>Js8YP&C0FzEAfMhF71rMnz)>9kd1~}RcxCjI;k1v6 z2vu`9ONF?UZ*uN;hP!FxNBr@Gq}&wBB(r$XLrw-`5zWe|Npxcqp@2~yG0+96u21&{jht#TEdLYs{dL~GyI4!`_0I|W z<=8}Nfl?|b9^?%HS~f?$xy zky`{szr2`mRJBEVT*Cic${ZQz&Z#ac(BRVhE*<0qq|OzejNIpxep*tj<&KCJFG6Bl zCQ*unDe;ff+Rexgj;!v*x!|!g2d_IHci<9VG&&|wF7f)eRS?(FDM%mrT{ZJ+k)JVt z)WgiQviV`ucoVC3B8k1uXRbqE_80UtoDip}m~Ce=kNms!Rr64jz?{Hf5#=dt(#LDU zr}fuxfqg3T%{H*3P>ZL9{hjW9%=zym>v4R1hXRzOljvQRdxN>Y2Ky=cxKGNZgw+Dt zDV#@MF&{Hx-|{1>I?FOqRCB6n^UDA2kKf-Tul2%x-|SI~c15mQFaNZ}mx0SdW^=Vk z)UGlwB=rdnEpgfFRhc#ng#8H8Skp9_=Xnf0sw@&z%%?9NJSCg&99}*ArWc7d(f0}^ zYsg^m(}D(vpH_=~_C~W#Ab>CXUFz+h_$cy^-m2^up#u@m#>-hRw5t* zUd>uDu5%b{4IC^G?8J4qi>giRa4Hf{+YG|)nMMpkw-i)bgB@0BQT41k1MIla#gLNX z&{3z(MUf^j#HHkHO(0Tyo^-Jk_t#>cJeP-ou4s#+1?}KUq0;tvM`k|~w93XEq5U8- zvT;gJrupzDZ8aH0JQF(}8c`nb%5|tiS2H1j0)z-FLy(bk$kS-!05DPSB+eVr31Vnq z&4uFx1fxHIvNoXdU`#0nV&5I2)7|GuL`?3gHnWe7SafqT0I5exA5A~?&YY6Z4@6yC zV#*#DDRH^y{Nf2kZ(27&H4av!rO~=w!ta^M)W9)>YuMDH`9LPc!uMU_Ex#cguaLJn zCxW$S8J$8B2Y;+J=EWlLRN$H8{U!e%E(N^fkDc#?Yj$M4!_A@fIHYT;T-Y?m^RwbF z<-}Em<99nP`&;GT8F+f2k}1WiAC!C$-p{o=Lg@;_Al(n0pQu!(%RfYCC=lZG(~1Yl z5H_2E#>CTv6JcBdYbe*%xt*(Z;g1cTUbn8V14&}&S@s0MIxkJESpgl$CA-kj2502nukXLf?N0K2<^21;ROv$2P#$=9f94`mG z6AqQltafdkQkB#$n`-vTJiRRG&Giel;Z(utU5+hen4J$HDwTMUC0z#^QsIi|0IXojzqUg^u&iGHro=(1N za3mN1Oc2wF#N|oQbNlWiy7`x1jCspMy!h4A#(Xq_Jkb@Bg17me<^=tTCH3F1f;38Cbt$3T89tBCQ*|C*nuHITPI_vzC}(Pg>PQ z6u_$#sgd02;|%}oXeG1-uckNS|DIM5HjOba9Vvdyz~gR5;H1VQCV`-xgl@%Dw?WQ< zAH3mkonNWy8wTWZCrj8xVYP$$NX%{JEruOH{*KhNJkZC+_AJ-yiX{@tUVM?4}rX0aJ3CbeDN7F9)3 zMTN^xfl8iJR-?X7R}=$VQ~H1qX?VFJVpCd_K0%7q1+@WtL45v56$M5Z+^VTZN0I#J zwJ?~d+T|ZE%h|2A8^>9Bms&6H?lv6%9umoQySQ-Q4uw;=wkqwcza==yEpj=d$hMse z-#*^p%-GdVMAnei-Gk_wm8Bi#$eo|G#WZ@c9v=&7`?Sydv>S7`;PsRC>wYHjH@! zuC3G6J~NOe`mP8Y@fP@c&v=Zw8tiHXIgoqi*Z;4x8(Je*w<^udT#zwpj?6CyZ+&xV zeDlHS;l72ot?}3I7O!;?L&I-A+eF#5xYa+Df*ax~LhW!`9r3(?NmX0&GfVe~$f|Hl zG0wkK;L$mFeyedU`|yBjc>^ zeEd?t8f)i=F&~aS>|}Y;WO)E8YEO#vw1Y^?$8+qJ&)U?d=j2dpVx&-`tHlpnIuXI4 z-1`1HToQCHw|XG1d(T}}xk9*TpPOtGqu2PY$@LCaK>^tHtmTU-(iI5?xGu&)CegtE zUq>hI??}W?S-C57ry)of9+->XJ`{=QcAD#D= zeo;&zs^N*N0nK9U_v9ngi;W#O$RZDrk>r^v-&nRE+Ni^+4<{h!hP<0vNq4PO=F-ql0 z(_h2Mc0OX3Y8iHu5cF1ReC6BO_Atd;WsgyTa?SX@rMFv5$mRme?uW6*O8H3e9hKs` zrW=;RfjmV1{o(+oX@pWV4uMI~r|IB3;@upf`KK@ppbR!c$)+YYZ@-5Mbu2_@i>NsUppp7-afNy+LJhx&~F;=WF*W|rLGgrBsU)7m<(teML zg(a|e!no1QGSx;4-t+mX|4zag7ho0K_@tzyq#LD`XjZ5?a!$wxpbtUJ$N}ud9AE>m z&)=NiWi80HbUmfx19l_*O%mw4^trUdEgIR=RB*{#0}|TJ$73@+?jVVv&7TW04XYf{ zwDg9${hi(+Vxmzv7t+pN{Yu~v7?@Lxol&-Gm-Z4G2$y$=v z5RriR_Fv(0Z--%`#C$Z=!IgYH;I@e4x@B>Fp(iuw@q$U5JXVG{koohbDgXA zoLTbY8w}20U#-aF>4H^cUzt#5Ar~R;y5c9$i}NF;lMJ5tuj94U5h4m;EC|mQVuuA z9NW2LRi-UGd_v2)O#m+F(N2-&uBsTq9Een-?`>dqSZ!A*Ti%{Mda$xj7=KHLgEZtL zYQ3(F#YmE7v2ra?UjC=a`2rP})!?INv9zBbYpZ(B454(Q8XwW48jbHMd!N+5=fRo~V+_E*CEtL@2+1?6!?rz3 zqe3tXhP5M9qjoic7P_Qpd3lxOo>%Lm?Ep?ShC2ZhnmymLlKgi24--41?X&iUulgEf zntr$$n@=^z+y^)m_!gJQQ@ZcCghrKp&(-zkw&GrHXbXj4ZWB3>ET!c$6>5wi&x zSy(pouN6LcZp0KKYu?w`-wg__s>!R-hjny-9^tVR(op(4t@K>S>W?=tfG;OU9y;60 zPF2r!kV(IP1*=uLvK|#Rce_4?!ti9V;{C+ut`w_!%)Hi&+6}ZsP!GTPF9Zwr|Cawp z)A$FDNoLe)2E0O#jICN zLRt$?-w+n9T*>sm=H!rFwi7e{L79%B;r3GV#pWlSe;v}$8T40TcvB9I%_2Uz2RsfF zdMqxx6JqCgk2IvsXByK4N#b0Y!7foMj>fhz)G*>fBRe(j$D%k$nLb5SJ*ixi^2xL5 zNOfabGR#$Ed+uw47Bz70fB&WPoWUQM{4D~fkHq1i)}9`K%W-^P?GSzsSUQg&VFpZO`X6i2p7yX9U9mBkSumE`Wq948eRk(Z&hVFzJ!5jn;P;J?S zgoMBVKL&?0dEFdy?NkITH1h#N2nzbV?lTeh2S z_D~3UIpTetv|mNVc$pk;N@Fn-H7gRttE?E%zKILgi-6I<|?Y>4;xe66{2D zq0JdhEBhU99eq+aU>0+I)+-!BDq0PewB%EezHPuTAuQll8?X|?Y_WYqaZJN91j`vB z+5D#W7gG3IY95dEXly1dZBWCsu@_l3ip%J~m@SevQ$(av1Ivl?%f^4@=~hQ+JOn+D zt43|9$u|hlwZ6(1mulR5UL|YYUWmNBqv;?;_#_yXBT{`fyb-;V0s z4)~Qe6sO9#r}w0)G9R6V6sIAU{Ox<3YSas{43n73-(JZHM)q1e&u=_jo02akZANUh zsPm&a6)DqPqej#1LoB&m6nNz0EqR#`0FK#5GJpX}WG&8g4h^n>8zZ5Bm6xr$)s;j5MGE(WOKxDl6Akv*l`} zjE|cYtI^TZ<3wuo50uW>{2>vsw6%?bLnHawkfTw78zmLl*DbeNf%O(f*nX~f?f?S@ ziX&F}OKL1U%r_IYQjOc`IN@&RpV2A9LtuLZJ+&D6gcUdVSsdKL(&!yxNU!SDKRcC6T~-|<>F8e*=6%uxa_X= z2QQ>*6c0iL%fxM7H>bi+M0bbi=)L05uqhlh7g8KrRbM^*5Ny4f5bWz6X{`eS53eH7 z2!r(?Fmc>_%X;6u9^M5mnwf9B+Ve`|z$YvWXFumF@1}CM2z=bcKPPRAyBP43{o+n= zFv8nC)z$p%=>%E#hYX3N@FgL96>9ry$&*(zwql(Ti|uF+H{>>j1>E9&@KkJRj`?3@ zrSK80i^+JP-oHtpFF0H)x?f`Hx^?@r3yrKS=HQB+mg{|>r!@UO(ihFojLuENr!q;N z1b^dzv=&?bhdIWj-Xd2Xr`mdZF*ScSDv!gGxtCYi)00mDow)qa$Otm%%GZ7@Nz2Tn z6iK4J@*+qsNh+8-n6zsUr9bBji_Y%9Pl@sgA+Mgc{;5MKU~fVY2wK!VY}O000l&aR zQB8}cg_mvWKs`bIB8!)o8$kWM=T;CtiJw|){${;cTJ+i#JRG>6bClaBjqQE1Umiyt z)6%}5?uguDC@7qKdRpW{3^CzISDgB-(6zY}G=zPh%P}T2Jk~6+rIE(`NYkzBtxW8(*BN_PFoDGg+MU z(P}kF3`w*&9+5&6y5?1KO-Qu{2i!7_?dVV-ZnqLRnLB>;!1?x7QQs>1A4j zOk-x7pJ-dE7H?$wFjQ;bpEgClK*rBbyhG2Sk&&UvBZ9lX(oZ#GruPlc&s9-yq$jQ% zsmsX8={x>qt(t0ei@NrE6!1M_PdE@mCo8~HN3;{Ai%=ogEERQMLmUeu{rXfJC!5U| z#HA)V-+(&Kb@Y%2YliuVTHq1>`5HZknG#j&uhW~iw}TThk|Ye*M6dw{+vkHM@F{u-DUY= z%7tB3x%<#|o$4`l0+Q)!dFxU4Uzl^agNuK(5p@r}5*}&uD zj$fah4eT^Kn;#l+S?rr#@dVP}3BEDx>f@vi)97j60?5fCDZm=rpG>e@c$@?*jVDV3 z9MsvCL7HW82mPOYC98JUyoBG=yxwIo00E&S26ci3lPZ0dLI%K zbNlcNqgGl5zr=pXev2J90x}V;%>TSlE<2VO;wlw0-!=M;?upgp0e^W^Gt;tGto6tg z50-woK!ZV*=`H^69ixo5VB#^7!ds+tH+CaUtwxsLe)_=8x|JnH8jGHqvKX@`#N-o@ zEsNthzCn%vy~#;{xXm|Lg8{h7*uduydwN)x8+|+DAbZB?II)RR41nugXOOB{D}@&- zOAjJRbdrqIPaQkR^S0BSM;01m^h&{ju^|Rl3=RB(906OR=J~(ulJ5g+@ zx<&gh%Oq;@35tXZa1yU^Q^c$DK<)o!pZ zooMA1X7v$`GB!drmO~k}oK(HInVCMj@2Ddm6t|0l9QsA=8J5HnV*1LXeg*7!)}j3FuvR79Yh*-g^CuxqPALi#zDG2J8(sdQXEdotygt6Xz1KNfgqIc*^~YEbo8nk@9pn!o%JuaPI||mDtjuf+ zZ@Z-Qbo{a0+@6M`6DOHYA##}hyiZFP_mZlYUqr@@g|fcVnXBoW!1o$I>JllmEDN`K zL2V_FkByF!v3a^rP;bnampedz^{8ZJQ)3`Q&QBe(%J`N|!7n<;spQoKfU|xtXfK0+ z9`@v$JNXH~Fmcl}_}^(;+}kwkW9AsPeGa%uS)t4wuC1>RIbb1yyf391Szd;GG&2jD znc)Hk#*}1=R2S{Gw!!X4!FTVb&53vB!))oPJ4h$28oq1V-gXRtPlT8Tv_E|Wv}_Pq z5xV0UQ&|Bphv*{>tuqmp2s|&Z;3fd13;I3=2lYsN;tRWQ*@;8d?;y!z%$wdj-yBj0 z)*q~7L{*}V1_QtqIXED6Z80cd+w2ZO((iPSsX0@f+Ph@z-VnQLK!-PJn>sk8xH4o1Z^e-~Z*2QH``sb6EVBSE z?!!%L4O5f?s4(0OfZ!3ESg3~ou}+^R`+espse0%fVxsDX24H$Mc6CiU9}GvGSQTGe zd3Wz|jOj4T))W3p%AbN6*^azg5i8;6d+vBm#DcW%ssm3at**Wgd@w#tJ)#6Ov%7fB zq~87)&zPE}Nrz>qr|*TRsS_YwRl@lfRWH&fbDg0Mq!MY8y|Tq@#T4)OrJo(2zdnvX zL)Yr_?=1^|C_2G7KACFw$($8=LR$IFugcVQK;Cjh75>f)nYy}2G>v;|EWZ67HKg;& z_Aum4d5v?lHwk5?oUYKpT+TNi8AOb0jCTG*R!aBdg8hSu`QYlH$Ok#Xn|X;rbn|c% zZ8}Dj-?IHxgLqt4l|{h_J=1LWEQ;R#1g)^?g56_5$xw_z98<>H_ikm@izj(K7d!!M zv2YOa(jE2BUtM17-BdRSU86zFfAT%Dy~0jOsB=%{xRZz0=4JROl9A66>*sfNZhO0b z9p|unS8pVg`8CGy>F{26J`R1z6So*ll#|0)3&h+#-nvc{E7MD14}fh7(+-Uh8@$%m z%AaBfE(8O~{$6Jbc%S`+`dIQUO+aJ-B$VvQ@>?&QqPWmgd)VpaN_h8mx=N3~{3;-_ z-7Zo@1G4n&%!wKdAtrcqrSOID;}_v(eTSF4fLbIW9|BF7sk|`%{p{}Ja9sxT*n1@~ zwq6r#c=^LR!#(2>?bUyXiuRjSBCRjq?v@B?+L=$<->6i>K=J!qNz@lDA3wismC0DnmF6#8pd_yN)=F*PI7qWl_X;X7_@+aJ&WJ8knDTg;l%nhvx@aP^ zTh9ty31UdJq`A4Il=RYr@9F~q)Uq)fp3Ux}C`Io0J0YPULd2Sf5Zw7TPpov;Z3V|e z=HYH|ecnIZ_49PZCSgJvtQ>59RERX~3A^ocmW*eaeEAaEeCNqTAJMlCPp_iuvONNz zqD`_gUW5Q#8yy=xF*Abz1O25V{@-aTl!@bDXYbmZ{wPa>1rV7vZFSv`-GVdn$?1F6 z?{gjU+S{|8c(GlDtC(ur+Pe4m8Nl>YfU)-@O{2pyxJf5x-opQm-NMF(BOtc0JHP|;2pSxoxhgC+LDj9KbGo$v^Lzw} z`p0dIN@WFv&Vi{ZOkmKHr04>}BYYmmL?|dIb@lb^+zsg+D=WqZYQWY9$e`*a%8BD! z+5oW)&SGfj7tAwWU0WO+9Ntfx>VT6aR$7~XWYN;r(IL-e&8z!IjAzuU{5rfP3h! zSjz9Ps%52r%QEV#kRpIDcEUm^$mGVr$M2I*JG}S^y;V3nO9%3(<~USUez(y5M`&@` zx>uwzvV9RKap$|I`jxy+v%yIcw}hF3Y#L>EQz<} zncRA-!3Q_YV{%7eYLA$Z3Hw28--gUT@1*I*CPYP;KPx~*NK!3a7V$`WVhyk83)xK2 z`>j2yzUyNo~gvo+2rBe&4dR5d0Yl=_+115b*&-1i*-LK7d9O+o zCQzVHT!sE6+5ECpoa-{6Q*~YS;QQ>^c$Kd}Qhf;Jvv>3T@Sw&`EVUjT8q)B34KIdl z7wr6TlG8UdT(KI|cFdX3bsT{T5hqtGrHWCCadmT>1Z+n8mro}ab8)H^7(G9!K2%{6 zgv|^bOoP1%gj*c34nEeJKifF3Gsa#oY!{46CxmYV6ESRIYO$;u zyKi%syf^5*5NzSsi|C{1{BvW^hKC$#L?kWB13sc~%F}y~m*`eZt*neyJ?}TpH@obF zDm`eK80Y22#=6hKNgOQq5q#Ga^1WYqc%18eCInQV8hap|4ID4C{(TTGD=T}vY`@`k zeuTL~x%xNTK>KnQ#{=VPM1S5an3$MIB~?_D zQDx=m*z*-<`rWjDUU6~AXTjK{Kp-sB&^S2nO>MZRY(se(Dx&UOdrQ{c4S1J z*+riAytGrKm# zu&qbW-&=^U^crI^;`%^K6iA&ney6Wvb9v?T^cY!>S4PK(A3%V+XqOkE#r_#YhM&{B#r8bEO%St{SBjjR%$D=PAVf zlRc%*aTnj^)Er&ZHqpBuvrH;$*&ZtuLPxRw4mvmqvcU}v+}ts-Kiv-SAdQYCt*r;C z$Gx<{WS9uxU3M}ctPrfzq^n5qzU#R0$V|Nb*0HeIWY*Nk0hqT!JhTnw^>N>?XfpGD#v2f+zrAsn3IH6pPnxIO3$PK%eR>$!;)I4!7#nNtfcIL2B>r9wfLqryx;^9 z3HWA#8AlEwAqhI{g5qN8>S5qoN*n^(>A{?%3KKSIXN}eJCs;*`5zn!U3_LhGUa{x_*3C`F^bGIn%I)8c$H&!|T&Cq@5C(3s^)ueu+S)8Wmrz2U{!$GF@9THC`f~pAWmU>eN2TJP$Kv&EiGkB)B(kJYGy``38yf>BPSsN z%ynAw`aZ${CLXqeh2VJ4&!d>N^QrSG>Bg7!b&8x5j3{Ym1Ij#+xbKiCjrT^P%8F|m zPrnw?Lg1xp4l)yJHqCIUKd{KGEqNl+D!*CS5vSw~D9($Qr44?oOlIahjqs3Em>l^$W#bY()-+=R&G?6i|^tjeuZIhS(1THW`vq9Sndi!3Cxs|H-}WqM{%A2+c17*Vjh|X>%e>FcM`l^q+A)W$Y^Ag=U6Hxej7+F*x8w zD@M;p?#;wFqp2enYgNX9IG@S9xmgV6*ngv8Pkp?&;5^6NIaQ2I_P;pxjTAxA0zt`_*6%-Y!sv&(3PL zwD9j8?;~zIfsgx#RN3#JM#6iIU;_L}z;{BA2#!x7OC7Iu@=A~tl;%9I4LMXR9l7mg z?x&?ekm)w(pf{b|4fPR#W`ZK0BTtr(SL}BtB2++R8ZIs_4lrP~+deNQRD3_`bg_-h zWwgoU+r?J+Du@5P(b- zB@r4dfk=+)abo%M>;r)9lYi#JlfDiO(Ss5X4vlzyzGg$R+vMM9@b&S6grg(Ro(2K= z-}y7F^73-0?L!^mhewz7GrX$yb3{(0VEw8=l$L(t0h5OY`$yK7I}xzWOpXp)ywo_i zzOj+AX!Ei8;_>f;2$*R*t*;_(Vnq}B?5mPj{e1GNcw}h0QKtlVR}El)M_|!5 z`FJG&dt$gO>Qt^*V){o7>@PXYT8&6H1(@)nxc@C-}Q9u?lp@Q;@l!4SsOO z!0fY}gv4tBce{^PPUv%PySux;oDIMkyWQQ0I}^%PE0wI*ML~qOIq@@D`+-pE33iL!l#(FNt$y8QDAOj9xEO(hzS`Z?VTE}P0Z;`->|OfM$w?3-GBqU7j|#umPG>6_+SCoP-RX^x4*{1OQ9`DqCQd?2U=qpg z+tXqAK)kmBqE=Ayiur!1IFPLDbqFt{#o>>?j^|qc-r}fraTysO2ixv~%3bG* zOG^_bCsjda(6=JQIyJi}Pk}*;jc6i(s%dX{kUB&RCG?&Nr{A4Pb8a>*BfYr2_)g)? zrFczmav4w4C;KdIL3tT3q%%omdYFKG0a^NL*LXPAj(CIBKN%Qt25PpehPb zNOkzj%ROn;`+pag@&7Kad^h8@%6jOEnxc>c{?7Ox+7(=>tVY{M9xEnm*Y>)4x>okq z`Nho$);ikt0YS3_b8hsh0PD&Q6c%-L^?yXymKLTxSN>fa^)4qS%m`44{hLc2RZ^l# zlp`CYKRG@&ecT3ZJiaKxPkV>Ed7V|MVBI51R|iPQCY1`As><1TyrPq5J_xRw^`t}@ zPk@`Kdtw3|Jbon=6)~8=`E~GlWqCgDtxv9XaC@UXPc~N4ZfoakC@m5{0>0l;k~|N=Z=egMOI8jqFn7c zO$XFU1yG_1`zG?N-XnY*%h|fWB4lD^t+k$}qwMJcfgnMV2H-#$ulz5oj0HfU>Ska% zNw?W&`=(%M9 zh{x6T!>(Auj#eo0YpDuJ=VhOhG5_$l5?3J1SRlk9oAPi`Y?|FKf7kI;XP}IfDmO)- ze!2?LcGKz3-%Y53uZ}*P&7EslZqwxmC~vJ>{JA33s5I>BWJgtCELSc;tVl?SB91iW zX+$U4rQ{Hlb#+afFcxulMB_;2=x**ht(`zjf}4SEsS6w%FPL*6k5bUyA}Xl%9~bt30=Fi4dMiy+ z34-@ypr=(z{aS*W0IF`#RLg8U3%BrdF?ux%jNjUqQ$c;=x>>;FI$H}P{RE=w{ytcl z#5p~=g5jFs;WjxprvTPKm1-akxCQ!L!`Cp$Q4tjs7A6OTNP**V`*?wc9U6N216^4% zT>7|4kiM8cMSf(Q+3DzBsnUp)Hg}wTesy$Eg|*b2sL93Kwh^PN(Jd@+QEjeXt^}*D zo`*wlYPh?b0t@S%WFbaI2BDJy+(6A}Ry_E<1-tP6r(%@vXwVzfmM23)+^fs|ItNSZ zw}IUEcsuYSZ@{gfrG=ZW2n*@BvDASF1i0XCa{U1@+fk5Gfl~#ZO!O9hReAeO=dhjt zS;)d<#KzK{ELw;-czmW8r^Kl+X|NHe|NN0PQ>Q#O_)uBu8mUxRI5INw>G2kUVe34U zw=>6wIykSkHptO;=fdWb4c43_G_HD!l=$<*+l?xEW zu<`Q;R$>2x*XR0vNg{px8wS1_s0LM4ajP%ws}`#rbGwJTpTn6u=LZj39+Xyi{G8{0 zs?Y^*@b;RjG7X!8?OTkXQTV>Z%FeFbS~277EVJ$98O{!jTRQq2=tW0Irv*%1gsc7a zy8R)aj+k>QYGa3DVuWs8PAkYA`N8PsmS!tiTBB@G{*4Sh(J%Ep_-&Z-Z_?|X=P2tB zhJ6lp-hvRT+mL)jDMUw~U;C?%LcS(YsSFnRXT?-S_DfEf9-p!Dg}j{MV4VmE(7#?JAy-!Dl0#VwXxDJ&Cye&`?g#`o*aJJh zOn+g3)3g7Oc2JiS?xM^su+Bi$yApHxAak8z%>L$e=L^%YKo_P9x%8PpWY%yZEO~`g z_y1`6%BZN?wrwS32F$zll`a8kq`OmEy33)5?)WaA`~B8J zmp{aqeeN@lkf2V#AvJ7V`IPBK)Uf-;@h5tk4a$o^y%Db3J+1uuD{^koi@~0joCfp! z3KD_79B0`Q!bCddkQ4AZhmb0AtHj3x)h&f@K(gc{X=rb*KEB!GVsvat5A=EKeCNU8 zYdMmDBgzL<kDdLgVqt z1Me~(+a+-^u}(x3>}=nR$FC6I^cCqz72 zUmCt!*G_GF_b&YGf*b?EpUk`Y2zNJHV)|s|x2DyN_bUHJurxzFXj{)cKqzXkDVM1E zy{*x3_cBn@zS3gv1#=cqKakDqFw5|w)Nr3Yf44ZRC6=cQ)a&g5vbO!tpZBBh4z9?~ znw1AK?J^627oFbY9_-&9$poguB7Y#e-xQx{6so)nmd(SfG4*q7Z^O6pDs&x=>C2+bj`jYv zb?>*=J`Mm8ECmJSmMQvsa0qH-q){yo zov~6EV(IT^oeq&xej0i&MJZnlpuIaZKSbr|zL8-B_xh2r3ZaJ1)f!OdCD|TW zCTLMnp{7q8Gayw}RUMv{QGo$rVtHChU!UsT;v(q3b$YMz=Bs=N*aow+gtSwp3&HWa z55_{y|K;m@MoC%{3FgMm=?`C9Aj!ou{Zb3!Q13*zkExfNXqn?+W& z2wGS{cl$ylw!f<&R7#3V4p@&gJICkcy}_gs>fDj_d#QabL!TXO+6vmWfYrg*{|yv? z>7ouvo%`TDSyZX^n^t|N2z~40NDc@umPF=6S>V|KR&-a9yjT-KHPlz!bz)4eXOAr zNa)hwL<`$JG10`Gb^;73R*6l@r*}(d$UIl=mYXMTKtvn}asYk!C65O$A%0KSb*E{r z+$m(MWh^v2(0EZ$>{rVRMYgb7vZM?h_VBjK2&5UltnC3CsU%YzRH=fZL1p!1uW~zG zhxu_A@0l4Xt=%?(htjWW9Hlv6gS^Ob@UJgc!3}5LDaI*RmL*o!>VX;H$cK6JLdV9c+vYU=8ymQg{>M$y|5s@ zMYc>`?}8<-z^kT9NPMsZ&oP-Q{R`UX&VOT>8>FhDUl30s|rO+V}vS@@+M- zfZTxAyJX2LQUc=C!zMk3sk9r=!ChhjKTmUN%4p>0IMsreFHBp&ruNLqLb;!BwgDq8 zZSnRrjgI{4mN;pjE>Ds(Ln1B`kuzdr4$U;!@tgXd! zAdf~a?CoztE9&7vmKAf8IAy=H!Hh|HP2V>)^+R264#3qotk^C*qrc?&!*8&3Ltr<6 z`)hBxre^nBUtfxwR5hX%Hf#?FsXlNtVEp2r%WAo7ok=kz?Gt8|Y&36G1 z&i21O=OC-|k@q+sH2;Cn`1`4ru&YD-iZwUpYr4T!c&5gBUUvk`YWYmp|6Bm92v)Ob zE}@aOKp$bR{^W5_1*~YEBq*!?di2K(g2vkMIlh>`XK%iZYWDoVXXd3I?(xj0;XEC_ z1b=>ZW;NfC*smQ=F68+QO2d?`p*{GxGy-ER@9_j)7*dwvmfy|zp;gW;iyi}t9xM_Blsg+UKttm45Eb88$g9;cCUI#z;0JN0u&7 z1y@N+{rTmNv70VKQScgdvR%N+X)`*WL3sMNTNR zPFv#WU1VcN?&Wj_{9AjkxNXFG$*AMR=h-!eJ8OqPFi<{)hDIL!lMML1`ua=0AI)Vl z=0E1DnOASz?lBhND-G=5t)BVKlz;ZYMcw;LG2V}4-j3eLGX|u4wF>Lhvi~t<+Ute{ zU*iuAIf2d-H&VRi6^t2{naVVwKTr}AQyKSLEuqqrLNt%n_-8XD*OVFQj% zZ}1|6hxi{m0fkrp-4jSJz7GBP{#_FYTd8RMNO3#rUhHaJbC2>q=l8i%e?XqE0c`>O z+R^i;x)7Wh(UM~2QdP=^sL#~{z!DI^y+QvT0357w!@916y|!#itC0&dtP`l=2 zX`LOugZnw3y9f-zHAba!lyqQv?WSTPWzT2kus-mVkPUk3uiO# z&l;QLM5cGodUlW9Ma0D3%`dzLLu-Jk%&&B*LRBMgL%$Ok$E((I-+jKoPQ&c6zIU3Z z!7!AdXa&?jDQOMg;^(u-q+~Rf2n}ajFDR>~m_~Z_wQ@bzm^O2$R<9^YgBaRm@=*6@ zBuu6cL_~N6(=LS)EqVKVJOkIVqM0dgkQA5#4`UGm%L{O!L7a8(yt;ZMV{wdG>%gwQ ztVBuBC23)`b3<52`f35$q#HfSViZcNXpUg1!1|rO$&~A;*&}RkF<^coGC~|XO3pf8 z_`t>VmEdbgNjodu@u1y}fYCLv`vLv+xrMkPX+p>-%hvHYTEYks{7+YdSbSC6m$5K4 z^To)|v%#Nd0sqi0$Dm#`zg~mGhzphtc5h7!y0@ip@53UpH4^VE$Y^EFO~A3Vy~6K~ z54J@x&TS+S`ap@aOD$$Q<0eF7d!bAQi&dkSRW-g}kEyR>o}g#KRP zgTwCBOR(TWt!E!IKh5IpzVh_b5$f&eKmZ0?V4x^>vO-Twqwu9BjRbSY_wQ+&@d`p& z`T5~Q&ihTa?_`;Qu!M3Uuqn%{|K8p%3RcaBfld`fey*V6a4{_|DS2uz&qFia{Gyj!YqI&PUXSIwk zlw^G)407ReI!&%&VAA@s6|Vpyyv%F=NoS{+2BX+zeRs-tx`%E1uj*wg=Y!IP z_MVaROOjRj8HXav#)IFc@;DPyYMIhn#m~;IRjVskKYi2i|FI+bc`o zRvDpT_KFEh>7|I&_E*5BJMqmzIEa zzDJa}c6>b8O#s9)B%~9IVAP?We1eM$$ZIIEBm!5))oGu*X<~9>5lCpak;!jOKsl;+ zJ7Fwqxjy#V9o1TA4T2%NZ7V~x=CuG|oi=UQN>FODV`SPP4!$2$s`={%ZTW&~=Jha9 zx`)sGRT`&D9teh_h174EMMZeFnGY>a8|ZFe3#*~4i`-Uey`W`wwRky@uUxoRME!yP zyX-iaumo{XO2CFzw)!jC7x)e~762^(dV@XKiYE~gfgaDC{!6m2p5bTrA4Sup0ErQ~ zE6{Y*!)sw_*;#bY3uM*0fc|S4SU9|T^-9E6fn(PJSGn(pG%<0lt!iQ!JZJ8STeHW# zXeaZ$^XI8En%sm1y{4gA2N<989-nRV8QwX3x!2b7X5MP93Y9t1_r6Iv?FYldkc8}%3cW$+h*f{^p|t2@PR+Cg*9Jwz#j=>KJHil9zg$b(4oJ_&X$fI^**-vTbkAvY&HbKSoJ|*bH9*y1QsDlULz;-w&J7z4 z8?)nUwsG2M6WL-D@}i)>JhupwU(JHnUTE=bLyE&FSQyPB(T$-H*^p7bxfsc}>e?Z( z^vzGtka`7<@XtC=LU2Z(gHS`Kk4FW4<<`N$&%(k-$=dr>s(byOo*vLuu|9u(2JXs0 z`Lu=&*fiHQ*YyDxB7Q*rQ!mv6$C9A*1Dj_kD20On8(Iz`t>s3$wI7AbyYFcI#kbTS zfE}T*3k5*%z+(?|yU0W_5{O0-%w7&z*xn(Ua(XFkm>DR(UusPKE+>XI!=!6}(B|dH^ z?pyS9rkjgqsEHFaILqaetE1rJg7PXVct;u$zhL&Kzehs5*8#>P?PUrt9vZUIDKG}% zeZhEnxgMa?twH+_;aR1&~bf#^J*rt?_>Bd0kGaKQhah3DN#=uqo>6D+p39Z&eai zD><5(y+F|uZW|atqoNY*izHhI^VN7EH}JLR=Kf1ZCDn39Cpq1c!W{IZ1fMDBP>{Ur zE9{E;4HOyB+$+*Yr(W_|Ta)3SMBA)$&s``DvL+~`WxJj-B?ci2`tLcg#vJsFlV^AU@ITZoov;A?j%+$(5fkOObAn&NvX zT`|nDAQRs^%eS=>dUngel3c3zojBidpA@_sN}Fiur6g`>esKu;tR^fHRuivQ{k)+s zDFUyr?P?@spZ#j7Ep&-@b88mZMBsF%{lvWeYIplbLuF-0=@ zr)UDgwzLJkz$;EQ1aX7@D6$Y~G@}n&;$#BKST?vuqWS#&YL3}B&?D+;oo@~!Ac%Dr zc!N244x&RMHF#$rf+25{>(BZG{R*8P?;QcFBpdu`1YBU56%sE^AKJSPfGp#4b6_7z z#OJn#q+Y6%r^?PH$Sn=lq7~-&y!b{&YlOht`QHoM)}a*J7Kz7YWOL-ffz9=eyQZxJ z<$PsOPmd%hn3sFMN5J7??az0Ih^VNT_w-|0@f`TTsTKp?{2+vfhX;Ti4i0!;US1kW zxjKb^E9=j^)KpyPa@z`>#2?;Qs4ZJ+=D{_qz#PN%=#V}F{(Zz0BsBPFcwfX+e|?;q zn&NZ5MS4{58v*Bvn+v!Z5L8v{Ykq+)Cre@y{q|fE#hF@U9$Y#EN7fHl=^k+$vi0wQ zN|j=P!8~C8q>Ts(_cX%q6F?>%o1J~E?ET`ndH9=Of&gJi=yr=v=wZ)c$#p$t4;&5M z8ydH_%=7CDzk@cRRIjn;>Vyag0z$GBLxHCbOX6Gswf@NK#2lI z%EbSrC2>s|HF~KPK$Kv?B*OC-Z>|!xsO5evd_qfXvQu9x+jED$J10Z=tcdA3=1Nbz zcyA5vd_8(&1r9k(PTj(_QnCI`)3(JiOuoW#gRTQjhk*&5O5YqGmzDCxQHibMgOpDw zq<%%HwO7+JGGkDwo?rBSsFu0uPURQ6gKBc}VU;A!;b$8LX+O!8)pZkG@$**6om~_= z5BKuj-2i`L6+0u>^fA&bPo_=mdbh4|Zufh^>wm3n3ucNqncOWUM{GeHBJ&7xDEc+$ zu?;np7JhgV;-oZVh#$1abUj9ADIMvN<&mssU7WrPuU}|`NSqa4K1s$Iq2k&NI;&Q# z_0_^p#Tf<}7PPK4|802$pU@x$AR^w5JWO1G#i$^N!=G9u$B&nWwJuc7ZAa=~T7+_g zg9|NQWXl(iW}PHkaAP~W7%+P-(IrUcD3Owpx>~>~fwtr1uU;(gOEFAJLFpQHbb)f3 z)-Pu)4h|<)%PnbH?VlHSXF1{NMqd7mH*PmATxSY_JCI z@Eb#*G9ZJDloaIu4tw$?uZw)J@(Pru_lLQG^h8K#1Gsa}&Q{CAgB<&Ljg2>yMIL~- zT=;{ap{~e48=wYn&YOd$e#E~}u)jJs#iY0n1TaZ(e@Zg7)>!AQ<>ms;f~9G1!Ip=C zFuW3g9X;T!BPdj!eE@0#E(GAb^?2w4}!SDvbFW;h8>ebDFO3dQSB)@j`Gnw&Phw& z!qgVu+VUsf1XXB8&tqcV_5OZ6nmJV{pp4t} zxt{ef2mV*=x$2a|^mpR5Q8ct8`JKM!UXIn!t10}=Fzp1Ondf;fxXEQ!_-7;&4LRXB z;N&BU8OIn?mY+@P0cLTJUEGSVyFI z(N~sI*3HrTd0L88=^~VgN{LmnLL58U7*Bjh`Xx5!*NDG#MnhXBK=J?*iy;sfq)0*k zV{BVK)T9k{y2~Nw(>zIu6!%xTtt&^-ZVaa@^e9 zhqXR8%fN)#=Slh4)0UP}kUYF^8e6-mfb%w33m#NJv5*|YLWb)(T;J0w z_fa>_SK_QK?GyMvFKh(oXd)nC07#RMV+a7B0#k?rt)#2;cN}13(_i0AzNmD8Q+8w> z5(zBB9UYfTo|mF;fmvl3z0vt7+2>53&*fh55itRByw}J%XoT-Cqwf)0uTqw?8jHgJ z{bQ^O2I~Uv+cMi@Kpz&yhQ8wD{L>~PoFXa36DZwlZ~po7Mxwgj)0K>eP5nB%RfPC> z6-Q@h+~{6K*{rIDlO;=J^wM2}S=6|Gq%re|6WEBu{@fejE*B6GKp)@#yvWTLNXjyi z{{(vCz4qW*06HCHgzIE}1mbi})ja>&254SPPA*F(0j2>>c_0D4nl$Uy50Ag|YHUi) zU($}Z9WHB$05TO#QM#%eI}HDzk2-6p6Efj-ueu5b@w6W%`^^AhH~$cVmKm6-{5v$% zT$G8Nq1l$IfB6BixPg0SWcyI$s=z3=W0SSm`%B;&3YF6RojxI~^e-HWv(s*C+Jb6_cHUGU+m6 zNt<)=%90GrC|V<-Qj1~ou4Q@WmN+l>zHe0XRxpiY6D9O@6}Rp`kPbC-37MZ^Ii+w3 zex54h5^YZ&)z|q{D)yKUUkMfo=5v`m&NrLI;j0)*4yp&j)C%g4bnLQsThV+}42h(ZH9XU@~2 zOy_I*K8*uZ^eWcF;RP^a2X-Qh7Xqtxp*1yX=Ld^o|HC$n%}%;4pBPmT>!wjO-Cqll zlJ0$|)$=m2uxs#UB!Hs31+Jeb9EW9?^Fc>N`l>*Y7FLcEMor<+j$~ys>P%9^~Lti`3?i}MPN9u@( zFa|S-OuYFk zghC=c`pO&RVk=w{XR4DVVd!Ujru#MArCWsh_ouaklJ zp&A%U%hH}FpP<@2IJ1J{=9xtKS*WXZkQ07eSN2i!%>aD~{G^zAEu<_Txf*v6OQpzoh6l9!)Y=iK)x73a?r5u7*QBqh2yRr&QJ{@DLGpwqr zgMXTMTw&87@Yc=2Qpd)qs6?G+f+btLnWik853o8w2l*I|Z2y5NFG(OY=H>&TcTrdZ&*W-Ie>}^_%SY)EXN!s-T~UUkLS(jEG=b+iP6UaYY4rl#|u>4 z>OY2_AzZt7ug?oRkY$fS78i9LU0f>Q)#`9flf}ASEX{J8e$$6kT5n!c0}+)hKyG zdB20!{o9Pm^PU9ip;0X@{FdZJm0QBrx%Hc;i;w^Xbb(~44w+9r_@ zuCEzplVW74uN!1MVd^rJGtr5%v^lZ8SMnIaQlU#sLhWUlMaUcD^k2?tKi_63#l!uM zaR#J55)4cmXhY;^bDxpmA3+#IH8V>@63RQVKTE!NHfr6NWr{I5iWT;(>dbXP^Kp1M za!|)k88fG%a(P=dt?KZ+U@p1t1;Zm%1PsW(1Hbn_!qqbnX%PJIaUe1X_i6s>)NSY_ zp%uHjTM7vNBGMP052cuH^@g^T8|4pQYTlId*Tz6It3M9NNQ3j@(+;MRnacGnqf7t z8#_w*A8NDNcS_G1%5>@ZI~%n_OiY|7+9+Qo+HoG^fyc4bcVJWVW`%A_=rX3`C?3L4 zh!**RTiG&q9e43}$l+3R*LhRu$7IYeBN=$N(5F5xrH(FTWM3%IeKH%JP$>w9*#$-i zL7%l0x85upK;{T%ectqxA3O+q6lTumL{ zaRk~{j4Nb~`oIF!G10B3(j;{}nK%Pjq?ZXnahL+BlAk1LCIh1K#$vfUK8V&);+AZ= z;)&yexU1-S13C^8XsE~A^hoxbZ#ZNqYX_K)RRxi0f&AkCRfwGbz%JhMxe2$~*9L)4 z2IDkZ%irA70`-C;FIzDYeRv&a@jo9oydN%85A+AgDB)Wz%1nUF_9+3O&$QCqwCOk5HQ(Yle?>I;%RoNdGMPjm{YecYTPkN;q>!fz82eJ+KvZqaPKpTBG?tbdRGTuU|~!Q8_5 z1(*1Fi}=oTOVGq(|GSPHFeWm#b9S3zd{J&2bLw`W>Sqcf>l2o2no(_ux;5LB4 zqOW?F_uG$D+W7v%o7Rg)(Bgp|izAazEfay~6(yk%4|S|Gcgs}hHCt>2PU`s-HR8Ea z=9{^TBXxD=3_-c0(fqA?HcXP4DN=7y?#QxU7b*(8G6!@6e>8E3R`~ z3RC$+iGyrWe-T3T*JV>K!#%=U>q54c-px2!m|XI230`;}3jP8BZM{~})isH)MC{6f z9+<7=lKn-BNtup^c{rhpq0&Aau`PP3QSuAvl(Z?lhAxiOYp4z{xdl_qgGSK?iWIei z6HztNeLD~~h{|OLH8vT#=D4%D1JqbA$FUmzn641#zM;lPh|!|kdu0+rJsBRwn`ulE zNC6F=h}o8U@fJH4Uz*I&Y7Pu^S^w-@V7A7F=O$T}lNee^(?ZM)Pz`B^=l?4rtKa{_ zHyXGyfm1kIkiD3V!5iCW!56C^i@^FcisJ3C&)sgTp|dmQs3+WGdEI0AhN3~>t^J3K zgOhOOEm?w9H|c%joQgp4oWp9#DN~3oDMsMuU7R$1tsGX<+dKwYvtgy{Q(~xE3_=27 zsB7xz7Srkv->8ZL@3pZ_&R;S4cBc-65A#5Fk(LIZK~B-Wt(pyL6W9f0wjZ{l%Xfdz zd^c-4(XpsfQ)J6VmtcVnt6W}U*DFNF0R(ZvC{rd2cMHDs%NR()K6M;(>QIWzo=4(V zscxW@q(1_YinNjI&w|Zr7Gy2IU;c2KsZRz@2sU2NYNN7~ZQG7NDex_|jO)Ev-ZCR1cutVp_w4eNB>;~EPKylXu^RL6n)g^rv z{0co#Tskbl&(|g@>A%^8@_)0*vra^u$46v!{hCkG?E2UAb>T7XmIy{ zOYkLF9`^!2R!{|Va&kcB#f_B6_@?90nIn}rP_RkRv_L8(^s%tuv!6H$g@o@eeN z!!MnmKtZn?FCTP1PpEKQakHzVBO1gdufw9PdxmqVW}QjAy{nD^F!*3pX=>@pcWsp} z^HKO?k3VX+0SJFA%rE}NQuC*NTKc3e?C+=VJQ5PhR^8#Zw6Hg&x4MO@3?KW$AD$!+ zgss;Zh2fSYW{WG)iuz-V;Jyw0-fp$%1s@W_V&c~`8lV@2UZ^0KD@qXBju?DuxN#Zb zw~nAE?q?Z6&t^&!`fxR$&n)BS{8{YUaAP-~M$+OaFt(z+f_j zMCEZq{8&%cx#dv`{Dk~<#Wobu=pVXJ(WDsr704NhDTX>69)u3|@rOSN9Ryrl%*5x z#U+NMP7!i4T}CgFXalqDXf;0;2{vIbIyH1nf7;Ty40Lotex)sTXLpKl+TV$v!556w z;?a@w$64Upr}&}TCBw6fdx|xIuRM}%EHttN31krsWJMn&+yvkm}L^)jIoKk zcN+O@i8t_ule_krmH#)SdFxeymvv50-`rUK=^?La@y$)C%MBVYop#JpN8Nt%f^W?C z;Nv2*GQ+p>KuUMqH}`1HcI3R}DCz~!mcR`3UAOd$S<&z|nFKG`g3L1L_+H7| z*->5fqcRcDoF>aGVXlzJIn&sPt~>KgHwlFljpVEmvP3GKx#jYNJCYSth4BTLM}{uS zLMme+*><=q*O<_Ur@5T|tZ;uFhOUwAVEqJ8R>D}sMkI~_oLdEf;8(&~0G@YR6+?F-d7Uqs^|Ep;w! z^jJU6-jMTGeBAF>di5RycPVNej`8>lpSUT~k~3$H_1L73s3JlcbQvSo7hjsBA_}Ls z{=AQ0YWXnw0X3CYBBvS~$v=vgzK`XKk`G4xrmlx^d(vVpoTwsh4JmaZ6H1>Umdq;6 zjy0FTDD+DwZe`B;2fV3wNB9A~UOt&tbF%*9SCKDB4ISKd4l9AEUep(^UDuuY_4e8d?IpRR_#l$$9HxjsVEDHXGd%5>o0F*=1N2tMFeDDkt6V}4TRKhwrj0;95Gw9m6@m{>!1 zKjwxH4zF+TJK?sO%G5tgb#Mv)`I{ne-d;SKH^jg_BSaQsSgS$uH%`cc)xQGeJb|hd zzxMXx%eIrpKbE4~r{OWW(_!zZkH*m=UD&bpzxOybGWn&7aJM9H_0gP;F>la(WaTq{ z6)CWI_NKuenvIy?07?3WM6#2A+@ZD!{UIWv4ci2fdmk zx7m-r#Hz;4fnZweDO+|;Lxu@WgNCAZ4t8FXbTpLM^+_@I>@-U2K5G%D?sL!aGg&MZ z*K9l2ioS8#DHB_TNZZN3l2?(VwXuD+Aj|sg-tbF6V?O~}U`tTr;|IDgEhKUQK4ZZV z5A0Mr-Da`f^}$>&2Xix}YzT68#XE7cRyjKpTuL?Hbkem%f;op1$CMAad42prl}W0~ zxvk>7e8n^nf~o9%#kM+=zOQ%em2k%T#)U^Z zDJfL=`rAPx)o9v-zw0XDCwmfOBl4t}66c@LSFZw>s#DhDUofW&$lPz?WEawD%H0?g zAxxi8(lJVmV>*7Wn%)S@0 zU^P*f3cUl$VRcbP0$ySi8FAv-cm8S}FtYIC&jLHtf?YdM4NFN4AyYy1}%%wG^U!w-eFM!(-9>fD`#}Ya0<>K}`Nt1Vwz4Hm}_< z+wZAk-f7$P`XX5}{Y;&l%ctO}dI!g)d+d{T81V$nM`le`wgP2jW_8r)_e!1z+xvRw zcZM&AwX7N=t>1*Te#`f`6WG^(2tMbyN1P}&{`l42pqQ?xgdkT@1P$3gAY>FzimCOO zb5dOos?M_Y#jP=V;N<>`HrLRHxQ{8lDWfHw|7a^;hb&xEaGtQ{R-@sXWHiaU6YMa% zuuj$f!u=SE4%Nx5$O>NLOTg?{GK)E~6o5BJFG+a>0z;l9p9jR!k%g76BV+P( zzW4R2j2MVOJ%*LFNT*e(b8Q?~_H4kj6*tSWBs4n|nk7=L1uWJ=-{s_-o_&Nr+t#nH ztLqAi7J@Q&|J|T(lyp{NPDZ6vme|WME-`iZ-7i_v6G_JVEiKK|`5YY}q5SrGp!gDC zbYNs;{Kn@Qiim;c+T#PE=I6|v4ZBig^#Vk4DWVN>!+9GBxza^IE^ zzPZJj)UA`Tympv_4Nu(fYk#XpF5aePm(ZTDgzXii0%c07hi_{R%X0?|%e*y16LVdmZofwqzv)H&)zavH zL2Qp%EV0H|HDzdwS$oZIbHX^TDY`})X9M-ZnYLbK%T&e|MKWRK>ouid$)?@7w!aH8 zu)}4cleWPA5>U7BM48g>7_!0Ae7Nx9C3r~lGL}Q_VV!__!9$3ts9o2dHlJ~{x^KY) zBQ&3UZ`)Y8V#k;G>EpkFEb%Nzn`~Lw$dnx!TrW^moJKv@)+8dUQ{juz=__EgUTL|9 z9U#^zB=}gCnkZ~;@E+4NRv*H;T2Xhmg3#*il?x;%X6&6uAMBWk!RqhMAMe+_^Q|`& z>ScO>co7%=r8#_+O>s&KF9-+7C;<$|`QEIU@t3%xqu0UDP?!nPHG|yYP+PzSsa+CM z$b3_;lkS-%LZd%({^XquuD~LDt?lx^@OplBz1wfm!u4H~ML-fZLy9?Q>gy|vZTK#1 zqdy+714lpC%1k7*w?7@&JcfUq;3a*|u6v(QUF`&b@Jjfv8$5V7E6Zxm4uq$-V@gZn z|L%4%_WNVtlR}WIm{Oac>Ij3GH+e-3UtNR>H$fKZQyju1_``oCC?%pL{vP4Fjed9%?I68i`Pyim z{pUnGTUpG4p2112ZTbC4MtpIJ8J%F7WGbyAS|k)k=MVJ_Kh8DuyWNJ5UR($>EHow? zI9{An#>4Jf-3@C$cqIPQm2Q+Kr7L-!>x^FOh|2pwX!V}%h;vOKl<*ZAky!@k@a$fb z6mzP0=zt#@4uOb0u{LGUn3)0GVoNymG*UDsWaYK@$RWtcSqaK}BxJ@H=}J6m7nKcl z8R%3Ansbo)8pXAL?)+pDIc@daWZMA}NI;;i=!qr4Fq%eygOEt8dZK4n`aP#gUJm&; z_w;_ed}4}ug?<;V4}7)p$|#P z$&bFu;3ZBMboyFR@mgG_rc(!1=Et}>w}!6fCeX;qm66r=0o*%Rf2zB!5c0R~2|7Yj zqeTrikNT<3k<<`?C8EFS=`EkK+BG(eFtl*{USIFFNCj|`X#i{i(XGU#XgVG_|TEhN(R7vu}-x{zs6EZzjY?Bi-D!Wa8>)ILc zx097U#GTHa?LAb@3R(Gsi8~D2Dvx z?XQDhahH&>W!q(8xZE6s+~M(`J^gv+2= zS#qpq+Sp*ZO~eIz-@0|c#q}`Rw9RGquUj>F{}+2Bn`Ls{*EP(TC!)CYPqF0~V=PU? z7v6HvK9!j=Ql>>#Zpg^N#|rxs(I;Md)HrhT&2|uIK1cgWO8{OjIQ6n^ej#B-24sCJ z9=%!eDlKl(=it)k0$jjDR*=kT!Zm zROI;lyc|%baOT7ut)41if};8<@7vj;SPz-B0-tg-A%Ve1jKnrqKC?3cz-k(S2!lll z$_Zuk+LIF!C4;)PsbJgE{~xP!b>I}^yH&6bdvD(%xDZM}L}@Z$eX(X1)d=1v^UK-Q z|G-&~1Q;yYr;b$D@?3;bdILt~laP%OWtEWp96(LQRt?SnXJ{&O=4}H)Xv*~5y z=1d9ljQY#UF?Q5?&mql$Gt%ZcZXOwx?KLe{9r+(zZUbmQGNkt2VSk;;kL9r!i&fEh)CQ?)P=>nLlOW5*l z($D}S*96z;`RNze9qj&Gl(w!ezK8wRd!oPuK;9bH-RoJ*nrhXugH(xjl-u zEpMqAUVgY+j^)5F&kah5%Z0`E=k}X$KEk_`lj-nQd>_CKzHCevg%kp&M~9fXY@+IzAaKO(Gfoa`gE^WALy;HiRvL2)%; zm8r7hE$IGqTSbV(dtp8_WVqNI-rNwiIF1CtMw5`vC6Je*8eYNv9&lraMbVZ*+)GB) zd9Z^t=)I9ffw8_j7FvKD$*Bq#wV)i}&2mQHVKs04T2My!SuRwP8FOa+sK!^^pnIF2 zTG1RQOJz~~T?n;sMBgcGye^~+PkAxsK!P6KoELTcKh1XV_#eOQeg5a(P|?}Jl&w~F zbkqyGoJg@f^0}vacq@E=6uq^*eZTSkhr--TOFP|UKR<8ansVDAmZfExpnQ6M{^fXs z8K48dwb}C|(6sBdcL8W9{?>X!kke5Jc<4ea$gNq&A$4;Jb>fs`u~VWV{Z z1fvKqC1r`y=5zm|X^73TLTUbVe<0DV8p!L$tJ(Dkn# z+=?t3tqW14PLMPwXw^f6_z~jfqNqJHWWcGx8)+uMX>jm2KV%TU5G@{768{C!o2vTs zXd(9BSA=bwXAuwZ?GV+n1QW#WF2j$OXlrfY1McqLAj1$p55q&qO^{}_nQXa(>wjs6 zhVpIHSmTD(1ziEG(B_x#)R3AH^+MH0d4Gs#MN#;B9Y+H-qjhxoj12JmbW zczL85-wB{mI9@nT%+Gg%Z@oAu0VXfoJ3Adt6niLEbmYM_kC|QgZsNhf*(S<_r91td zv7pO_=GSfxtcyTw03E11Cl?UF`ysdW>WMpK2MwVCR_SlS#bMPD2b{`R#lT=L| zy;K?Nz$E~v1cOF*dw<(4^X^RqN3N>QHbu1vuP6!=Hxykpw_M<@G=)&$+a|K3P(+1E zb7dbmBG3Jm%jNXHCnz*xxr&+eNtj^9ur9`7XU}4N zQ$-laM4N?54?$9%r@x@0zspfSVq~;)iC)1tr9;1}Ls$-k^%#oM!98_B>_0whS!U3l7Zm}S)oAOtfIo|Nbqn)>nCTE4!gtAxM?6Zc>82p@#~^~Q)Jqzu>i77MY&zd)fE}| zuzyvP>UCJEf4TT=X&zdA=47+n(s_7jgRAEs(PyAJ<)sd$QPj?u*;&h`n zYWWf`PdN<8-25#q_8A>;>%8P%L6W&m#&jPw*)P_|Nps+xFjg4Uf_AdK9%+AJUfA&r&z`Kbtp9nko8d>rPWD`z6^+igH|o7o*N-`zF-95nEnp4HtA@ z*SFqd(T|&NQ@=L=Zdd;$Z$o0NMAT8B>hByg^svvx&F2CFZ)e_Ag#&^;NYGG7T)Nc6Md9Sm?Us~qZc!1soR%vpyoHM*55I)E z&9+)m_O;U%c3IOg=eo!J7uOb3%N{p@v<@e7(ji8N>9UFG>A|c3l$sH{3j z^%<-(^^E7rp#QvcQp2Ndim?kthXX~S|yN0Zqhrtv> zYXd7L%f))X+I%mjES1qoN!~V)>!$pPbe9Rrn}WnkWbWx0_3sqpenCgat)(V(N=Uir z(o0Oz{=$+$dXJRxro+M2*hBjHKJ9CsuWtpu{xQW-So!0!{#Ke*ya;pXc>!AvFFaG- zEK@N0bWpk#!yEMnS?JU=jUxo9NXb43cBnKW!b{Oc3rA-NT25#ws<`u$CIo?5)P7p} zbyQ~2S!^um)3cN5$hNLwYD z-HY840J=UOCC@F8-dxOGk||NGWo&aG5GffC6&l&tpvPNZHyPhPzgkB-1$x6YFZ;6! z#eg^~w#3)W$?P$6&UX%pJ~y??zbhML&7@Ffb&_<1Lg2iB@&WX4RSMM#)mQ*BA0Yo` zJ@?;$oBX_XU26ca;T`*oj8yWZ}zW$oaJ4C{lcq^nM8WHqSJhS_Bc-?-W;q87p?k z&${=wCDp8a;E~{Vcrrv?eM~EBK4s!bKYds}R{Z@@5ufg2w2g2?tF)97cu=0v1}(a7 z_dVJLi45dp2sGF;eLBx-W9aS{xJ-PG9QLwkiia^>7Z6QK#tcKxy|Ry=tsZj@og^1D zp9n>UCm-7W$@!IHo)x2&gWM;M5GzX)$1MHxDBUgi50;Pg@u+Ci(L3ppKm5GTF>0Ck zfkL!aP>mopZ0;S*E1cFWQ~Q z3TYc05Wb>h!Y!Egf=wu`I9e9)D$RTTuM~rVoNn@e30f()uF*9aNc_v>j|)0ozFO>F zQ`eKs(bU$4xwPI8vFkNSds2VQsbWMEyHyL%oTP<7!Q?&kDc;ND#Woxc?)!+ak$>!# zHNWO&g&4J$W>$J`KL9~{nPxp$+x^{b$irdn`}Yw*xiE6sN|_~DQ$u5=Co(0K{{-iS ze0qf0U)ihg{QExrYB%Sfe#;O`Kxlya!2hG_t)rrj+OA>g0R)Eb?iNHqnxQ+Sq)X|N z?v|1+0cj8DO#va>j?0WW(NuL%ZdL5kgceK|SJl+~Zdu0%BuLcf=(AVIA!uK9UzFuU zXb4mY5mHAi8vMDSq-(l-;>HpkH%W^QS9>_-bxFSSxFkA~o&oN890@azE^0`P(>J7f z)7UiM)-H`|IaQVse%JJ!$2;NjQ$jf{1tuE2oEk|R^via;(&21TQayU=@k{980u2yFtFbMp1_)HytAc86^-0iWWVgNypU~`=?b-9pz#*Ce}1I z+SJ{RhHT0_taosP1p9l=gjkY;#5HnRX6PusBoP%nC5fg>bx?6-ZaxdNccsCSGek1i zl`IRL74-{^fT-fQGm!z2G~MX(ddF^nIitW#sBFPV%ADU|24leg#AlF!N&iz|2PZ}9 z7#h9>6q2eDE`X{sxw!aTBZWM{0FN*Os1knB!ltp`s;HrXzyr&rXz5Jp{D?QN!E&v! zAf`NX=QBwgzSffR-Elo__SMN__{pismte0O2qe?2&`;MnaEji}s1OlT^nTypCpfJm zu>aebPgqCC4rWDLRQvBtA85^a7UIco???B9o&kD6+$hZlSP+$1EyCG9(ZL7(X@61M zzR%UwiGzcfz*|SAP@Njmsj?6X-}l|gmXsQ)^$-M#pF6WG_XxgN&BANHe1t{fZ{~AkgNP2Gt(7XiFSgl{~!Rs%l*neq6Q4pqukXFN{SzZ^b%X z#vUCKQMzbg-ZN#SYw5e;C0!CfehLT42+u(kN79|(7rJEq${VZGgsgDbu><_M+E5_u z*z!5U$6qtcA72ybaLo4SWIpX2444X3zRYc6P?O-yYwC@Uc-pyOJwPG4aUQdX{r~du z`{R4_zkZw_$P1E8U0tJrA}ANY&8wQO3fboi<7BZJ$ARuNtxVSXaIVB(x7ycCg^o#sLatT@up)8-=Py{jrkG*9o^iE zk(VUTt0kk6bE05NT_{$XbwP)WAGGexL*i-;Uv_a(4*8`2{>-K_-s|4Axj#at z8mrfLq&0SNzTo=!<>ccw9}lMiOp`YrhWms%C?y3L66ddNiqgCOc|D&CXU=dxt(|4l zCRP9Ky}#%C8`8tkPg$R98V*l{c)TLZNh3G`*{VV*fzx~Yb-&7&X?STk;i!G#_+tiO`@Xs=p6BQYl@lNKd zyXHdcp8%f+UOwK}t?sdfh3jr&4{}mB)6-0}w6v0HN2w=qk*2ea~N?8>zCX5!evMdjY}7!u3pg#|3qUe zRE>bpb{u%tw2&;0A8#mM)0fB4=<+$Ji{5e#tb5mlv`auaqehm!Ji;*JJ@+-sDtBB= zgap(=FkzjAZ-QoQKsTIo@o*cWa2YoW&#oH4omI}u#G9s&MIpm#hW`_0yo|K<67gEx<=g4=rA}Z0)7dz5;hxP?A+@ zyrMBh9Z<@DY@XH|@g~-jE21N2r5XcTYs9e=o5J^Ci)i(9S*Z_CZvo%x=?)}sQkrV&fk%Bct%V8>^qGB4nZYfw%VjQkx< z+=h+XDMTqxhweo!mb*E0MdZpd=yoCO=6EgXG5axfvXh*R&DP2URh$(K!XEMSZIyr^ zb_K}7xEj@=EXiN8Un*R?x8-`S2z^uU#7UP8jBXcCm~M;h=JXRk`SE6_{Xn2C0Q?3RI)0*!+>p>5VGHElGfB|K&#)a-zrg|a~ME>WQhm? zDrTI3hfF6N`z+F;V9LgoJMB!XB5={ZwBq}7*FdTdG&|AAt%r48=b}rM^^t~O%C&YI zg*SyB^xUg5LNao6_Ey);`i8qZJe!iTz-9LG^7=}ik+Rg8Kmg{O&z+O&7X89(d4B=4 z>eAJnrO=Wm1H@>J0-%Ha;c4tMfQHX-7MsUvNRBz=)qbwdPaLdJ25kIFJL2B#s1p2i zK48VQ2wF8u>S0S7oTOKVNG^xts#ZnwX9P|Lq3v@cfNO}&x_A-V8P)}@N_N9`nj63AIT24us!VfQm(uEN^OiK1LAI8CM{>6^_f~<5J zF0L5C8uX@8+!fD{NAn&9H8GnBe7xAnt~#00^G!h&>^ZyW;aa%ZHQ^+?#cxq_cOmG* zG!!AZi0Z*90eFx(WJZM0`>jqtmnn#VD8!y5?MGgs!Lq9u4QbfsDwj6}>Hn#elK)c} zOMGX^S)1I&2E{7CkU+QDc68@uqwA^P*y>Ae)PR9q$5OY7)904#M%LQ5KR%~9o!!bn zUT31>feM&DKt|}p)5DGBK!oh3hi6Z%ZbZs+Y7Lay&KboR5`m}A$lP31*3FsFX}#~A z+q!!bd}~uv26(6-AzBRi{eG?@D%E1x=cNCs?HSh8rQW<@{Q%HH$Vf)Z+N`pm`77a5jfa)Gji*w-AA?%3N56mmo* z$(?OZi8o)K*AS!*ry$acG1KtOy2|d&DIBb)#xG=I`QG-XzEYyp{IYD6QRsI^H-Ot` zl_?UVs~6pbP-En~9|Nyt#M!?Y8+SKSTA!bTHoQUtov-l#X+Z$-b?ezE0d|8ex zAxx52nwDBr#WX=I7gzxBC`%IYpX>FRF)bWlE-AP=eN7T zF70;s5OnItV(S;MGx7Pb8i?;NG)0Z?Vk8(QXt0R9PQgD6rjOrmSci4*PZ>-V#&J5X zZ72ciwSfSdr=iz2QKpN}#*Ob%kv_|-%83YtnKk)~@|~-4dA(mamiL>tZ@LcJM>ay7;tmd+3kwVNsQ(gZO{4N@eyo*Y8bisHntBdiiql*;+zO~_?pI?{>bR>KJIOBmhn=Kl|z{7|A zOMB&jzI#JR!=6S1$%TByLChJU(`&v00o$JeMpYAz-Ww`yTl<^&LyjO;zIX4iK^GVd z*`s}euScp$jdS9JV8Aft-NKYQQ3xbh=`)L)>8k*ZZU0f>FqtFYFqJBYd9a!gX5 zVd*Ol2dV-~?f5<(Xbn8bYQT7Jr86|@_kaOVM`~

VL~!UqKo+x0?9Nej?f?r#e4a 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

V0|q_14YZ9tPv6x?nSAM6$GK&ybM~a zGeDuL_(D$kNHF86rWh@uop{+mIpNG84<(biwl?Js-7HvJpyujBus-6UD+V*HKZjc3 z?p(^a(=VFU98#(fjzVQJg#%&raCfOxXeJ>=5=_P1t{87D)K0bTVo{2aQN1z{R23(T1ex9Qr(q^TD$ya zW|-FL!{~09vn&kk4B)UxD}AK%^pEe^plE=JCpC(aCC3k@qfmXbvqhwdqz?u(N9vDz z@sSM97JK1#CFLOPTtg$bcGUg35qzPw`EZ|5s;6}@jH(XDnAkWturC8W75inPEWM2q ze*}k2fEQ|bPCb_4ae!D|LMSLI=C;V)TYZ(NVUb^6Oy)V+_xbaa=xELfr8SILrSk!E z)(f4gY8stRFEEoz5@+H1W)Qksbh?CnjeL#~M*U7iMBSQ!ejXY<@o4Q+sVI0uN0g>m zT09HU$NwyPK?!$XnaVU@iL4(PEIM*M4EiBmz+b9LPh-ud&HRnAv3jN@pm(7IJc4EC zIciO-DfX@AZ)W+o6U+SkWU_Z!-AGZkcTv+yxrJSKwNX2LJl`}uJw0iG1qoct zA}k}w2;H;J$3K4YZYj(Znk{wS@AomMGw;(29X}1<>Ws3q=XXo9LvH^A4zo{h`o7+D@L=-!xn9F z+p^fsT%7MtNVYxFd8F1H@7OH=xSqlcdkulx#Odil7Q4a?^k>cG`OK9>OiHVYL23_+ z#kMfRxVgEfCsKI}R9+#(_P-~3qa5csWjf*-vL{_={NbA*zm7JWMABEoGrqzgyfQ1qC&C_p; z&oio0fp6j9sJB0ywU>iq^bdI5yZ)3Je##bRuH$hZt+Ktq3pZ0ahN8_{=E_aj=(j0*0qQ?QY zOcseW-KieQ4)yYKptVCgetwEv-sqiF^L7~wz_$h6Oc={EK0oy->R{}XGqKt^u}_F) zUheR47V3EP(PvM3DU^cgxNeA=vgB>uv&nAm?xuPdFhiu+W5HZQ`1cp6TB00&Ryz>h=^e_+NPn$Xo+ zSvhE9XJZC=-M6^-?)$!}Kpx;Y*4Ca-29Hp#sse@pJ^+U7J#!6krv3;`TVZt)QO}KZ zZjr}^JSo(EzdtC)Ab6}j{>MhAs~Jch>xxs%q*CEOdSC{IhNPmCcKIHzSgRgF*b$1t zRSa+_3RQ4DxtrX#PLo_@g(#3bQ5770sM<(DSvmh;w?K;SS%m)C-WU2(BVE~w)b(@> z=IeBSNw`EilfEb7&o7XKoIrQGr9e9{T6ed=>dEa5C?t6NX?ABxzVt9UP<6zPJp4T2 zdGmHOV~e#we>`@MtqA}=Ngm~DDfKj$5(eHuDz!CuV}ja^^Bhb8Bo*iT!pT%KLJ92q zhJ=wWbDP^+#>MH`SXC8$4=xo%LJ6VP+ndCbGmpobyrq1V&= zZKjJa;+ILSTv3|Kp+?}!9~*<-^z~;)+~S)iYKpns-DM3-Ie9+36$qH^`25+yQ}~31 zIA1l*kGh;szVQ<*FEN-MF4PgvjuW^9TfZpgaM^t%bz#`GlhAT!Sq(~{?XSCfpofYn zcj#)+OO;nqDFkbe^GiyMI;|Lw$UJNY0T&bZ%f)0EpMMKVm_T%#-&h1&zk`G`rehT&hoI( z)66(e6;vH4idWu{p&A99FAhg(ewA@IIGao8$#UE z!=t(ULKM+a!t^$O9~aQkWmO|O8V*okgY9>ci`?pLKe^hE#+a@)a(;QeA^1$_RdJcb z=dM0J#$bVlu7v5#)Rb{ZNUi277i;XC;nY~7Mjwgf_MW>=Y`Ot|X=d@w4N9fA=2-26 zO^f$Q+&5e!Q6ZV!l2@T{aS*47y{35R2GUcK?^)iN z0WmUm&V^Vd&N2$n3Hs2qD-6E(ff5q-`SBtYeo6Po(uKxZv zrK|Z7()@zaJ;0v%Tc#$pyrrm65W47|;n(JtmX??AZDK4|F)%mg`o%E1Z3I^HO_p14 zZ%0Q~Fe^B6aeGhnLzM&>!8@X=KG%TqlV~eaNBhQuJ{ASGmhtn%^b8MU=jV%pYeLe& zs~NCnWjAupsH~<&EYU~;Tx@%wqg3?qBR00-u8_!30UC`~VcJGJO(AE%s*rq7B9Y|s zzK!bv@p4L=3t0LcBQINK3WO54G2daEFrMmseMpXs?SYi9Z|gdW#${}AQx(J*2B@=U zhA*{3+5A)dZA+W;k&g~^^D&h?I%+Z3Pp}UQ!^c(*4fqZRh&am$4ur@676O|9^YAF& zV1giEriPN|kvG`~z*f)TV9ujQ;SDxBumPwU>R6+8b=5|_4%iE!v~Fh878vKh2Npk_#J4Q5b{3wy`= z+zP4{dfgO2Xi&SwSHDU5sNwce?tptyjd@yhXAuWAlxKrxdZD<`>cY&)t))yx`}T6l zj}hjUHg)rB<%Cj#2nudgpP%gVHU3B>?-3Q#=n#0hQyztbTP z33yVW|um`;Q=HZHfBu~On^NH#xDqFCu_#rp_mr5skOH~hX1AdbNW8dPVU=A z+OFZX+EJT1c^v^Bwh5l@fBkjsNXR*HV#oNnVEn?!s_|ZbYHDAsR@ib&3MThbL2d4> z$F`N{d()Dft$F9vcLzaz$;@WoeBw*TJi#p1G6>SV(x~zGnx>kc5|-jMEUL}A>b6HY ze=HIcPf+g7u?VUqn4fMA_cVSQo6<1AVY)5EU6LB;Tr!^jHxa3#Qaj+$uIz#>z<}Hg zrZhrVQYelT-0WAn5dfZg z>LHz5%U=32iVAw&eBBiWkP_WxjCad(S@9tqBzrFHy{fTk^S?R?WaRC5dcT&-hk#tR z;+%wlZ%Db_vMARkZ!jS1l-_vbV7tWaXtC~;L&Sn@d3+uaMx!CdfZWHgc{Bw67 zYdy;Qw24apByFgU+&dfWWpC$Cf}FrM$t!kH2p z09~}=?vytJo%lj__8tjc{ZWND;uZ;v0B!wM4URJ)W3e8yh+}f(R@wKdhtP%;5mLF1 z1pewz1(=JW=a$QZ%tFg|T98e3*>#|#eGHI?xAPNAA$Zqc#uMWA%$8MlLlo;_+m1=z_B~>q7Id1u>Fd!TA zB2Xl!t|L8wCz4B0x16ZlV6jYg#~-$dbaOVYs|2~$ubSs1f(TfVX;scXXLQx2_Z%Y5 zF8^GGf|QQBwZ)C`q-cncd1)1ww}D|~Ofd_^_uU<2S7-Im4u}Y&j#)Q4s3ldlomcvD zIb09Q<7oD@&RchAiM6#AGmlz3%>2c}Qt`Q%&H<^;8F!%@5euTJmH+c>Bu!c=QqiEw zhc9L*&$`3}Um?GNIfx&m(_BZpz+qpl03T#Uv791n5*UXwU`W4)O;aR~H3I|+sddaM zYI^2d+*ALcYDK*FX{RVNpMAaWNq)>VA?b^OoZ?+YkJyBwZ&6;K3$rH-AFc~jLC^}V zO3#OV%Bm(J@A|Ssc|)|(rnyI(pq+|CUvT(L!#}G4wcbTLN?GATaMq3HJZgSCx`>tk zSJhjD^fIy83i=KKukHjEG>tbdY+_gZCcy42!FB~24Lcy!$CDvYTyt5sO?vO$0@tgFND8}+TxlF&Ht4V@^ZpB z>&l0HG3FpGx?m*UM+&A22 zA4yudSUq+ZXcvz_wCDtlSv%mD<4WG-XyZ_IXjeS1qpl!sbw1#jy*@m?w}OY5u#71v zo&l2{g*6KbtP`K4|02dgXOUi+8gVdWmA-JJl-W_~;6N0aFw10yl8##9cn4bb*cwYRKJ>Jx?F?$3#leeeR!e@8WQM^Y zOtM-~xhfvyF%ocn%9|3%5!FAsrTL4+`ama6WjHMpTB(-JX&c52t!*+)8`CkDrm1Jx z{fLkx^wm5r8L--wxjc4r>~UJy;>nO;y2r_Jbf*&r484}Kf?HYnis|z!GUFFq_~CT5 zLNHDPx6yOTaYz8jWPG zA+No(h~0cJYl?fgu->zLjxJ4dMxuw}GQjg6zgGF?u>hBWX=C1X1a6U4%EV=OglF_o zSG$rmO_CZvMZlewN&}{?W6|(39%;{<*a?&cal6A>@_1%d>=~sZml0Ct$qB%kfas^u zU9#G@nmodli|7Y9=qiE{5|O|3+v-l=HDb%(cyj#xYJBW)Qje8p+zQfBXT?G=YK#ml+*`VBNm=(tM)I<5&FsRzY$khmrLsgqI6YNO#hGMmK^hzyu%0TE+W$$QP& zER@FJcxF-(R2(uSv*BU;h|E|*D;NBjbf^6U3)s6EPwxIWF?!M~<20A9m$*WtEQM;5 zqEtn(B%$;lJPsFO$3aNb>UqK>BI6Sg+58n=PJNZx$Q=|6>11Z3BJRfP{%W%(*X&`Gf5y*|wqHSf6xx(_(M7WU)9m4w(X4=R{JP z%j7cdD0s6D1EWw!otVru8~b+$|FX0anA#IT<(TXaoq1TZ+-tNONDhqaiI@T z!{CLD(k5D4Rnt&ITkhUnjKg3b+X-XkxJw*T$WTKPaBUVAI0~$!Cicr33|xgPVhQoe zpiO0~{0IP79Na6-&0YddMw;AZglj6nd?Pchq6P;0rPgC47jRp-jy*gbzrNY`CMfaM zviN-cQY~F*+RU&Lup0dbW%Xx8Y(8t0*&V4GEB+lP6N0g^Ri%_|;4l{$=`fKVJv!vC zV?2Wv#GAhxuSzKZ6Mns;L50DHL-!?iBX=~BSZ# z3ET7qY0u=tzJHN1Wk@iIXPLaw`XVRdjZA{19FecVurmV=H;64F6>E?>rAX?p@D4Li zC-u@F?Y9ez*%$1)ZKM_(FY2P4xBj)gCAY&$NXU)X9|+dz_%$2t%2CPqfi)p&nf5=M zQHsS1yd&n7;ymr+RwH)J=!S7Np`#J{Y^t#_>9#x_EWUT@$_SNo&UtC}7_!t0!9fvo zXISwpqzdhiR|042TC-W7qJ)w_U#sn!@NNB;Vlp?~v?8aGbq8mYsS-h2q3Qx+#d4lo zgtr<8!j!JREF^FF`ZHIJI})qb6+R1+>rWvMIYVP^%Ywwsa4^CZ___i+bN~1S##OWJ z50DDTM5$M}))KDe}OL>GHFwg3w%Npj23dHvkDAxi%EuKSTcdb*}V|ZsGIy%sQf#AuJ#u zMO~(rgfmvFJ{bQ!a=+1Z52v-V%}^Qx3qd zm4o@dErCy{5Sz9H+t1rWoh+@42}m%{luD9nnJtns(HnE(BmP2m!?5*a_amT)CaOqi zkZ;=j{0uh*9!+u}F$Epiv0-On#B$6XaFGlE#Ek4UFeI~$-uh$_+ujsO6ep&rz<-nN zJ~g9Gia;vB`hm?7sW{I_>8zc$cZ~~ZV33_xLtB># zBf~4kx4kEg3>zQ=?C0u5K(|rj90od6q#XQI0gf_^H!`?BIzglJys5@3JifkDO5gIy z&R6%LJJzjo>WC}HjF^xfyYNOz{f^rf99$Jfs7z^?KPj=)`GvsqwR5O=gjig;y0+Hs zMxk{X3rpY+63y{uew_?s2IkP|m`oC-Zi@|q1Pe9U3hW}fIys#zH*WP8GOuoKvNASL zDDdL6Ujh4`2F|4BtR#I2=H@BRb<2C^SBq%0!0i+vF;KUent-d5m|77Vas0RnosZs~ zClT_GpWnX%NdKtBjhINQ(0=P=;l+Sym}(^E1^@#3j7Ur6l1i2@g78XRP6Y{3UafsG z+qzt<8XU;rIip{S+@z4;1{N0=`KB9dv~Oe7prmLei1Odv)X*dU^zKk-(?glhZjykz?Mr`|jt@hJWwX%{Q%Ea79m})?(!A>&utt z(n(~x69N=N@5XJ|)%XR;ILxT{KY47OZAw+4l z+vupT|BV>+69@9ZAABd%Ou3h{$6MKEsgE;oopmvX#>Ql{)4;b;dVT@REDS^Vw;)B1;1qOD$Fq|*zbq{(5sy}y)7esucG@@oi)@~wOz%HjnQ|H$ z8p&cde;XFHQb-+r=vDl`X30@mTU!GXN+SP2BQ|AjY%8myYvYm#B&(pn27^nMQhI)( zwr7fT;Z5PU1B;fSAxZo&IogI@-S7ZUoiz^$miRYZ6jjrme!Uo*SB{ZV6yZV9a1U@oxNH8Krg#a5bW}+OBEnwzZ)*3!DWrNY5Glx18d9)ACvS8~#=Y>g2AazFIm1Dq#s2&%9Rz7jVf_b9Nc2FDNTNDKU#9YJl(*4$ zsLD;ZBr{91=g&*+Sye3nS|eLc2z>y2uYF(oCVm40L99eeX@w_=%gc*m{WL@ZrF0S{ zgriZVNK9-2kpO@a6y~GW?GeZXd3>lXSO5%4qEs$sAegBtvsMTZiC~aTrX))ei-=$% z%cZ-PVZD?SOQNcj5+j1+{{h?Bur{L%S~+oXyYiZlrjgYiLywraaCEf0dF~mOmf^-z zTsS6w?Lng`=Q-3)v#l1b$y=nsAa&u@zXvJ zPpK?bro<%}3|vQ{g7X-4d;f=G+xPv2ISxfZx58+846xYmth2k4s% z@C1Hirn%jv6i}%JlYjZ0Xd$_%(y!hIX!MfMp~bD}+=$`Bf&m8bC4Ea!p%O{yV6HIh zfBUP~Fnq1Yyp^nwr1Et++)&rBPXR_i7oSjV`7g*OfEam({Donm^+bSxPV5CP;BQbS zqh8m~%?sg%DN&0*ECsAZ;%pk+d_@K0kLzt9uA3h98j?}!hha|TCc)UHvB}*xoy4~L zs1=>Fs!>(+fFrLL17DW*a*+BRhQbP387oAkfGT`44cB2TEe@m*c_sXp81r)CdRe4Z zV>HS5Skwg&gUx16_=~oQh-yL|hVi>k8#{|p8zOS2)!WYsmSCCp$tKHpBSuWl=WL;T zRx(O(@P;$Vt%<`nTg?dm8 z&5biE+a+`#M1%Om5Wc-fCd46lhP}m>nS{ppwQGFeheRcp%zC$a?T`Z6;UQP)qy;FA zsYL1!#s5~JCM0kW$A>{rU@#@k+Ee3dnY>=V(4rMvp_EtM43Bn5Ca{SKB@bXC4irLV z*UFT4CE;jsVoejhKrZUG)uqMX6YX5}fej&0zQ#1Ke=dg_0S!yNs#;+D_0P~D{pIs^ z{AbUyeUEElI(x<^yr!+ndb3#$U)HQ_-siR~Kr=7JUHd-cSA!f~s}~eR2v>MC?Et7O z#%NE@!XYx}SWR5@i&^k~GhEH8(8gJ-NVhqgwNky?Pbiz+BX)v?hp>wwaRB*f+DzYh zZalu?oXnW;UrU*A7A)<1F(L6_z&#(LmJ`~1g(H6z26?Cz(eZF-1IW7B6N;ISo}U}N z60ls|!z>MehlC+>mh-uJm0;>`E(`hR#|7O@jDyz24MD*B$S<^(^{apGLluxeXrVxV zbQ9%f8-oCm5vZJTo`FsXvw}@17;`lvj!JQtUF2%{)5N9$vEDwmAC|vgDYJTeV60ii zG-ATGPWag4LFP$k}8%?beE*;Z`&o#bN=(n&HMJ5t|friuQ%$*bxjdWz5h* z;RQW$5YD^Z5qc51@x-koQAI*3vUw-%_II~^UVD{rTM%|jXv(W%oK}E7X=o)*J4CY` z=MDTKG?uqhPJgq2oPOJ1CC9GGhx@vLGy+p}#4hw!AX!h$&z(*tzssCb)cKD=x?0Tc z51))V6V0OTRo9sv#?fZQ4a+Jm?=ZdCe97kJTK7_QBA)qQWcqd!)I!;LU87avSr1Fz z)HR^!4Z)TRS`odw7+3OW(#D`-CjD%DMX)HMPR~y)wBv21#vO|AY|1A<_IbM=sq22| zfFpkTFk;Eb&gMO>C}!^Z*FUc)s1LtT#g89t=E?ozq=;ysKVJG*D-C|mZCn7Nn+MY% z@}PhUWo~?aU05!>fiipUq6`MShE|teD1~PQlRsfUC;V>1+L-wKG!M1D z5>XWPeeB#Kh?mS&IO3l6RPexvFbC)vv?yDUwx-++6WIG4@opgm6wl6_V@x)jPk)@- z)_DxkcWl(Au50@Cow94@=kzLUK<0Y1&h7u|AtD@m`$twmBl61!bwOI51A=xb$oRE< zH_xFz?oWG4Ol8^P2&)x#B;!O7%3|{9pT%_}rX9B*O)%4ZItu*MHH&c^np$hR+AVKb z)$gEG%y5TD^|m~#xR^GTHbnU@s*LLF33G2VWzgq)uAo(a0Yj|e_E0-h$!1sZRg za~S2>&@8*CHx#j$9x=vxo!K2Cif*PW*yF4jITuRiSj`~=h_&-xfp z8pBG?w4d>9d#waNuH)-EPU!$rN&Aa+e)m(k1Rs|91 zqYW;|1P0=8sy@6?ve**_S^0=cCFu@iB?vGs8=gk!jVcCTa$-DI`bqS%Oo z2W2Q$Ra>(&tTmA_;t1V0TNvAgKR{>kz;btrvwPA%JfP!po_6;OQDjqhmSkg*P!W>! zHE>+wi{!-g=+jR1!y$-6gjvA;*lGh82UUW)I=nYaiF9Lwc8|qR>??Eb?P0n1a9Dja5vb ziBfa!<+6M^;s&OGgTbi$D~4Co)6-XcuH`bNa#QgneovC9{7wF!A9k&s&PP*>V2!fY zq7M&NwBW~Wrce}B@Qnp6$LD4q8yoww{V31g_e{4u-|t1+JU0}OWWkzwzS?}2=Y2^# z?lcldWS(JXp^VEg8#g|qj0(%yS5H5`Sg>tWT}e-GInJ~D8v zWxd#SAruDJ$E7GFc3q87j)hQrfKy&mI6@qX=No#aIl41Sq)}9;39(@awlX?ivDpwg zTq1RBZm?M_Ka@vU>C%N!YZi&tmw*~^W#(t73Q0A-Wtf;^Vy8gD3dH5?7;cj1&BOyx z{caAW@pel=l#GS}0gHW_9tj%N&4$Q^Uf(YhUHoTXRV{zg>?t6*_x9RE1@D=p8pc|U z4A1$v;q#66)~f*k7)djJqkrXezS?r(N` zf9^7W>@Mlr6Dd+zCINQGncKD-#+hEdpUKfU)#*K-=R z|2VW?f^+$n#^v#EyIkO&761S<>1448%2{lbi0w9$c;89p?qPoRwjxS_f4`w}72wdo zf5xYoAY2NxvtiD+mzk?z?%VA@$-b=Tb3J64)$+}$k*$QDR$&SLczU>9XAwv5;aSSc zI7?cV&5~gxj9v0@3W8j&9RiC^oPb(*TXx+iajWt5B)IQuMRz%b``GU#*J}MYCV8%^ zm%nk!b*^Ti4I%5f4!}sP-S04-)5r>H6NOfg9%;m1SHUeBw&_;gdx z{zz)V=J$$j@5jr(jYnYwAD)kw8zgVri_Xr@0Ed6uWUfMkf_k^8?mn+;A`wLli?o&W z^z{BtLs+PM|DYgGU3k{g(jPCj{P*NJ5y*!3BJnq&0j>o*|CP9V_nE%n^Qht+8~^nn z23R*=bzb#I68k-kwRT@Lw00d7MH|qICAr^RthJKxxLEjhGl#5nxSs9q{wSaS6_@ve zkpma$mI$RMROn(~-Ru5DPvX~71iwENX2 zKOqVZ4t6ymdF;`nZvO@sHbn^&LesV+x_E%j;9oX}w`XM2Z8d?2CTe4K^38B(dOZZj zOnb&xhcp$W*CHSI3+b6y=P~;YAc{2)hj8zd%~UZHl(k4zt7hm^cVNbb(~Uz^ESGm+ zh~E@}n}%*+XWJb-tHO*}JvLRDtIut?jMD;c5;hF$8P80y0j|%0N1H3+fyc-5QNI7j zv!p2j^zW-ys}7!aYyZsCrLrC0sFUMFwpxfIY!hq~J_0`;P-+CuU z>wP*k^tmN@pPfr9-Er{PXkPZ+4kiKEu3#2wXrSo3E~>viT<|{cC)c&@Mtz^=Q-zbNAVMSo^OR=X+nam*+T*<@emz_&>q342EI$2(*Jikb|iF+eb8Vb^Q1m9UZ+L0gXmZ?7HCQdVVy?x#hE@ZH_>8_l>R1 z`_W`zM<}(kqXSesTj6X$jWHifI6k2O2anmgw}SPQfbO)OM}dHLXq~wbkiQCFTJuSl zbR&?XJD{TxNaMsR53gryGb(r%3_ary8K~MRTq>zk(pS~0?-?20xHHzu+O{?I|fkP;3mW`KKe2GdY zS0;zF11s(bpoq-1ce>uq>T-`8_(|#A|H`cVKq^1~UtKTjIZwX4yojRmr%+03rvVbm zER`{tJx67kdf%K}Er9?4aZ%q{kvJ!9&)<#qSFjy6<- zDny(GgX5RSE&tEAx3{&ekB9G5T%wf?zJC9o1-KvO$(`ceypEG)YTut38*5%R@P0l> zhx)y~u9szIC28aeQONDRv}WRyl zTgMD(i1E+F!u{2r+juZH+qTc|FxcgDwycH2a;(Z7=73Q!oK28Ufg&J}Z%T4;$XQfG z5avRvnrAD$Z^ROv9=UW}vF9p*8OW`wx)EMk3*!2C+KXTNB`QM;jI3Z7zrVltzUp@O z_1z$>rVUY&s9n1NZ){rqjCzq<1&mB!9Fw2FyRY-_?%+d0lZF@S+E0@0d0DK(7B5s- zWsKTgwXTz$cR8BMo%R_14md@I9U*dGZvkT>7{k_VTgk{rU$i6y{8ef&9Dfo5s-opx zWR-j`aiTB*V+~@y9KductfZso{I^lv&!f*b|JV0s`r5W#_PXcNa{h~w_t!`NkK6p- z*Gq2&zU#q_PLi)61w~{|W1yN0MMiD?ScU{lLF>oEStxUxvEmo6Oaq;LL0N3?Rzbl!UtV$+F zRg>|?2egz{{Zet0-T0}IW|~FWy5V)k*t+httnYrY(do{DTVbuRh(#@(Q~^pgwY0+* z9lZ9)Id}%Q=SBS#FfPdWPGgdz<+`m}uC>^DgEd{MD`ETys=yN|8h^uCqTzF@p)%Sc zj40UQcD0o!6}b6BQO#=GJ?z)(e>=&U?WLn81PB6mZrptg$TwXG_FE!`kyjN|au}n-1|6MtL zFDHhttIJ~zIdW9VqmibS-+Xd#eO5^^HAbfgB8N_Zn==tM??f@r;Rp<1y<2l z4fM^_#j{mCE4O1_PbFU9R99EOwSGQqxh%&%;N zw%#|k{_7X-%%3;Roo@VyLXt$T3)AoG)A}AeRUhO2p3x~zj*cf8CUFSBjK+p=8>M+@ z=osI)(LN+ug&@7RL3nL-&?iqZ%b*LYWq!lzgO;z9CmSLqMaK0%p7@cr1A&;}e`YXS z??+z!)ULdY{i-9L{baurcSwebTRaDZVuXf#%p_kInWquTJ-EVbF7Cppi4r{$Y$f9W zTw#-i8LGU3IpQp4e`7{9ecPh0Yho!Fp^YUz;qhSIuo-jl05cSRa43XrH@5b?VCwO< zzHSY^bDUi}$g;As5nTAOOl{ji*B;dz;p)+3rE1;ZlA$08eHWAqMmTaOG{KFHn9qU< zMm~x1YM-s>i2w8X%J<6qmO=9oqVg?QHVhZdTt(K1iD9lI7GR_zheFKN<~pt+y)8FX z*&SdN-}fI@PH`W_NKlAjl1tCKxVqkNdS6i#;dE`ooa-=Y5Hsf_Zd~u+6HW^e_2U~{ z#YW@vhJ~fiVid>oZ=6&`Xa}67W*vL|2|2*iwp0mK`IpVVze~sU#Sof3kznc>9zt^L zs7)p?$@SKF0&zk`q=cSjs7sz7tCEcD*p#ZI+tE%TMaM|?37;$Sln(+x*?F01?K2__ z-_)riR-wqEk{u2Jd`0WE`pfH7Uz>{O@s-`%{$jxPA`+S&kDE7Y5uWe6p{0ZyQ|i^% z#B?B6*rK`b?+i+G&?Pzu+vZ3UrmDC{wcGfwN;5Y4L>qc>uuemvO=PAbUDR%E=cUfs zqp7xm+h0>0eV0TXwIV<1e8!@fga%tHqhu2gFu|CZoUEy<+wyz804pmV!Rwo7!?z#G zm{gI#-33*}_sz$i)+_2)u%~~9jwMCA*zco#g$hHf?u*a{&5aBxB*yD@-gZ)!U4JUQ zEJ>Fkza+(BqvNfga(ATMBEkc1I#C#9POJ7gSD%F*A=Gz27 zxn&1m-}ha^*Ji<LEUbzm+>REIr0=$A5yKv`uhKy3pR%gUaUq5p*78qXYd zMAIy-RhVs{;0??9-r7~0A}UHGLdjN3ZvL*u|3;%8p$}DmXoc~lIj4>3iw1v8R3U^= zGtw<{yOo79fnP@zHc~WY+=E2DOB@RGI5>@#L@7_Z93iDGO^HfqdE_F1=5=7q&Wafm zqojqXU_dOj{*47F_b&X>09mE@f-g!O%`1EC%Z^&HXRM4}${-(|O&~Riz)Y9$N2k+_ zP6N4&LP}aqzarKMPdMEFscvoBxoxPpT{JD=>AITD(--~O63R(AU4~Rit?FrYv}Mm4 zJVG!`VVSK_s?ypHQX(5fCGq*!qHCWkNA>O}IDOk^3X*~^v)~k~7M$^_eR$3p_@f)e0_6E z4D4&?PeKrk2)^g4 zJwNrI-|@H{1JNd@r{Pe|t%M?arKI6d&Lsy!Lx=dLU26KwxQup;X`+7Ex?-X6<|^3N znmalz1iIgd12W{OtQP(1mM3rH=DfZ!fiTDcfs|nOi)yO>??fp1Qk1CQ%c45r~D5V`7<=h6nUUu4len8dvzn|50-PlI##_{&} zo|M|lB<+vU*ZEvWPwN^OC?r7xBEdAJ{kklB(|u9B%Gz2*rn%{-qvQ2|^-`K{(6Mx7 z=yg&Gc2Xi$Xj?bj*8Wp4!EmURshMM9v@d!dJE8XP^MV&{ogftOHhYhYqBS&^=h$e+ zZy4=8$L-&j?62KOi)JmF8X6!0R(KI9Dy}0ih-V>M*}*wsq zl;bzo9x0}tNt8JHcdLT0je_%3!S_Dv>-RNvEoF#ODF42k&AUTO9kL9b2HBhSNP#CSl@nvFIV~jS zDWW7VlKut}Qbg0B7T>R{(VEH+K1ViuEb-a1`vnWXWOP(dVY6*hHvC02^L&6PK$;Eg zT@Dy$l|_H~vWYv7;=L88^GZdyqxdDU+P?! zq!WES0)Mdm=Lb#&-WI@?N-48n<G9=neC|I_SX zp$9IdJbrJa3uz6CQ5oPJWS0g+^`N^G)QrPFPm+gCpWHHN*#@wl}=g# z*!Po<)|4AR)~nl~JKe-BK?PfU_P1XjqGL%40eBXtGzF}TjE%u0zX1!vSnRIK}81M;Dk177E}wFotn(^LFBr<$F1MzqZIJ8J(L$|6~(=LF&N<&4CW@RH;0|{?t;mUSS&lkBrHfE)a>6ypK$aG>6xBJjZ>l(2z zpbCddNT@g*9WC2!fCImhq2){4!mcNVPX_p|S3udG(y)By%1cy(Y`sqr$9yV42)c(a zo|UQ`4-E}n@@)%1rXP3u{CJm%r?)*zSz|I!P`O-dWkxGnKAW7JL_7H=YGB0G*l`bZ zV8cHV(5qX!;OLM%{;8+05-cQUs(dL}PXdvao*oJmp&VlbijX4SI~>mxHqf-#Z^e0? zwQ|dey@QOC!1^2N_uHFK-jNwCVj{Hnv9!MD?U-hd6C3{fW@-Az)YV&@a1+Bg*!k}f zpotJp%YTP86vSstvH^gvR41u3xuOJB+ea3g}OX4I=|YHI2py}R2>OTYSd zxyoHU6;s`>ot} zkR^?BTm>?r=g&(2ET*YD=ei*zx%A#>+v>$n215E-Esebr2b~`aizu zNU39O{;w7?3ewD>_tfmqRbxxQs0g>K&G*04eh-5fif_%){>aKe>1K}o{{qu#@6GRd zavyKgpKq>p-nolCbR_O4e)pp>@NAJ;I1{!)YS1%fIIkR;m?~+x3L{JHHCc%x{|y~U z4K8>xhd+B*Xs3)_055kJt)yM6nGZq~s4$XJN>USUxW3bV8=wXr{%#>PWk2rMfO*w= z!j5bAeYl7fa(Igz37=*Y9;B2HSPhd1eJ-$3UDy9WOMB zOHv2Jhbp6X*kW6pSM}w$SlAy)_?I!5MkptjS@(Suv=|#iEZFLcA{_IlzA_1}5_{WW8wqFpsKuz@?%)KIo zCc%eFiK~gcpIfsly^8~+=Ahw$EYr7EO`>CBo$>djWf3a6ohmYYT-f*b<%2CingbT% zc(A|x=zl}F<4{hrl*4qT|E;_X%ZC6jUT7a{%RYh zt4m$Nv5c1JD~VbJ9!_F_1XH|#>t{8a%{yCt!azusFQSsaD>6%g0jIV%WcTrXXT6@n zuuq4`1|lp+uo;zga{x2^ATo4ioF!)>5%z%v8SbvR!6+%<$&-%qWPbe_gc|{|UH(W| z1oJ_bts;&cz~=K$&LjS%f_;&&Enu+aFxH!V|DubNBfj9FkAL=-BtSE3E80vMw5k}b zbRZiMbid+)I5(X$b=+uU0Ck&(0lF3Fr=NlJd<|Wi zvn)f7_%2j15_bNV@1J##uzADTtmM}Hl)K-f_m(J_dxbK{j;nx#?~CIFUT(&j{r^6n zZnAHWRo#X5%EYw5lD&bHOdl_cvEIgbkf_2WJbdO{-;qv4}~jOC>EjYCW<_Q=Ckc~E0}0o^6R-|gb6AzB2{Qzffv{D;7D>z7{o{vshemLcFbx{H}@J_NeI* z-^Fmn09Cy@P_QeVMJ>KEJI>eYQJ-AKiVa~aiYV)c31*thWi&ZK74$;CuN$MH zgJ9VO?iaHbDMw)0)ZgFV#dFrMug}>{HM6iFvgTzqr}fLrdMpGx+ro=ehb#Q3kpIiG z`~geB6*=c$Zv9t}_itwV{lI77=%+L#7ok~3xN81c6r1H)0HZSkP>orAkgJ?SG?vNp%j+eMMwwJq8j_9!1=lx?_LBL%-lc%N3Uij&wTA0ni9VR${G=erO4^&kOAK@dT9(2m- zhQnc#Ktr4q(86M*#lDw@V-mH#L3m9qulNAUHA6LLu~nlrryqydVd87YS*cqKIDN41 zaS_0y`fGbefa~%kXD*XQMA|P?XUZLE)_0y* zJb5-No`llK%`(ekwJ0okwDXwfmT&dq{a6_-LVWTjqC1$U?e`C?^C<}T97SKfn{t8% zl2QNY>A+y0-nXYfWV6YB*pc4|bkzE59ZbO*@Uj$#w!o0<@)s9LizPM%R=l`)+(q2T zsME%P#DatSD2>vH#!J7|hBcl#hqqrGhE38^=UAVOL5mXEkyW{yEj6+lP8iBKuQ==z zVukjc!m{g_jr^)hZTPCp7?2gSF7e##+5zh6qy3h?oW&Xmq}#54&4m47fqYVq%CpdT zEt*>v>bpO8F4IB*oGk*7`lysfb6%CMI3#)soCtoAT!7dsly-Otq(}J3ajyMYj6m>J>h5sScqwIh~ty9#&X0hYL!Nez`0K~zQ+cQiK5*##?10Ho{g>sIuSzHHs-fE_YWQFk3 zc~LU0IIJ^tSQSc_!`*VB8@Xm>b8jkQQ^sg-73wN~7ax z4jn=p`|xX%T!K|3+4IcCM_6m3+E{&@@{{u85s%)VAZwft{9k5@D%ppkQsWE7DF!wm ze_iv5SJBn@8RkRXWU3q(n=o5-N3-8%ob}Y5NkE8-%h}LCf-L!eYV8$^ zSB3abQQx!lMJ*jUvUd5JM?Xf9knUe#)zYWT@-1~aGXmJjc#tit$OpJ>mdF;S7y~%N z50{27ku;m`Z{|Ff;*3=<6Za_FbF4$T&3v7CvD9f94|BLuH%tuQC1#${7of&UuD)J3 zWf!0HU%E5o%^UdVH#l^_`yJ9>$C%E1^|HfU!Q6y&cngFhg?*Yx`H^10Idq`YI)WlD5Z5hRtq-%iuMN-C>~|BLgFcV%LY??V8Q-3<#SWq3cE=p@_1l@N zHSKVgY`|R-oh$&C=O^_hbUjNPn**2Av1m-@dSj#wym!I=TtTkNv!%$zK2IT_fI;s# zm`wh>z^XUJfu>=C+!jkokWM5rzH|#_p7OTv#idqt{5=vLu9(ST63iSF|jo zRn-`^Hc1wux|&3vq+v(%c`z7hA!a3n3JI0)&Rc#?jYgGARn*zVT2D2QDD$&`b_cXxQvk8^wjE(OC^@l zcAQZI^6?*j-+Ms7Rs|73%ys$^~Zb_E(Cxnxm)gn>*E`sO0w93QILadZrI zkGe)@I)c&&FlOS_6n|Dec~#Z57VsRiS3rHaCm~*liI*sGE04TGPWu)SWwPN2$-h0e z43j+Djb$$9IIt=dJgd3LYO`kzPQ^wT1{quI6#z>2g>+WZGyzm`+F9NB4D4qUv@9GY zwZ<%k>6I`V2QkXb6W#~_B{j1iXgUZZXf+{QrUU>bLbGclnKkhkuk)-FyeHJ*|7QUp zQi$C0Cmj~Nz2E~1%xuU>EA_r5`7CBz?4?;t@;!08Eec_NCd9WpMsnQ*YzE(=cdRa^ zfijZ!O26SPbF#DxsB%%{)Buw!AS{W)wGdQEC;noa_2jxa#VrS)%`7cBAhta>fy%PQ z`Dg94?LOpIciX}-mR6A_X$aMp9ENpx#^5qc7q>N;SDS|2Q^m^Sph;uM7pUzzdOl%E zjm))|;hK@f?L7%R35PiN6C||SAVbT5w8BI`!w&HPQs@el@CkVER1otU&X0AdkA!&maGz>8zsKXrMJ3AV6@ZxCYna?(XjHUYz3E;x5JAonXaXiaW)j z6n7~UiroD7uKSvYgvCr|CgeMObClDe+&iZ1sstKH{P*Z_DqNBw&FNscc3dH<2)OfeBG8CE-K)Lao zi}#0CS@IWglLS-0`I@6PCq!JaAI!@|0F~$Ps+t?0Y5|v*7XriINC0vAc-BJT&pw~o z$KJP3{=xT>Bxs$!oz5F=1^+tkAUFw;T%o0!F+%e;1mXY&pAnlx`zY>20RJgU&(2D# z6pR{UBr>S5`=*?Dg*?!R%t)DbB%s}Al+c#sJ*=5xmO`2WDO1}UDgDb3INRe(ZiNPc zrpjGMoz(AMvV`v9I-lzs{=&j ziTzaeugLtptT}*2? zv(D^pp)h6CBi7`E|_1c3DmY8AMHXgYSx1_5qh8!t(t-%z<*Dy1D*^c6ls2 z#X8&_0UM*h0!7Cu+Zd}^RC=7Bd``n!vJ)souDj_gIls&6rq-C>cDZv}i>*Zebx&Tk z*RpC=UBbaRH-SQOPjAnX!o1M|OYwe-AD4I)a=L|^cZCdFKbkl?JXAG5EFiQSSe|?y ztBZ;z+r#AJJ?0b0XOl>1LeJt|rmRx>WS#dXc@kKNTaX*Ix0_?yeKOFn!-#$<>eABN zLqHu@L?W&)CgCS)mX4zA!!q{|jlyMn?o-5CzXKam2vDMbJCf|>W#?7d&-EP%1%)l( zh3TO07qCM*0*a) z*kgo`Il+$L3FMV8)HWT;-U~E)cCBn}@ug%K_$ap+8mE`@4Z;jx-07m8jm4;eA1c(r1z;mx?5Kw5=JJr{FS3@hYB&`i4l%6Nz*qO!hT z8Lcfo0H@8{F5D$(5v$Ehtpq8mdIx0+`kb7I!$gjUmE4jqQFSIIJ;~L`p>QP0PZ3o> z?jHsTFb~AYg!F96RDOd;J<$pWpdcn852R;@alIs>j5o(^nw#bW{ZvsXavfK6!(UM)E7R8zCU&KJuh1-KIK;A-^ZmExSxr>TiWoz6`TDU zpKi2~Xj@A*rorObrPQEahJaEWp0bk*YM?c{i64J!cmsQdJYD@WdasuoB5Xx)4&BF7 zj=Jxq3*P&ep>5ip8z$4v-6_t!Vc+9>fHW1@9Kj2*{g7OfE&N7n&vlEQO7ojpywD;x zpfvg{RjGKI8)r}tF1Y!J?T4({* zGw*E4xRj;4(8X`&pmQtT#yd4dxpuUZ!RBjL{1+7B%syAE{4X{BelUNtXuC`I%-BiL z7n$?UrlZ03#>@sSlmw`V(6n?C0-bJS4rXtuuYw|pN70~Jb@%|qWOK(h2{M=pCX8r` zSTD|rDqg1KZQUT_=$o`|Rj%}N~KKnmNeu~&p79tyr17**>R{mAIx)`ETtG%U)u z-a0+4Z4=9;T)H|vb~5%8ob;UY)TY0fj@SK)fxDm>%T^2$yD3xVh%Z9z=mx2=m<=UWyR;+pG#6SPY zpu44&n%1RsNU~a7q3Tv&PjB4gqOdukKoO6l7Y3=#{WD*7?H^rD#?e#=XZtmz;Qh(D z;vzyArMV3+;E)5CPC4cgam= z>G>Z&U%F2vjZ?2d6Wvhoh%#p0?(s4b<9rQn=qAfH4}Mkv4&QHXQUO=q)*Q-s_T79E z>0yRJCy5{hrG?>!$c_GXT#uL84+>TWH8nOuF-Ye!B6W9XL1@XjK#A5j-=_=81b*+I6IXCZxEE8GsxI~@hX>6GH(~yxSgD*vMn#IbFed2^L5cHBuyiu43kPZ zg-bqZOKMZ^!{j)FvZ(?z>9Jxk{~;qXb=doE*reRILmn^V(PPrS>Uh$}M?ji`!6O{p3n$c?i*}uBMN<`HTvXR;S+?CnMo;^DR6eVt}B@mh8F8N$Ka?0yQ-5 ztZHTkJ%5UWkwT2fYtyyzA8KvMUhfxuMDEs-?g5=@Hc0YvcQXqgB@Q>}VX|N-pbvz_ zw`#^n`FXT{75TzKos1$b%`^JaP!y)W%= zcTI|hDa>D(;V~T`@gQ(5%^Z$2QW^jh0#r*=V@cqSV4l=K@>j=&lFH>38tDuDKHjRD z3LOxL2JXoEdNwB2iMKHCVhqMZP8tWaua94vCas=kU3I=V^~&xHjbaB}`OZBBSXf9_ z;Ypw&G_+uxlQRiHg~d+*z(9n^(IfTqSI-V?2G{?_fbzOi53(?+D9C@8*heIOK4+fv z>&f>nBx-HjV&9yV8fKncSzV2VXr;Rge`5#wBSFJuZ1X^1K_BKO!Ahh{J5$8?-R9qL z%{=kNJ~1iz<-Z}PiJfpCxHi6vXP4_|Q;D^2C`NF6YOS!?`7H0mzU07PRw|h1l7cHw z759EgQ z@8r8$mLHDFsv8s4(6B;bR4Yi`5OAftjnjzKU(N-0!`lV$@J@;jb zJ<@U>VlWJ_>0lcCRR6wzS4dInu&(FoN#2EG+TzJn@>R2F4M4Cmr<7cZ6b0=CKJU#a zw1#Y7Jc^MPyExaToE-sB^Mp8Y5lpeTBG!px&J;9|2PCB+OA!yCa8!+FM$v4FIB) z#cONznK3hS!iTHpcNHdE==ojc~oj!XBT#uixkKhuvIf zoV~mKy-sXb9z7EJ7kBXf_g$<31&|nY`HcAfdPyF9b@}eOQ1>_Gn*?hVFiZ)6rFLo* zV1cEcVLdrH`E}5R*>IjqEdNNBJg|jGJL6%vQ4*p0JlO!tGTWGOasJG^E6+$Fs~jnv zMjlh&C#e)iNs$=sfso1*H`dPCaQ;VIfAJD02WQO1~{dx4o_|b~aV6&u#P2C!xO^(&e6L z6Nc6=Je#>_LYS3d3dOyiRZ@|);}_2UK$xiux#Xwix~bL7-&g8Q8+f6?bTWlJHYVVA zJ$XQ|O2(7xb-z#V-K*i-1%p=iaa{A>@P1Lw>bA~Bk`^Vj3gqjnuU#P%-ijv~PHmr@ z8wE8-R4jh9ax(<~Zmr=fCPNgX(%=-4D0E}a9>;{Cj3DxK=KByPsWpQMWloMJ_=OP< zr-rocsIjycKe2#$(19Tm;8N9cG0M{(9dyW_Pb1*#3U^IOD8bLP;G{!M_zLl%Qi`o?bc zgvEp!D`IO@->o!g`7ac$gS#OsvNUe|@04g}hF?+Y;>>5PDn4TkU!6V@pI2JYh0@Q=JutI~0gw zNW#s86%Q-VRPb0ak_SdgvziPh0jVgkROzyN?Sph6Aj z3!D@+Ekx5Ou1E-2Y4TJ>c7y}Fl3h`O31{XZj=`U{(EBeqnceBAEzR=!^pt`6o3;Kj zmewMqZ5|}p!psDlriQEpV4qxob%o7@qsas)VTZ68J!0IY&NFPZ=iOH8O0>fvX_dwQe*su5PPcg`$sOvQ)GYE1xFc?(!nZk>6Y1j? z!oXO5nUURT&gO8FN@CPsTtGDT79v_l8UinI0EyXlu}M-181@Kr&JPc~lbFjaI2~)_ zWb`P8|1gV}L2&+P<&NsIu>D$zr=X8La0H<-91`?6r8@4Qg?|-uE;!4eLs+45ou+IL zj^A25DL!rM`=u2LHAe=`4$TU^k=Fd!r{7rUsFnnl24wd)cS$J#pk&wA63(ODOaVLz zf3n~JYcHDF+te9Bj5apO3KV;EdDx!&u$|}SSEL6zn$19RR9SY0DOy(!*l?W$BJ*X8 zYsLHR083|EYXT0|pRjTuT%;&q(E=SkjXaVyl9U=Ob{QsL!R&r7y$Oh02e_i^BFP?ZhlOdKF2vosnL7O)(W&i4B_!VT|&7o`bgVqH#;36{H` zOD6JSJ-C_NNPxC9qpV~pWxKo+-(Fq5KbipLVUd=3Fkq=Tcy+iXmmq|QSf51_bmFRG z)TmFJvDMLF&k_(S1`q^gST2mDKwjux@p-;{qa=V`rLWGoTIJZ8%wIyAzpXK%7#v{U zz|rMm38AR6%!^yDmebzIdBK!(YDnj2NwIoQyxwZ}&S$t`{bDsLM7a3p=ESUi6cuOv zM+4EHV~XPwpwf>YZ;X0&jbWOCgbTF%71)s7U#X&#+8lTFKJ$1eN7C~hFuB1EHa zjsA`aOew_V61o4|_cpYXc=jUdsx=u@IF{=3|6gd~jwxZWoZeA6tLBHPLleV%1I@!Wl~ z9USB^Lk5GeLU>ts>Q}n@+`DIQyZ9%^6&RyCFdgKEQfNA6UOBdQsBsE z;X5;B&lG2)J2*9_Sp6#?ouy}0ULp!5ax963J+g4c7#Wfn0|mD9aWl~;)Su{%c;vy< z*6PbmwXHdsGXzReMu?ezEpenkGbb_9p|%XF1#iMPu^(_>lYWM*EvSbMD0uukB9ORu zujwUQzx!-5!E%Sv$c~XmlF}lE^@I-=&> z4kUXo7JGP>PhV*d7Ro!yszjVAYVT`T zq;x!@)nMhAzmTLOlK(s1d7r-g6#RO8v(DCYFMWNlS-2S50!O9p00;>IBLk`Sr@k}U zpkhtU3w6H+NM8g?2!a>p+!P2!!)Yc3=5ivpg@o?(8@`_>##km^PX6jLePdJtFYVJ5 z3mDaZ+?N@ZRM|o}63$-tU%aQ5K{sU&Z1>`%jBAudgb|AH6##tIJPjEdLIg0IqZ{r{ zxU#ED)&_fl;k+ek*abB=hN|ckjd6>Ln!?38O@*5GAt!2-GnJN0?#dy6lb5(t`tgPt zDh^>%Q*ypum@IHlh z)=_Uvjo%i%9vwD)X_$Dbj7bcGa(CluJ(+x*cIiq4Gb0_+Fh?-4Hke4h;lFmfWj=lb7dE!$j7DKv zA2p?$&e06a%axgVV=U!d)k0=Td z*I*RH0N_Cp)h`|SO9N&&p-rURBXOHHa=DNnejFx4 zKVYk7x&YV!K7=rbW1i9hL#>U01&7J1zk)7Sq)xaJ%rHNdMbdq2Z0gx1eG42rJH8X) z;lFi%Y?M2|UQ;*ie?b$@AnTb?$Kg5T)$PFY_*@%Q?F^^4sC)#|3>n;Oql<3cPp#sV zq(L6`eSW9DoZjcIs+OE@_0|p?;;)EY^x*VD6t{z^2pNXS4YErsEC#EmcISM1#HRic z|8eyA75*dNus^r&;VU*Ot&BP~I`61sm;!iKD$Wd0;)(?%4rf8*n!DpaBCd95cpR(m zalELi?p;)d1i5zhRtwj*K4d=_k@t-92pX!e;$kj0DCY>;=Zd9OG+7P$;}oO8z$|D; z$a8a?Qp%?SQ^5?eRGG`89ofDuB@oy3Y(PN*rk-a0LkiBGx?T?*eY&ZpKi$2A_VOZa zh*3ZNh`Q-B4UUcuPP3;MSq=xF&V!+028DL!@>3mS}DT_ zI=Wn>`&Eo$g8D%Oab;FAMJ!p24UUpliUAZFCWmZCoaTyk*j6qaxI`V1CTz!sx7eI7 zbiYp?6PWn6(YNLIEN^HwX>nuO}Ai(rQ)6ctpFDC46DSf65ZD0D$5R*= z^{9(V{%c)u`ti7AGROjT2=EjSt88^&xrup1g06a)NG*B7;TAkI;@ z(nIH=vf<70_`D1<%-U{#!qUCnFUObUwFL^u3Vgz%F22xK)RpY>yN#=>eVHbGa%;F-F1)tY{BLCU`I77bG zML|KWpOK0qhl=2+;&Dri1zcUuzQaU#D1$R8|hSFo8>?J^X0} zAyfdMwRe;BRdP^-4FsIwxcD1QEO(O2UT<1SPJ@GS4Q&!w{xZar&!UZz0@LI+;@$WBq+d4qOG_2- zaQ8hfAQeZP{AKiu_p|y%i+G6m)!H{`dHS7D^m$ZSai@>?TVj+2#BIMEts?*HtRJh; ziKkvOf}gM$_n(XyghL)+JZrvE9I>$ha=|(%~s~kh_%ts6&lz&V0 zVmv_@AaOjU6`6ix^o1WuozY=7%u&Ho z5VF*?KB6qem^jT)rJHA-SU24e5DaKh5L-{ zS@iu=A&FWTt{74hrUN!94LHIY9hTxmJUZz<3OKB49*?7gf@dJQL3xfO=08b*?y&Rp zJYu!APM3GbHKFJgNst7jq!2H}PQhKmC7}SMukRwuUgpumWn};*Jn6zmMWx(6a1NmB z!jA3=fa-5Rhk?8~(2W8Aw<7?(4{S&T$Fa5~fmOcBTgb!D|0Y&gVOhA%*i6(+Sf6Al zQn0$5GbfLU#b3X#bB~;8SqC&JAg#e5$`^lG?o0P1`cw4wiQnO9g45?Z^+AVQu$!_LwTl8MM}rKD8O<*HqJ}3Wj~iaS znoc1R_GT!~D_puy=;CRxel^Zdj>BWL0_ zlG~VkJH3Dv{8iQdJ8uwO#~01&&8tW9?SE0JwNUGNQwNaqZdgE6hs^7+)(0QyrlK$f zxV<#9aBGb^_w<2E$njV1)-=Tbpk|qQ%=rdJ*vhNXHlgo>iT32kAFm@9Sx)fr7#azJ zU%-jgC4pK*d;ZU7rKNHsLt~_as0X2IjNrh$&({NWz8?z`o87ZxEzacW8lFUh;JtGZ zegOO=Lt2Oczs6(=B{d0F#}hv*+)6c4&VKYOO>(^44YjFS7W5HFSxYdhmPNL`oS{NV zUZy*a@BpS?*CZXT%Mb2nZZp!3sTST*V)pv+`To&EV6!WO>nQ#~G*zJ*tEm=Wp9V}f zrI@3QBSizDUnrXei|h^KH11r9wmc?VHm?1)YEwOpJz0Puw}hX4@CS|D>6h1 zK%)kOP4O);=uvQS>#<&6pqn+_^{~qIFxA`zD}_4=UCb(^P-UpPVJPA2jJno&MO)g| zLIZZ3Oho3=Kzr-oKLT~5ecOt28nG45K?G;i3xwGp^S6e?qwsFz`0lAwvH^3Q{`!x0 zPps6=O~o+sI6c_|Xm69=p3b=N9IhUVJqKZ|B++2?V_cb<`pyNr^U+|~kQ-NwtH9rX zs||--*sp@R?Fg*M(zy8SPbX(74*OdIruanmksXI^n)RGzYPJp9+2}?cl3!V?Vb!T{ zXU3p%R-+poL#^hTSojd`rOglpyK0)R^c3Hc0BSI)cyh}U)MGtko^gJDIzu)H3y7j3l*f(B)r8^kj0T7#L zVJ|egT+hMUJ6B`zh9(M#pvN|Ha%Fu^`+&Wb?Yr7y3YYM(BBkn&8kEApI1`}q@`!+n z3cBR1mS`c{(sBNa7R%PX!r*ho89Lvo31}h4E}dyf@Cw!~RgY3qEzcss8{Y=bXzgbb z{}vNOF&1}u0Lc%OY-|L!MXZ_CnEt(C7;D6mvBxXDRGtqr%0wPXFfwC*>m|^)n!V(0=vzXU4nirm*?t zIC(v-C-Ga(E!%m&G!I7@)S6Bb!-*ezU(yXYBLQ;cmBpWK!L61GJ*uSBRe{!csViM8 z7ig{*vGe;>Y9*KUm3{0#A00T6Gn(=yTvkXp;04ltnk#Rn4LdZi{cwBeFNfPgq@t2P z72qu%#|qr)zoBmmBVxL~UbLA`)O)!eal_lRq!jB38vtt5`%omdj>l552yi06nK;%V zFiJi3eqvAzG^Tm9Y7*f4HCj-$aXmFMv#VL|!}=A~_1HGB{Krk(bVfclwIvCKAQWU6_r&5?a*y+6P0FLUH8o7S4^FRVG+X*jSsX;xX;~$LKP8s^yH8 zOndT`sW-Q!CJh{G-ume{!wk$VYTPVW4s}?tmy@9O zA*e@T;?Vw~i7@c!uSsn^TZNc3E0GaFa)m5V%G~GVv*4(rH-e34?{TBXe-SSa_D^If zsYQDeTzG)lUtpwI*JlA_YkjC4C&Qxii1^EqLW_%ItGaK+qJ936S8w9hN$V4o zfigw|1v&0)n&RkZ?~3WE0&JFCQS>)1h)UC9Sp5^ro9b@7twx~oa%d6Om$l@=#Gd+U zl@ExWZ)9PRj= zjTN(HDy_T^p#X}qT%}QI^|g=oA}wAfZ`KR0ce&QF5b6u zlqw?xOG8fSiChYOku32GCN$PVp_Kwag0f!lmrLd=|AQM4!$UDus59ek>@bM|njV|mr8n2lfVSjk zD_)^0R?PCAxnGV#5(}p8NQ>!sX&jS~fkMQjQ?FEUjQ#xWh-a3oUw-)%sMU^nGJB|}5k{OsKJ^AXdk4k}A7GcqJ~(nfu70t~iwnoME{y*P z71?K(L$gr{aFk4%B*L5v-L^E;z61TQtxn?Ob3{d)l*eHfA(QiyCF;tQ1T~0?iju1= zAvh>G`uh3`OgA%YA9&`+wL{g)M2q&@SC2=Bhn}X5^%D_r0=kvt;(&Euv}ZW$00-$h zW5#(;0n&IG`IJ)oP6rISvZ*@@Au?P26=#rehI*g{oS6EVvRYFE*69WUr7E<<@HfbrRS_$zfi%BLr4-w%b1A=nXefB zBRAeaxIMLzQBF=}(d>9r#3J9U`LmRw=#@1O_NZ`RvN;afm5~{&^N*lTo>9&<{FquN z5j)A+ukz)-=m7a_8}lu&BI^?+^3+ml>5WzHkJ=qaynI@<(kzk3xHAsMfLI8DDinR; zQ%>blUUp}sRKh4ph=faa`|tgsD=Ux}|Gh?>s<*1?)L&M9Is#}&L0KgTGxP|gRopvA zB!;}gPCy9aWhNCB-Bm_^uT2g&)zCUB=(Dml;7TX(*~XeE_KiGMrv-8mVg2u}g;Mh% z0Ru8v093vNg>M+js2Ifvs2F974Imvq5ilj_w-m9>f1ws5%;Li1VbjVFZfOWxU8#&L zivp3&u;;EGp%(q96*1}+kth&QKKtIU2igoag8ezr7}zZe+rR1RB9wIxVU}02U5_?- zK}Uh8(@8~umA`sO;?iS>DiF3TQHSY&aZ1K%+yes2nf_ZDG3;K=3aril<(vW@+EbI} zQNR4&`Y)JiC_XBDKr9OAklmGL&#DoMJ5sn)0UJ?>*^s^KrCfkjgG&D3#A1 z9(0+5ksDfNo;*A}oG2ziMWDh0=auR#+r=gUldP+7IpwiO%qgV;7+3SA+!;0Xq1|%f z_*I8|r$LYwNmhB4gwlyF-@@UM!Fp@ulS*<_P+tM9eb*XVD3$@GREG6t6nCV|K!Zfo zo>`@Y2PL+4_E^nlx~UflrA1FZ5=Q)VjW7fM&1k4**#qn2Bovy+w9X<5(?-Dy*uhU! z1_9DisEQYAWj1@TVW!gcqWE}uza1?ypRLtY2~H*=j1-u#X@225%Xi{O_uBQ$Q$TO# z(mYEaw9S@dn1pC)pv05z*{B`RJAOGmMiZWNpo@bSE9A)h!MMLy>$?18iIZ6Sv^-Ue z_58DQAme9vdG`fApY#{ep#1s%}EK z9N!O50qrl~(DBSxW{h^BXgZ3Nv=6@Aeq7CYOWc5v!^8#6g`C=OuD@*2)j15yoF|gV zp?SRnrC<8(y=@kj{5hj*{u*TsWD{f2ST;=SLBDW-OmOtAt3;tHOeZ~o3H7mc=K4Is zZ~pVWT2s7r1$nRLyQpr*eTE{QeP@&HXWPHt5{A}Hi-;f)UB0Kq#ooAe%oi9xS@E{8 z1@j!_qcTPN$3bH|5%@x~mn#JcRJ;^$6-4>+SghS5a9J1K2uaQ(6UmHM!x`@E%iEt^ z3uXI~@7Nn}+I=W2KOJeEd2a0DD~ix}bPm>RrWOel*-r@)2jRH|JLE8JHv;3oUKD1B zG<=Bq-1Yp?X?iQp2tq23eEfj`Mces-$`E=eBiL4*<6(4BK9+N{FG@(=NG);Jc!@E; z2o_4JpgUl1tvbbNRK#`x>(2jd0vEaahUQKUm)rxkTfG{cF8iByaz*aR65x$CMqouC zT`VqNq)JDdFmEDo))KDDzczH7I7$$V->>$cJ5bqWM;ftcVul!O8oox^b%w{or3Xki z8)oYdw<8aSw?&pL{9r9f)$)SFeOkvv#Md^6TEVuOLW9MWODUA`xe(&~TaWK}wz6|< zJRSq?6sMmulwJWGjECa|C~)egqywqv+s6T`5?0n_!`a1#Z0xX{$D>f{zl zajRwPbonu00`xy%CmVuHc|*>PD7xS% ziT$@}H`w^`X>U*fP#fX7X#Yfm<)cl&A$Dh(|qZJss_jD5e^ zLyEAao1L=H(`k)Rt%bl>*mXIf%54#OT024+lDgaIH%Xjvc)H}5btOQZZ=aWP57eeF zlD82&jU+NyF(q^o3%<*7wHVWjlPaUM93pgfMXK#IY4(~4ANGFGR}jP9#aN$K^F!R# z8Etmg8be$8+_QQ=4Jo8bhMxWOG>zzD3N$=AW(U z+>hNsr2^cm8e=Nc$i0)OOY6Vh9fF`wP29d$Ct1d(Ks1av-z9Rx?EEQw6t3@BA?p_4 zKjZm^(LNhdy1GWfu%M6b=a%nbq4N$Qs*&nm`B>SU^YF+kq5HY*)m|??-!Wt{kK4`L znW6(rwJBv{v*Vl)UAGKtMw+!d>vYARtK2`?!DrD@!eUkLeXds-+dVBNYggCJ8fZ<( zu2m-By9yg1tZojI*x9%hr3}$7p)~uI+0i!VKud1Non_lKjX1q;@Kt-I@Pu(q@ zel5~^8-v-+u_hw%m_(&@Ye*8AGxuY^&y!L4IWJJWzFC(?-bRKgH*vXJVD6`Wtbq<1 z5Ja$cQrg(?XUAFKVj$3=a^^G=i&bx03lR?}<`8URrvM|&%WmjN0GQ0?+wy!}mtQT@ z`t)@q2)|qGAJ0Q$fE#YaC2ox@}_@>tK(Cw#v zCba_Rcg2J{9aXcrL(ys*9Cc-Bwg5})c!^TQoRb85u8?{Exith;o|cQ<=N$8Otb zfA{jfOf*@Kp03B`$$wA7d%*7%kYPrKi7k-;!;Tj4%tb88AY#q0vy3U+`4U}wd@O|n z6{Uu>aEZ&w*#KBaM>n)b7|L}&#eZrxUCHIFMB3!n z?kQeEr|-^&Ib}uGCTxwqQD%Sz=nu&l@sULQ(Otk`6fwRy0mDo=vtNu`;}Z@eOA4B6 zrn}Ah2~|44;51L2)@DnTBDlj92#gfvsl~RN{ngGn(ibkInMVGF>&|~P8=qNp*FbtR z=HMnrOS{SPr}5SoANj?al$Jc4!oZ}AWk3qJC5LJ`VRgt)Cd~dmQCt71b;>`kyGj9> zf?%*gA4a0-`V^jb!N2*YN##>fNPp?TQs{|SSvXu?pTB=jXcQTJZ*L;|dA6c{nm8g_8#)=MQzWk9K*3mOD z>3x6uH?2w@8Pwo&SZ@qy_6~F$F2;wIJb3~BE_M0XGOQ_`6un0%9}znYh&dc$ zA8G<1;8U5rPiyvk^L5;ES$z%b0Bq}JTWjUB2A-N_hVje-ns?mUPOiTAfv4w|L!pdd zxJ@#i&$v*8Tb1Sbaf=Gm>7Ye?jgQ;9spNBajLp9pC}StscPEI3q#}CJqH648>;v~( ztXUgeb;Rczvirqtv+-!GurCizYo!|W3q zGV~I8qU=T9qi3yf8?J7Rq<7*Mf|+AwBK>aE7!6GBmFC=eUd&2jpG-IRU-0Bez(U@h z6J^;%vgtdCKZtmEQeMMPbiucDvw@c$aNM0}5f2-gCZw|Lt;LVqI?j#jvpt4|A5}b% zUEkU)Dldg$qXbIz(THKSa&!ZaE|=@y?PQNe#9_4lx@S})K!`V3cN~27?@k+L?B8}N zFTNM9w|Q~@E2nB?k;@ZHCKp)|3Gi%R9c;Dm7O$#bQ#DCV|1g58b*s(qRFUmxy_I07 zJ;bAyx*ZA-ClVO>T&H5o9bM~M0^S2U|Y2H;-zqY6nCia1!ypg{WuhLo z3$QiSLlO!+05@~PAJChx z$ahPkzV!(lN6!QVfnGF1#di-VqAL74W=t#q7{|cIIppOAO{BN49+Qe^V{W~0pMb3# zozjXu&xQlT70%0WTIx7D&zJ?BcMg>(kFOc2OXeaoQ*`0AGf{pYqGYK!nj{-KzorZ^ zdC){9L`o^&QjQ~#8y3puEjh% zSSA)y?!#&AI8PzxGVQU8%VBX~jF$Mdp+)|V6BBj5Zh^B*T3xKRasB4&arSjTYqXOj zN_FJKxA=585VjIsCN$H3k@0A0E+RE=j#*-f(9+#7(kB;_vz@?5%ls96#54bsePdh= zutiLL+*0kU4)_%HJks)qQr9(t`}qd*r2$6r_41&IdLGKs<~fJV4jP7tw&&dym^ zww`%Ho+}g5iJ$C*Q1~=s6N+<-#?5n!zmFjdB?TNMRwI*;j9WeZaqTL?2M-XAeDs4d z7F1Upcs+oaNW!0Db5gFH_lJzT zLY~O|_V1UYg~uFuFSySrHNNmh-qgFkoT}gsLUU^Y%k+=hF{@t%W?WZn1Tz1s&HnIe z1@fQ=d@j7T`olnZ+Q2@GD>^QpC?;;!@vbDcZ3s+2D90E$kt*b+DaQv#ibWbHDs{>M8QTYXFldNLq1q2A27a zmhB9E_PtmUlK2_qdBwS0u#Z=$!_I`I|2{0&tm)%}Y4dUomHfW!i@sUzlH^NMGix@m znFzW69*^hU{;T?auL`~Pvi* z`{cB6&n@k4%aqK2>%A`{{?x6WcVD@?plj@RQp4sv@o5+rs*wu3%h~x)oO%8CZA?2V z-?|3{DvgF1^Y|Lye2LTw-a9k=a2^*(j_%`!hI4UW1i zX~;bPEbHzBOtMsCXlInI^G?;v#OgeELPcUJimXVKSH$JnX~ZtyL%&g%z05_5cwV%w zYS%7n9?Ws)E+?DdJtU4lnF`(`rShdQ`o5(&7@Wr^!Z@^rR0 z=D~`b%^2mCm2KYLhY4>oA_dx~fH`I4>r|PbdWHHG$rxZYP-fpmw3kf@R8ADd>6K z+URj>NmFb6-=4tx|74I*nXiF5E>LUhPngA6g60xwM7+Y;ng4l(@>hK6+our))|g*K zkz~&|iH~v&tt(%+Xa+xuq{#>c=B6N6Fu|BH5ap6Is?KELMg7g14R|=MX&_6Kl}|~t zW}qqRhic!dJ(jicD~>AauYN+;8DIom!{J4yThDtBE1@A`kZ}=g*m-nzoWv?rr%dpU7Th)Mv4#ow8K}Z=Amsk+bus+t7VGE5=HQ~ z+-MLsH5?mIQx0~c`|wjcoJ{xStBJIS4-#?p0f){tf{7DOqTAZ}7u#QOb;O^pwdZUj z^^J#0CmJ1_i;cFd1YS3fM0}u!x*lo^!~Cff3Z1~Gfz>Inlxb6iW*eTaxuGi+`n7e9 ztz7{2LtGR>^B~6~Uk1F&4Ql{`l+dRD_nL`Kp)h#eyWHXORtVyY)8GWb`vKtdoyAI>DtT zSHFK!2$Dz*7t?Fa`Y#XSe?+;oL``b_5FGrt_#$hV*18s#6$>1=00RsM?1#tGgr>;lu1$PsR>ZpHkv{yh^{K!;Y zhIZDQoh7jhWB+rGH+`8>+2bLJySea9EY#-@3i1MYUnC)1PC6RfCnhN&azRUNy8Tr7*$_n+n3eA%HpEnso4UbUGn!Um zuHxCQ?}tnsT5Lv_utQF4ew`A=~RCxT;&ytQbdv; z^D3$q!da4rO2r~u@Do!(?`3C?KluctHjRb?gbOZ1{%7~~tPZWh)`{5JlzZQavm|(C zmJRCRW;4>)uTN*up$(6OZUt)F_ypbMDXm|B=(H)5wH)g9&jKUdE%~S&s;U0Zfh&0V z9j@OXioOgu$BWoBLOU_*HdHaJ%`E_vl$OKe+_@Wu!dN?g09%n0H6wI4<@Y-^`GcVb zCe4Hru{3J+ziJzJlzJ9!J0AWqP*7zh8qPW!7jo4dq>gWAcKTP37tWY*Zd1tsEUBis zrSr}i!C)Kd>5os|BZ#_HeoPNIi1^A_OL@DzxqP1oVs%w4i#usvqH+)1s}BR{M9D=1 zD})~!CCF0Sm?ycEq2hQSGLe9vo<0cS1JJwH;eSg&taf}~|GRzRLG5ih+xO+vvI)4> zlxj(Z{~7Y1W`m(d*jT;}fE&z-)9+7kj(A`HcZ*i{?L^mQr{bERQc5@dbIC8~ma{30}-4v&))})e6DBqsITg7@9 z5QjKM^!SyWYQNmay?kJ;?OrRNYUVz`yZOlGAhfi z>)IC~B`pZjEsfIM-QC??(%q?acXx-BG}7G-(jlNXUGi<7Z@dhD2@I|}_qo=ZbIrqN zkR|8e_m)n%jaysV-*|}X`Lc8EZH`?Lfi4EBe#_N!4;)XIcL5qWtHd)8!#Oa)k9+(N zdYD6V<3+gELaJ3L(~rkLNOeemJJ{oo51#(P4Pamt&2E{g#^aSj62bOjYjq0w<4wiz z>zDUfi93|QZ})=f0M~OWW_u24k&KdCknRrhkj-UfQ_Q;m;&(fZP^PMG_US*rl1h95 z9Yd?z&o{+9BJJ>=JeJq_w7NxnT}QQO#41;umOkNgPYDP(mSQFSh8=10@mSOGZGlHlzRU{sllOfsoFE_V0cH zgncf}T@(G|?<5)D{HQg;$81Ve#2)w!qJ1ZME<^|PYfB|P7b^AlQwp zX6WP;EiK&~)WcKeGgsC#`x^D8GIxlht4yL2xgl!)9@F^Ej$o5Mzx9WX-Y<_%(nM~h zf=fhLdyCJrdVz3Q<|gjgRgNR|tUH?DYwq;$5J)!aJ)rp*=QkDJ7Uu5|l`NEaky(jj z^%u9eK3dCQ^L#Cw+4){VR`B{tdFB)fHs^bvey@Iwm`Cr^b=LV+*b<%#cqD+093Q|TPAUpI)27swdL}s;&_O4h?**{JTQQ*C=a92|- z4mmk<@P7m(9|OS5pb}NSeJgY%`Bs%;1UFCp=^sd|R}HOfemz)}v$;BTdMa2Epe7n( zPpvE+s?TxhHor~vq?%XK7FdU{>mSxbM~{pY$A05jl1y(-A~1j`@~|XOH17&bYu$?^ z=9BpreqQUU_#SJC7@H#|IzEr&8ilu}_`#yU8@@1kmVTB^pf?dSTy<+Sv1_r}&Sgw| z%uJQ?opOpW#e1aoUwGMVGleIW`ph4jgi^zpYY|~OX-c`8v_ zW16do7aAaAO4|Fq)&24=_f9nakUAuZ8Dl4kuBJ|N{=H4w#-iu|#qbhC)e1CtF0S%Syu@l*j zSoWT)3kU!Dm|V@3bmxPd-1#@b55x&GlVNmA1OI5T0?`++TD2#1nlCD{v-~%6ViPv3 z)!#zbeFdW>FLLcdF6xSLXz&- zD5Gn4E?8g(tLnlLKY#u#IT~;#Q$tiv(2k6w013UbK(?%10uPu_Et4)2uisv!I1vE? z<`F<&?9_MY4?{s&*)3LYCFJ!0>Tj=Mo%sZwzpqgqJOao|GgXiYy?NYU#jcP^* zha>*iHhjW&=ri%;694(EUfeEKY3YR41^%dVLqpG_9^2nHBRfHZ>+gj$6=Zb#-C>u+ zT7r09(W2F8e`Q#3FY@5Tg@%xoSb1%>9Tsaz=Zkcr5pY5vRvD91Q1-bc0O$!-`KoEwk`kDcBdPR)rIQS_-7k=U%~|M#2#wZ@7|E78A5ZzZ}a5bwV|B z4y`h1J8H>{p~2)%UrTGG!PdzMqt$l4BLgz-+aB-7gTcVSpa47qE(KYXL8scfx8_65 zs~5BXf#5dY$p%{^BT}gZHF&9TG-B}U$G49t;>p*)JZzZB!~Yx=#*%HX11^dqYL=2T zjPfX`+_!?}r38pZzWanU>oQ!8HjHZ_gg_d6;l&y53THT{F7<1355-cfgqF5DbBUMCS7j z4w?nL&<5(L2KtYQh%XstA5K_8XiPun5O^UjOD6p909xU< zg#iB5Ft$XkkPw1k%Dzj6!*boPDEA+`pw#)dzD|G#U(SLwpiHccW5G2!P3uHL^3!hN zOG~_%3@(PtfZg9}`Y{SQ@B&2hGW{2R!~fdW;)vz5BTCX3`2GEv@`xtBik$V=T7uN2 zCl*=6kgshtB}QF+w1M?eA>s(d!K44J{+}Qee0BtORm0Jx4Td!x^nEeLV)|&|6iTQf zD=$EP%rvr&kGKcxuByfmpp_R{g&~+}RcNle9AM?jb${aidR$97eG1~^N1d6|q2mPu zBmRB;@l%^>Zfq}~=b~wV@w{O8|0?G=j z%exQ#RSz2FArF;q3)HbZGAyn7v}0I$QiWmZS22i9^i}8uTNf~KU$ne=R6A?~AoCPH z-Am+Ts!F_Z0U0VN`vw0#%FXo}f)tMwGvP9*^PW(3-t4q_-}n9(RP z@UmxtQ*$zdds9VKt@4g_tbs!6;rSn+p{ZhprdO`DeJQ;uQl}^GmzY?lG&g@6P|!e3 z3qTID6vt*@o1P2<;OrPxg(x0^Hv|7J4ICAnH{{HfQv1(*iHND1KQ<<;PqyR5N z20=B)@0x`g0g}g=MG;AnK=B6YKo}P(89wjiZNDr-E1*2|_r?XhCeHgl-jokQ7hFe2 z3%o)H)CoVzzFKg`v(gj8ui*%s=4r0GK_QTww-*<|*m{ z3&EAFp-emA2qI#_%+Gg+;|tBSKq?FaJv|`b(1-|$S{pZSU6fi`%by`?vJBc5_Alh2 zLSsnMG*)pCB%lMe7bT|v)1>;pCIm?mD8XwR?@n3oUkj2-wMzhZw6&jpd3`&w_BBB|HE{`#d`X@fx0XMk?E z-Wtzg0Atpy$a0Hj>(fr6LNb=L0Ov z3Pe5Ly>Cf)D#mm$!#{O~g2ZRV6-0WgC9hYu>!ovYPDGizhOrlZW%?@Q12-ul$#ZSP z@AEA~OeRDy0HBC20opo7@7Xpi$-P|@!|;*I(7}2=o`DIoeL>SJ9E&0$0Ge)dQ6xG_ ztfKe!VrvTi<7k7&b|Cz}p~sh@7KfJ`V2LQMz;**s+ecuqd++Z5a$D;KLdu^rma_it zeS8OTUHR#7yZ4j|9ol0_a>~rvX9t>OyxR9=O-|{EY@LFH0z#cN%&o-oFrH}JQr*N* zKy5C&?X}WbUoO6$KmzO@9gc&|)e~ph|GWklg!TVOvoHJ|?m>jk=#}qrQxP3e^b1mO z)IJD7$4hprgTC~A%|~8Qga>(4%NLy?sNVVaF~69k z9bgDE9Usc(3VP0cocFES{{$a%R`uPd*|%!})1Sh>|CnB!t*oTvcHi~Bwz=&`l)ZB= z?ZH-nzx<{@Q(Vx73FTdglx|b$`(?f#7pE=AE^3*-1jz|X(om}DBu5;95>ibu zNK#ZxiGbh7k~wG3Gyh;&m9<2DPtCgq9gUdZXF*Nl`EsedhS6fX!%3UOveR0Z!ID8X zubVkEre4Y%YKxd_vTSf*740y2XYZDvB)RI#c7)pRm3;4CyB@!u|sUP3qt97-I$2gU@cG-iJ1Z+?GA<%*=O4r9Fl0BPO#ncel? zxAyy+qYb*Oz)SmR&s|}uM?eBYE>&e3+m4o-Wm-A-B8*8 zh(Hur61Mw14C5P4q3zfOWr6y@3Et~&rs2Q;mJS#o2zTbg-v zX0c^XG9eZ1oNmmbSPTE`n|DE!R9;3rb`WHiexvQnVJMDnE5I=~&=dLm=>-&^5_qCJ zcec}#C><>=&)2EMA@RdBAg$0&6jV%-r+ntKn>3x#T1kBv>;Stjhp-}A1ty7kGIdgZCs}DDE;4g=*jG>f?s|&^8V=0J*`S#@ zBUNHX<;utQirVr@OMmiA1yZaI?ysoj>W7<<3Z>duFn|KHX9F|Qhy)7H=Tmt65l{=2cHdWwt#l_#ey>KQ0eZB}Qt`WtpwK!O_2?ds(Wjs!)YzYB|+r^XyDQ zH8#rn75pJr)kK7lGKGPlZh5HDM6C=Tf&IU=>765Qa`k4{mPHm=a?uuAoy&-$dI{pk zaQuHzE-ugzFq$31IXLW1?THC%5_`i%Og{V_PasA5C{RMNv^-tMP0cKVtXw_s$I(wF zzhBY%MF)7V17i9ycDvP(2+=q*KC*H*aUhEwB-i@v176@OgU+A>*coJKpai8o`%yS_ z0dWvu7v-nNTLdNS*btv1zI&ZXh$&QgN3*Kbc~)=~Or8bxuHm?t%sz1tek#Vxw3q8M z8J`T0)Z4I}Hu+oID>yY{aQ^fJc~AZj^DB4HFGeS7F|Ba-5qDlS?`1EpHAA`3Fs&8I zRcQ_}_xZQQ%hS{g0i;1+K@ZOz;L=_>dgjOhn`G zMhgSOac>JzpZcjKMTwC_*O?sUDAX?=zzy$sA@_ez?WTnD1HctzBIR5J; z|1$y|r**<;o05_H(VscCE1dr@TDDpb zb#&c!0*V;)5mdlR;nITO*>U6>PWkXd&R~Yqy~yOtas1m|g0YhGkZc+FJ3QVBA)wLs+nJjs~F0^ULnMwXB89Zv5eWb9O<1yU1xLP z_EFPn169w>Co?xj7uL>;gA8MVcg0Bubr2))#G?-Nu=@|ZNH%$ykXJTlR<2(+3a^`3 z-X@koIsED!S9#(7IFVZO*}Iy^iova(tT%zlo0%a)q++_d+&T?ztst%mjA| zqahD;FU$vRl)yvEnzn53crjR3!@S&CBcCo^$)dB12)p=~%R`we_yXz4LT0Q9)cU z>o4;WdurPPWkB4!ZZ{lvpo}J#7o+$bl%qHj@<_p6hs5dq{;S4b8$QIj#3 z@DB+R-j|?4vvIX92r$+R_O+Iy;Rrw6LBY|wKd34>n{>SKNG~zXVWg%ZmBpL(GuF*o z^(vT3PUmX5-S&xkqtE|E{jK@ccd^2{lYnu}c0bFLD%anU8ZRW6ExBcc2oAcro_@U3 zaJu2y1Q8yfh5a}3^7v6%8Wdm!>)(CX0C{f9J=@bffPK?=L596(Tk12KrpNknsK!Aa zx6X1uicp@fWAfWmAyp3YDH|=rhHk!kbmTmf0QMAwSB4^h%~?&i+@+X#z7`l~Fs2L zxqTj@RBe#4UzWrkhiWwLZRSPJ&d!oDu!9JHYEg^7S6>>T3z&XP(eB&BoOx}q4z@hO zs>z$`o;8K#f8O1<-y3uO!@5vs0T7+z%MnUEv*Iz^Tevv6ovJHE^& z=;~qY#CJ*0sZsEgvE>_{eE@m2Z$GA*4(GV>eg=WFxm!OxzxeWTQ0qAHD!LVYRxMJH zNafgOvsgGr9_8y}dg@~;>zA89z644phg`Vq+rs_2h@+b|2Z;e#3zwN{S{5zy8NBi3q;wiVH zJJkXcS$T0!c~qLQdRM3%z4j^Yg2jhp0V0JXWy@h)(2QMxX};Qr2nDa%ME(0Hji4?@ z`H6C3gpc&3Eli(T08*nY}7!yeL_>R28_^VO8=Jyp|BcKyIfQ| zFxFe3tk7NQs!aL+ya4GdAL}QixcMuYxsCY7XJibJEc zH#6Vo3z=Y4;zrl;bhJY=#EL5`Tk26XcnSRns)}D5CZ&hrgg=iEWZ0yYZRf zeERvaJjDMU&`fD@prO-rDxeH`iF|kQUz~>s-OC=oVSp(#IK&ou+tdWs`R&my?GGL2 zO;%TCbs1m^3oMUo&wop6E%Jm0y$SI#`D!IDBT{U+?Qnuw31b>-V4}Lwa@Ty$?sn6U zj8_y~q6z!?UEXFuEtiy6rlY%p-OKD%SyyCo$hvIv@wR!fJzEn+8PBH|&B~s7TpAHc zxwkWb9a+=569s04pn?sI0J)7@!1yI_>p3Mit6CjE69r-^m4oMHW->wsVl~ITd8~&o zb@hhkXr1F7d#%&A@g%9NVutfoLULBvgH-PYFme-fTo))y=OrcG%Wim7_QBJ8>gayt zX~fTt0QAY5tV7r_tzTTJPFC^P>n<-F}M2OmE-FK!f{ zzqS8{@NsB7mYSnG2+h(5Lx?XV29G$_3at~5A;TGZGQX}rJQQ_|E6yV04~EYzr3 zZKZd?_Bh;n52_4LiA$ddwUUf4Ax7iAhMK@ebA)UBIUs5`?;4ZDAyA;bVB2l`cQ*ok zH`_D@rq{oU{1Ms0$4i6%TE$ae>u;US|5Cuc69$5WMU7y|NdW!}oLf%e6f~j*vRxwI zFvLg`UYW;$9&TAN_$Tcr>dCKapr`i+!$+1;k1=F&bf0cq5Fx|;68`;3z7lTboo%vw z+3|-&W|y=?;qV@7d-8|jl7jk-^q7J8M!XI*-y;#=4&lKlSDD^?K6iK6Y*@ijnPfS& zBlIC9%o9=oMAk4Y7uL5cfv zlR3rxNYA7eTIJmCM>;sdwTx@4^up>A+%_TI{R6m50F9jGI9=9c5+c@9v4R%;{2dnK>+wpHVb=-r7{) ziXEr_-*j==Hu8`^LD^sVcgT0cF4))|X1|Bz$>0Cu60W*MkAZtW|2A^Oie68*N{D2V z_Q89|ftoGeLJV^Tz^BFbH)$UkAc(|%N55=pJ5wSsNh{W) zIdtreVG`;-!H$4Az2SQc0>%?$=bEUaXf-2n-`gWKqrg3G3FeS2c*zzQ7;6jw5V6Q70w$jxH0|9fWLeydk9t_}p{Su&P(Z}V0oF7li=pLL z^|WT(WH|H+CoaE6YVx=%S=!RRij9&O5iMYeT+luPzL zNY7QDnnQ4?^N)mxBLMYY)N|h`-h+kAvieTg=qG}GLaM1Rlb_S{hLQ*}8Y7dPIGy(* z@Sd=!55m4&zP+T5dz%*PMmb(Vuo*^VM)XxfxBQFqVHN)MAfO{5@I6rufg@3dd6}lJ ztTwdw`6lMd&YXWIBtTtCZdT6R#!V9f>G|u?)WD1>3}TZlw73f&HB8>ZLclJunHi^sl(qjC-0jD-qZLKqkif zmOueaL7m?QY#sN8(GJ= zO5RUCb^#H?V6!`eszwDu?>F!{dNf!%~_J5IwLpgHd=Ap;(-Dv7#6`Z^+ zIbEt%m}6z^W83rW`td_n6fBrthBxiD>@8V#5VxcExG-z!>r+8!ihq6S`Q30k`g|JE zBF&TjHI_(Ec!14j@yd%2yKo>*L#ILYcZ2Oq}~cY=apL?-NgOy79+sX$|~|I zZp83Y8vf)PZw_fh3?(I1ED-)3-P|BS>Vej3d<={VV24-`pWT+Ev&wuay`!e<;pCOw z%mE4jDzf<}4R42vccqDOiT(?fQhWy(f_+fzSuxZ3#9)C_x9wEMOPBq>Y4F*{0T^66%eRR zD!6g<`2m*wM@+LyPE^ym=xFtEiwr^~8-Qqya#3AW@*Td7inKq}DLG635f;GN4R z%e*h6l?hAKBnbYOpnvQ#I@qhBrJ8f-$)7Eo0DJ*<_7k1*xMZUZ!&WJ1q=?BmzK;2J(5|fS#BpPwct5*0(we=VM|dULC1a^3SjL4dNZ7 zk?QK|A?QAoC&1CwZG;`PdjRg~w#(DJAxo#%0JS{0>y$tNTpeF7zeI%?>eT9WxD8Ea zA4Ii+R-N`~VXA|p0)#bb?(l3*d?*6`i>;By8_soDK@6k=k^X5s6U z@rZY=SB3KD4!9LU|33;s3Bw?Obymo#s57}3T^L+uG-kC+CZ!wWi$qakwDWd3$7j&b zeg;Nj6d3Qs#NEr2m66b;5>UhYMI-dPiKjH%+BnO5x*Ik-gr<6SDSjQ z`hXJ0eFl6jMBsLj+<>)^Kd(L~LlY`_d$y*L@`en3gmoh4=Bo6xP7OLBia)vl$of_p z(h^^1tW$w1{k&lCoQ#*OTt*X5H`cIqK_{?!dMk*+E}c#h*`P)wkXKD!f#l-!CAv zmkU4hy*z&Q zjLB=}zyFv?68Ig{!_@~X)4#j(ID%eGrkSDCSUbZ!qD)po!c=!XVjfb(O!%Z?!bIq? zqzW(miC~ga%6haO8U5ssz?j$Dx6lwdczU)KLQRYE0X3{spJ}FZ z5AJv18I+^(O4M!eKw#g9N5 zg7D3~{4$L8eTkJYh5N-nfF4PvOW1#HIV&1VXWx>(e}ABsE0rKR^bog$n&G7cQ>!Lc zZ{5Ttg{kIN;J}+vJ~n%57Ja&ee^ML*Y~#|iu+k*7bF9AqLZ>vA*^4v&b1}P$b4 zG#|#wCVV*V;pV2Pw5=GC2(hnZUEb}USn*PN8V#tr?XLaCMrVN>v-wpL?YRhwiAei= zBj5gVt@P=m83w5^8RobXBVv_$C#q_rE{B)e$nc9;uz8&rJ&=N=4^-lr zhoOSwv$7OBr8&d6h^Wn#|PcsN&_Rphh3DOxiJDKH?^Qo_6Cdeh536G_wb)ehbn zao)kJHtG)0UoIAuAoj)bZvR@$pzEM^clS1{R&c)8ZA`SiKQ1rzxbY%P0Q6rTSt`jk&F{YzVTDG#&^8 zAAnPLmD~kOZ-(#^nEp*Ik`Q#SrX)OiWKS=(j)aKboo~a{L8MiFCe==kLI_GJ z`(Q?pWJ(53hqf}j`e>84t~zD7@Z&%Dm&|fx6n>DRM@wKY#PGV|-hy`$l@XTrCq#1$>N znzlYImD3;MLgClFr#L@^F4A6E_#^T|+19qoTvLsa@b^1SOAhKBXl%SeWe@cRB1uix z@COel{5ipe5qLQ!{4>jVB9_Jtb&b5KDPwCgvgV=pU(po(J#-*~u%!HMf!k3%EV=jN zr?uT(+%S<5K#x_T%U^Il<8q)BBmbOFf^^@a$^Rb9tvZtLSe?spyC+{HeEwuU$IAzT}Uu#j|yM27N5O`c++0oT9hrive zRQz!j#jtP(C4cF2dk(s~Yjt45PA%(r8-fnC_{lQOhzoAsu6Q;ZpdY=a(p4NZ+Kfb# z&F(q;FFCAz8;C9so#|5NF$vF7gCb`CQ@P;Fxf%GS2)BuTi93I~ zQ9Z+h68@X9L>diV9nL}X2R8${tGhL8`Xzrxbcia;pM{wquZRS9l8gp#Jvcgzi6pp2 zG)Mq7dH{Op$~z70{pL_6YQL3L5%pi-&XA>r65)kPyj+I}5xf=hF%I!+n4T7!vq5Tq z8>trf_ZRSx=xJ%iD^rni?S5qe1xLmxa-Cv#3o7x2X)A%v`uwp8jpy`O^a(5ii{ZpV+g&i@@uWOlHooHzVbjHa`tW5MfQyqR)IC|YlE$c-Y$S*jHPn-?1y9htBb zi+N5y#`H4POX3K@m}bvnGV1fNbv%dK)om53%+@05?Vb+{H0T26+xw3Q;uuGMFekKm zEGufYZxEU?zsOb;%B+9YD5R>q8F)$Wxk9h>6`sD{%o6vvzvrsFT~z*lTn16WI3p$e zP}p9g*n6F7jgh?(u^48r#*I{oYfP!MSF3USHxXj$uUB*q79)A57Aj6l`LD}wu%Jb1 z+Gwg#FcPYL9ES9Ku*j+hmZvm)98HfvLcwt6L`oAV zTm1Uk*;CjEFlyh86(|w48%tsMnC+pQc^s0IzQ2$~Yrc*m`UEXs=IyOuZWg}uyOeYTEq zm$>s7#51B>)+85C+lehw@(?X zB7`6ERPPO6huzBKC?H9*u<}(*smh?`pBa;PdU(tvkq#wbn7Cb_Wb6-Hb;bx2$cXDz zG)1@m3d0}okYQ{qGC7mG;^3j?S*r4dWvoz65p|s6y9JgNQNqT2k^m@14r0Vp0kd+csB zi@q+Cq1Fz1YPVqQoj;l*7Q5pJ;{E?(xL*8sHrX^&3%QZ?DlHBkZ(4{ga(!cBC@4r} z0z7E?&=Hm$>$3-z9hv0IqJmXidoliyQ@PnA)SLCQ#ReowORjXO>fyK%*beo|8zHMg z$B=T)|0K~hlqa2TnSKV#XFy**i|T&mns z`ZcDAk$H}wO(CAN#GfcrYN1f~?#Et}R}m0<9H$<6%p0n?5Azn`!((u&EvXuv=8JqOlM z{*xyC`&!Ql8`%ktQ1ibr1dvqbea~Jvsa05yW4dPC~)To>9ZCr`CJ) zLSi%D#79qxe`(AaK~Wb-QWNi+`$=Ln!-F<*u7G%t%ZE}#gvGdo-`T31L9n?{`TfIR5$l z7j?x#5{g8^=iU;bA#uokQ!^ zp7IE(nam`6##SZf;g`@NngU_UO~e1jFQJ@LnMEyq&t`UMwEFLa~tw^ zL!6LhXbenM-C*bV(||-IQ%PCTTJJFqj8yX}dY-@ODDB~*QNg6KQV*C-fe6B9!Li1k z6bo+0pL&yVutkh)T}A_{^SDJMJP`*d3SUyzPMq3B(FVdGXF|B5rm?>*cj5Sr`m5$0 zxpxIc#>chZjlfM!`NqhkhzBAk3p_<)@;X`P`n2rI?+9Z8nXKl3!e|S2skE>$mmU{+Yxn$-FRSH+BX{Ifp0uUKAO|H1y^kv+BP6 zjw|zr$~#3dE{c~k0WlQZ*;P_9+{nZ7pk}UoLcJ1_MAmD^*f%rE$k|KI?%ZKuBm8B{u0BxIDxE4H! z_0d+4{jNp#)TlxR#yd=ph&2Lf)w+Fm5U%YihSgX0Tuv?_fZ^1K8v)()O*$)M?Q=}( z*|wT#25zgK*6(jT`)$4}^WXl$%FVIvv}t{iig^m~=&4ZT>Wz$OTAMCbiEU5+7{S;k zAhjb)AUT8f*-vb-M0YiQA$57IEUV{Ij1L+Fn)8LvK|ALw3(AGpqV}j!>RBZ`Jik+( z>R=o*w^4fo6?x~RUI|0Rwnu54&_M3XM3@!4XG=XKPp^bFyKK1JX`fU?io~*q9@(QK zyqXLdBhkyhX3?V8b2FSJ7#~L7K~JA3&VO?6&0;uJQ2)xWV&rzV z{cTYC{M+0>>d&b0+mDtc{}vsd7ePLO(Ya>paY<>6_`-&}{~_2jeT0A6CeGU6w;4Xx z-A*O3c!Te-$L_UHhPbzYrm}xIj3s8eCrGd!O)sRWe|S-LAFyP=$UoTkH3@y#`v>m( z#Ns2>05(ZeM)(hbDbufqJ0BW_mNT1HN}uGShG_`9#Kl_2-0WGDr{r^!zqk}Fw`6LP zT1Dbjg9MGbG0UL9uvZ-8clX9>CSF&MZ`Z?{ntM?=L>sX^Mao%6ta+um;gH{5p@z?S z$&vPSGyCO|!k>CNi;WZ{cFcqnf1|Q#A__n#e2{ytH=7p0p4#bB_di$fU??c`0@|pZ zhmZRHua<^ww10*GvZpkEvzUXfl!DBp)mu-Zm6=kee2!CVqL5)Pj`PTYRWn2IBmd1bJwyy8+4p-)gEg*Q$V7I#w=o@|dUGoi`-4aAm9MwPyn?EBn> za&j2Fq%C^GkP~?TuFLm{SqnLJ7#S_%uEk=Efb0s=IV(t=%!M=cDy`%`)o;BT?Z^t3 z;q6%xCq2w`O41v2EE%uI;A}jz8rOe|EnQ~%?B5uXidBuyvB8_#@o&HTAr&+v7NZ59 z4qebRJjzWaK8TOvsN^8*S^E%gZ*uzqKlSeks>5E4hC^H<>H@3N#{d#%-^t@-uK!FxNHpC-Ct%>D}3jkqrV>BmNrA&~SW60#z-{M@8lS zq-8{<^>)K-0tf*iq3<>f@uxF@3&cc3|A3GE0qhJ>L@S{krm@45+D|hb zUmNKWmb?qZ;kxyYN`O2BKSm6(=BYClAHDS@7ys;SqZBDWH&o2M&;F*mu3-9uXQB!e zvQn)4|$5;8o%ms z%+1DZHa+>&GmwS{(fp?^Ur!>DzNpQCcULoKmS=^>!4`wmY|o>sG&N#bBlT1c(hjbH zxBAzw{5G9tD?Es8#z9}`Td+r;ne#AT`rb?_NlZ-*IGwj@|DDuA2h~q6aK7L4y>>g1Yc5w<`$H2x%GHop?6%$!U zGMv$JoJU8=qUHl$-4r`}^}yJq`iE&L7AAyy}aku#CkJSPPXsF?cn0$vwobyIkd`RB)pFc<2+lK6!lr$;^R9~^uZtOD5{a*~hzt0AWoJ~mjP`Z=91H|W8y}iA` zUfet%Z5&cLRc9L04frX>3pTk%Vcbnil!sM>p*T1gh6OJ&LQM@SVDW)Q!Slb+w;CV`WMX2X`;y$hv^=wb8f&MZ#{c5^!ohao zNmFDo;vIzk;Bu^^13ccD$D@@>lM=qtx#MD)R7SmaQ?l>uOWW}jr^H8p{y5(LxBuMP zDSiqyWZw}aY#nLdxU#vqx!=h*beNJRACD|4EIRP~{2Uw{{QT@&zr4rAH;fuxV3{#U z{c~m}KHq|kM*+M`;o#|Su5H0s!kbWI=IBoGhIEdlf)^k*Hg-ax9u5BT{)g4ouU|rX z9PhDXpS(I4&N54^z@IW!Qt>#{SFr2P)jnOZb@TDDZKvrefV>yoN;S7Qv(qNyLYIFsAW`?6drOklO9_%bKfaUq)O?nkNgs0iS? zWY4T_ott+<&>ixv*W81>VEVVi^qOv^*Y0A)ikE(l@M(tao%6vjN`b2cV1KkS9B*0l ze<<~T0FK&~iK*t~ktE}R!kG#1XeZ3=2b0@8HnIQui+$>|-AixnH$vJZ{C_l^Wl&sQ z+pGt77~C~@aCorb?oM#`;2JyxcXti$5Zv8egS!W};Bq!^oo{|X6;)8fX0!HMeRp5| zka2B(qBn&yZiBy;>H?hBHVESc!W&*`VRYF=pb)mO%}N)^G4 z2vVL+h|I+N+ggQt6NDtHkr4=0jvFm#Ci}(S2N=!Uct(rohH~Wjb7u(^JetmLFenp7 z4Qi{ZtD9+|(6E+$RmQTmwiZ`bQ>Qu&3#*eL342xg=EH`so z)o01Evb4lfQ~ZvFtsuAcppk52;v-7;A7=_Hq$~>_2l_{wy0eq4h*mNoAz`bPj6wAh zQh|E_0VcUI&_6X&KpQ?|nK&|zU6WNQT_{7>(Al}cF|o3u{mmPW(11wl{X2tOqSm{LfV6{Mt|BqN`CP%--x#;>8_Kg?Scl4ERIvHlr%-6)C5 zxVp;vuBPI!Mouo6d%8g}XnD!4y;z5UWAt1bIt0yV!s9xBY{#uxBRVVe$XTcG# z>FiVx^D&Y~!&5{6Az}wMmS$|CV}gN8Ma|8OF<)#ZO27G+Q0*IA8aQrW5e_>quK|!P z7Z#FLzG=OYxmRWUc?9kfA-ya?SXO?-Rd$WBJY9oLB}63kK{nqWfdEB*VA9n~bW8OQ-48c3)C&`9uY|ZuW;W4p|CX0&OCm?r$-$zpBbg{I3~A@xqiW zam{C~Ka+l{3FHYNolG{Ohp@@%E;r$`+*M6^JGaE0iR7v&V~uJp_+PB>dW4@gJ_L^uiOG_wf>Jdqe5zBN@bugWlQ)BZN2Cn zNcIW1;xpPfm<+|@!n*34^A&SiSmKi1W0og*^W%nc*`wtV? zbHKzk+RGHb1=#mCI}g(*X9@WHolsOYqpKMZgAi}}j^n=~o^+Pgs+E4xs>R&iqjA#v z>yH}QhzCLTbRB|!$RrZ!jwPdR7AA9q$?&I~eR6E3?_e9+)=9n(g@_A%cn?wx!Wd6s zZ|{i=QFL!1`uJu`6zz4>-WP~2zWoC}WdM}7w{_rtAVj_`KFU8%|89<1o*~XYx)a-6 zMnl|#XY}>d>({Ej7fjqsCUP=8;%CBO_6-}C_=TMlx>e%Jz{>qIXAxP5>xC0j=NEML z6sXkBqDTwBN5sJYIMj2Ob?GkuLL-tE=tqf3k&@-0N7Z?Q^Pte;5r#H)ysTHo7Pkqs8w z-bKBfex5lC))F*9f`#fyqYG@|&E-Q7>3s z?TJ`!i2QO7e!`Iez<=}mNf+K%XJ>)zrFDf@?(!TJ#8Z?jZEGPi!!}Wsi;Mou5X9ez z02AkPVOYCWe8(H<)BMu_hxoIow|Vu(RrL4vJt}4ofK+ug^|mbN1t`g%+)O7V z&;x|6Urhw>Oul^iVjlkhJp4RzAfk}*@FR_7?oy;zYk7})dnPGWoG=6;ST3dD?4)6Z z68ZS0#hkooLiLy z#My+~b9nzU1ilg@mXn%F<_P?1(ur-xo-`tYtX0QBED|>rRbeki&g{d}5 zbp^|^ELS-oLq1(o=SV5{(-G9Z4tJZ|q4qq|IRLntQFbNV` z_C3#BZeewH^(u(i0`BhtO|Rp&z(!D9`C|cneMNhFGquGa+n*}sZQ+6zsWSR^{1A@O zm`fFku@NjHJ+kndtZ`e!t2aoqdf4%a^bPyOM#(*|rCV&=d)V*ACp0&<%h*uGgc2T{ zg9%=Ixe7z%cTm6oL0r(2GR4*1^vDJp9*<6~%2=k%E{bf##ul%s`*_XyHp-;X!TS)+ z3=DIZ)PGkVQIE}+C{{|9-&K)VD#)i;E53~4u&3x3a}0X=`Il6XXCa7(QHR!iv^3O0 zN!hwhaSIaz_iTgqtI%^8jd6Kw#p2D*+zP=rSxbZ9eWB=2#fKYyf0(baMQbUv8X$^z z5{ZoI%*5-8hmIJno(v3L4S>T$nNs@g`T2R%#gm)RC%D>o?z8hK**eM$UP}qPQCg2K zNQZ%4Whf6bR+^WGN4^a%hXE5V^wJ*J$DM=80c4NyWq&XHu6U41k-Q0kg8CO;h{{P= zfdI;FBtA`WPC=ZOwp=k3vTFRmXH!%hhk*w+Nq%xEs3e7x6+>dBud#b6Ln|2)ZaK8dlc<*9OL-oa;<%VHa`)lT000rdlHb^S>PR3i|N~Y$MMC7lNiQ66=Wt9c#^&H^FU9E1shp5{?_Di!*xWyMJ$JE zAk?N%KDmemca?{E-((|$K`T_vaxk^&+_Wr)NC>9Cv#{Nk?!i^Xcwa^x+Vi%=UpNzZ zil`qtRBSF7kSZ$ z?Ua-<((#;bDNB=tcHkZ_wswO!z$xX&IH<~Rcsj!BBd8LfNGhg-hhN_Oe z`ivbWsD<6u2R>-#{Vna;zlR*Fnl{*gRXRs(^c0x{*#Kj8bQHf^UbNn0k_dch-F0UT z(6WCx4Pa}my)3?^JAK|_-J_vogf?P*F*E%JDcDY-lHP1rWK~6JS zqmtVUp&2X_hBT-fZ|9B_Cd5Dz$)9ELOey?U?1b=45z!i9RuP_*5B6qDQIkb53@eXE zmM9+QpuNUX%Flx>%^QdibuEX;&QK%Ca8rjqnYo*_ zqZqcvhdNFC#T9DJ_hR2F4?tsoH;muF@(Y{>J& zhVc{b1Y1C=Ae&-fD6wZ8j$MS_K#K?Bb5M!mU^03i?GkE~`J`bc%b*Mj5sf+ip!kOW z7vtCr!zBq98ImqLk zHiZV}JmGauKilL2T;`vZ7LUcC&R!NM#a;YKoJu%ktA9bQx9`<+<@AmmUK>_OX8xN5 zQ6KC!v$H`8J*t)pW>GVQCo|si9|OGUgzyz`GQYqiBOMGo8$sa!2WKBg2pmuCwj_U$ z>_4;b3kX)@J+a7_LQpZT2ecudE(T_1V~Z@G7qVbnv?n=izkO!^4{X4Ea+bHSHyBM} z+)5u7IZbPdf+3F2_Pm{(j~`EexkI~0^^kHTA{fC^o1*Ld!I!x11HfJ%jCvqo)DGYR zv*oDoq>j|6DBQ$1M1wc#FjN?nD^?pKm_ii1fyP@(I{9KZSMP%1CmA^moum$}g${9W z+K`%^yUfgGAu1`md_9(WHmZtF>orUfxSL6a+k1L z6F19Au3ECB%pnU!d@WD@W)-~+(Gr3nt>rAyCE5a(-j zvUDiROJu*IXd*L-o?%YE;QqlJC1>Nqv-LYM&a%YF3kfv8sgDoYl}Hu|z6!=9WOXz= zC?#$(YN)5Vgam|B(yr(Ai#GuA7!&$ohRMDG;z0K;Qw>9U;S-5cC7LmoC83YSnbjCb zEVA-z%lHKiJPtmtTNNjq7pX~c`euX`Q6d7@w^?8@46)hS6dD(E;{HH0X>4)Ou>A0M z=K)yf76*zedY>X|b$GSpA>Ljd`&Vdi(`QyOVVW`QBeJl6`m@c{g~(1$c4ld3Mj@0I z11{n%Ce%)a!6=Xvc=VrY4WcTY_Le9Zbz}%w3t~({m2X+%b$Esmu!?MJuN~7WSdJ=O znI5*WB{?BYhs-7j%qht7K8QZ=JGfnzOzyf2I0moB8p})ktiaCG-%8vHv4a+N2Lbf! z)G*?4?+&fP`)_$ME?d$rL4+3d{a4M0m8pVZl+5IPTPie^dSBhRC`vjfBc8Dz;i;$v6oDEMs`tgtJQ&e2IEq_|rlnLPN6?{8n{c zyd2!YL`!|*{rwzwng*3&ejmis*U|Uq&wvmbC{y}jfAMKLE3~t>j1fQWaAfE|##K)b zjV_*BUtf1CV&SoVo8P&dM|1u1Bp@fuhu0B>G|Fn|8tN~h;Y*4x>6nr8~+=qsKs_SW$<=_Xnn4z)+4u#^p<0oZ~VK@2T!ZtKB6S4AGI+88N- zEVIgb#mdk)e6XVj5F2-U(UEP2=7nI@xF`Qf&g&`X#b&G~BwbVxf{e~Wj{vM<|MTX% zubB6Utp4?=MyE>W=I}8aq-CC0r}LDT?>~)I57~NwX%1 z3|&YFxx)yl7U)^O3>-lExz$KJt@(FZiVVVm9NS_iNUxc(@?3}uZ7ykY(f)lrQ z=4aTi><9Wx^0mQ~hISZx#0TE0K8=1@h(7`YdSZzb^$HN?AhP452@yzS(QrQ;jQ4j< zUF&Pm?|@VN?8Dvbs@Tq?fVHwe*5>s-1uQ*2_Zt?)4VThD;8XBz=$*S+w+#wL=pe0B zoLYaZxs`01(`xN@6_6VN^<`3$#6!&52Z*zMtF(V!&e_qb#|8^7;?xFLy`19XNk4BUu-HXAYLYtV+yhOl2l4(eT(dQ)o3y{KWPJe z!vR>^Ri@QIs5t8EFjf&msbN*saDFA$Tc5s_89Q`HM^9Ta4OsRVp34VyRO{14_+Uht z6}BwYL45QL^&>}Vj2;>(^k4|-ZZRg9O^CD|z7FM40e2u9^`TwXSf-l`^Nq{XJ;c-QX(V`Vc%-G4ayytTcKA&k`VN{#%a~{;&AqR3@Kot^XsR!* zTw`6o29CtN`-iix1>gUO)o4GC`XW4q)3J<|ldC=dlmoW;i#tNgC&a|~J?Pr~oon2h zXU9o)i%Gsio+;L*UQ7_h25_51VtHsFQ3Al1||q*q6{A3?Ee^`N@3HFS-VL-0r)fcPwBDZl6k zhxvQwZdTp$xbBla)_(chlt#zPK6CX+aH{KBLDeV3!oVNGb?AS8_jq=XQ&m(}c3dY_ za}Zgl7ge1|lKLcyh$*X?$ovu0K2iIXN0RudDT11n;rxY3jRuvoVv!OA-)2Xi`?Ee) zu&FL!DN{EXlfAtr?~r@YrD(#S8584otrXg*6zDq9ue!YD)8ZwKv#S=|Lp3XZsXGdE z1Z`*CcNUCAwLt=lukR>F#b9(T0@y+0w-L_opNrli{%K|zVlK%a)h=T}?)^cbRAts^ zmC|-Us>_aV{M+TZ!NIS?$-V_ zWRsVhn?b=5B!%^gAWi)mE-%*vS6kdS+(Eoln5|Ku#-p zEevc`DEA)U{rw=2g&4$Su#q(dd{5?=@6lad4%_|<2i?pz>E<<>E;olW5x5yerDezC z3t#2fK})LFx=Mlgf7{)!c5FCTmzI{+)^5+lrFrS9e@NE@BO6Ty>Vy$MXpA7yQzF{9 zA-un8*4tcP*Bi$@Av^(eSsAnZ5^t^nhDYTXzUyIcfz`D&Ugv}H-@l@X-r9sN6TzBDJ-&}|U<3SR6Fbe^LPkU-eyG zXrRN%obpkbW9Oi*gtKCa*O=(&ag+!h9UW_vANy9tKkxbJXsYJ^-fnFP<*o>{0op7s z7rq-c3ACSBeN)qScXvR&e!Mvx%Y#Rb>Pzd7qq_$NO~4OH>~%hz{Jf9mye%yr#@4tF z%oqClIyyQU8XDMFS3^q@YiDMs$!SIZ?XR!@wfU;9ZrZPj(IeFiEg=eFX>WgVbmY!a z*4Q*fUkIuX!^EQ@iUBWOkg-5EyZoK?7GNH`etEp<@v2ujCTuv_x3^>7AIi(i*qDLw5D-;-TReCAFMI#(`Qkla@kM!#BfVbbo5kVj zN4tqZvjcFA04-cz0Mf7RKL5E{r&v(iy3(pfbKcb}t7)Ot>RX==ZX0SDu!cAam#ziHt%17ZmBLWz#EDm_PcEC(5)>km6Rc(kJUPK zb~jUr&9{=f(KD^~5o)nw(+bP zSs>3XaB%|pHf1ckbav7gD5*te?RZ~CA>pGo@*Hi<>Q79r(qt7WJ?cz^Ze;q zQLbEA!HOpYuL)&gDi>9TZVLuQmc`L)r$Lcuqa20O6^_=fEv-TO^&YiVLo;)VW>;D& zV*zV|xH5RAgkT_Fml)f0cPTVH6u@@e-MJ}a{V6dSsUMI#A3ktEasV?D)aXv zrg@13fLhIrO$7HH5m*si^?)qy*DgM~mT1Fg#)q)xni?Q{snpP+!s>C~9ZYUxVj^m- zr>?Gy6T8X?%!qX2x>jflNB$#;L4k_`+uPf}zmmQ_zaQwm7ttbO{(RfGc+FmTin904 zzp`-E`~Okq-1_|w6dPrY-l>Y-N06{-pys)^g2$5G>(*Ud?p(jv8dzO)RVuYtg zo%)}JUhR$HCwbc+z&J$M>%6Y+Oy*?J<;!R-1;uP@iZgJjKtTO5iD|NK$EmW>?iJpU zN$&QX2L6c!!X%6?8I!P0Rw+|KNA*R;DAab1i1Px45G^)87 zsR_t_ZWotp6v3@9|B*mXQ~{<_&&_1m~Bo=IjrC4}MICPH+}o^b5-UaPF`VU%vE;0S}59vX+|gGskp{GASInvJq1ib#<-eEE9#AES7CwFIh$q$i~Jd zmYD3nZCtd5cd@@}#IZ2=psY zDVXVdV1aD>GQ!aE>RUY&0W?VaWOw&dAz}bR5~8GMzUIt55_%Fb?mi64R@rNt%VcEY z!%@y`4H6c+7;%gR2TTGP)Yx7b*ukZ<`wdVej$8gryPb@q8k z7Co{?8gAK!*8Ca%j8+>}_CS;aEzp-+fkko*q)6gs;uLiOJ1vp}ij114N>sL{pf3#H zlG1qAbGWO4qmoibl7n7rnk^VY^2Eno<-i_^Cb)N9fiYZ*+TV;q$Uo6PKtxslQ*YtM z(M#i^<%5JrP;V!KIN~dO$4ouEJT0V3p|#`5@3#6w>ukO)COZaA&RS$ zFnAx~W0SbRZYl%XdlPGh`q6DoX>^4pt=3q)bt7Dcqhli&tUX_)=3yjP?k7j)j6M7d zGL}dJS6!sWk-$Z@bmlt=`HI9;7AOvD&njuq%c&cNELyEqDG;hX|5Cz8^9% z5-ibKwjYObf}+9=1+?*bbP4kL%Z6F;KWYhpZ$Air0>cx7eHwMXSY}T zm#8kIHO)B==v$<&OQesj4{#W#tFu~h&-y3|0~sDbin@TdAT>cngnR|pSs}Ds=%7@s z&vUKRyx$ou+JbGnjb#rVDZi^327c7_y!x#EkOVP=vqfe$H#sclALuZ_PpPp&kT*vm zI$#?$`zXM_!_v`?Zk;kfkkLk(McSe!w85f(aX+M-OTmL4MZLW>41Gp2XGzzgikvN4 zu9;v9T*`E;85qjZRV%R3O5RqcS1x)Y!uu8|!tNkd zJ7md5E^=)l{4E?Uo!_RMEZ;DDU2o5Ld1?lBeBFOg-IC^a_Fu3@f;&COHL4-6 zOLMkfh4gB}x72p72n(T4w84%R7Kg+a?n9~o0E(TwNt1!Z_hI{kh62DoL&hP+DONT% zeDCUVvIKvqSSrjt$A{o)d2%hxONegs!dEuf@}%(8dJGe+zSyv)ok4_-CQtu%3nOVR z;OW^tXLl;0(9DlDlkN>*$W=4OBEsyhV0l(Q)T8;#_J; zo>7JcEn;D$g27F0a@Bix1%3XQ{k>iSLTI_Cmx1dT9AFiyVJKFJZ+{bSxuPzY1?IcK z<{8}kOrU#M;RCfyo|ZdOx7OWh%&UEn@bK79hT2IymuO}=N;3~xN^PfG7-ao^kjT8O zrH>3=Obyk!zmw9_D6J+L+V~(UvY`9Aw<=$BequMhoS25b$3B1&Y3%G2Ac%_Geg+sM z4*;ujpu$I_|LpASBm8EuF|a^+-0{fFc(G#I-OljCEnjiQG$xHX$$0elXA`8#YVpKcN9PWLIL9&hbcNcyb7lSglz(oc;)@|E$`BT~2ym)U+-o2IM zyCut0haK+uDS0Ib91Y^O+e1WypTxq=i($d@YQ7bsY9QLq!T*0;|X;Vo#N{_;#L{Ue{}M0`UFzZt3Q2*kAdiClG9q*)Nh`w&aE;i*C| zK;6`?Op%HOWq9go`9_Nh`!0|@$ zMn2zwYPf9mOK3m>`Sl$V)7S(*4sT~$J9OLY*|6v&*>MLaYRw%F7n~q-6~ULV#-TeX z%);jps(Zp#gQz%(J0`W(7^a#-nR1l6nY@2u`R3fVZF)>08e5=Jff|F!t^EOE`f+~& z+#E><#rUx{>4V&1Gy+#)-pmn4eRTduLDaZP5Pm9B^V#@Ci7G*CnEx!l0J!Ovb3H$I z%_x8esO`+2IdYxy<1qzL1W}67Nd(R;9G1G`-l)(GavI>3P1A{q={3O4A;NjNwd6=& zlto^YYy{wfZQx%dQ@O_^q9=<#ZMrSJC5Oz9vpK$zmq@JzfH4u~TgCK%16VQ31G15c z@o*EBaALq6wnW33FyvOT1R$Z0SG%Q_r~C)u6xG7Pd`zK)V-Y)vW?H7DSh=5!tvHsran{$$61{&=&B+{{sE=d29FS` zwQ>`N+rpdIPUu>cTD+dhrhIsi{pM~wh&NY#yWa(MQSCbZEdYLyh!16Y{gLiKn9i(< zkNDgWl!`9HZJ+P#;?v+}f(h~aPoZfO>yob4d%B3$*Ufw2Xb~6V4GpSa0Pqt{`p+wi z0)STEaWzOdaWMM96#a;!0sLh-jRs6cwn|VDoZj`w?x0PcP~nV#Cx6{2{^KIamNM`I z#>QD_3kd^BM6jT^lT#fr1l{KDYDCcH<$10m1qz*=mZ{*_4wevHuNkr;PpLFy4A<>e zlvqhMAU6J>r<-d@wb$Qx<>LGnQNccEmLRy;XAQ%HMz=*^U;&l*8qbvEFS$ zqmM?PI(Unq7Q;ah7eCxc)5Hj|H=fq;1XBM*?%Vlxa<_N5!`0|bNRb_0`-#T&Y97?yq!^~ggQYvF*Du!2Oy!=(}$R|{i_yM<-5HH)y`hGSla zKYshZK2i3JhmQiKY_D^x^dbgXP|3*?(3j;6SSp+W6!5JQsbmHg!uP5)5uZ5Z1dRvo zUnn67$*Aq61Jl9CpusIA^CLwvLZFJbTJlIZc>f#(MuZLw zmRfWWEJIZs{U3QD5d`XLMP%jQV18s4OY-vPEYlqe-K`nsXj|A^Xc}}r+d!-k^whkh z$!;A;T3_(D^tf!Y-@*{;+VdlUBDbcQ7J5f!QBK;cSxyKAtYV+#S;p(@qjXU8AAnM} zj}zlM_3l&^P`CDBgX~t+(;<2I%F};WrcxQ^AuwAYoxop$v^;E6v%nV)Y$7I1qs=2;3nk+>+cFQZu|`%euju=M*)_wP_ErhJU_VoHGWxRm4|h z#m$TbBZ#2*Pk+vDb73x_7;Tp!-O1xdWR-uDl@f#{Z_(U0>~`~eO*R}5G7U1$i{GgV zkn^{QAp5DZv(yp90pDWM4t-|4{@W||q>l0; zls*ZSmUSm)dpI8G0YA;LQn{+8U8>TuOTRKhy6}^b`|F3#_w@nLNGv&?&Nko909m}B z$Pi^*i}Qdbsg=aROZ2-MwaaW~`(7fi@9JIE3kRl_1{UmwC^;4y?mosZo%~J3#G!o_ zSP1TNqARvAtv{2D5JoK`pk;iRRfYf?Vp$@xsC5!Zr7F@8tJDpx0~5&1fuHiDY%Bjs zuFhSt(bK@jd{(WSA;ceH z8rMJNBb^?~O+e}oPYCs<%+nQkl%m`u@0KEM7wGzsDEV<@?(VaAQx?;Zi^`14bTami zRVw|!4iL+36lTrS75F_G!jr#}#6a2<4sRRrWxR*bm;I2g7f|G0|9$^`%Yg@1XO006 znu(NaOcL>e<=PF@+n8M#GEge0gd>m$%5S6%|4>+gf*nHN9U9+{j#p2h^LU~)zO~A} zWgo|x;~`#M7CTWkLoSaD6er?Npbf!-*yisf;&9D7HcGwC3oYSG`q0=9u{WYC69NMl zU(Ev(!v`hYuXiV2tF^tCS($IT1^p@5R$JlL1l7uKZxitVHmhq}**RWNipcxSle`sj zr$_7bMCByrYIE5Az^}rG$QZ&a9{fqj&Ifdqo)^_++D{(h;Sq{>RHmEqiaNF6op~Iz$C$=2urvNpxsj$Z{A#{!Woqr z7^CB58=|9Qx?k-8f0pQ9uQ($ndmBzD+NV^gnoBO6&(2=fhEy>~-i8#{;_VPosB#b!#3zYB3b$Dxjg1}9hp@}#kA&dv2KJNYN!xtQB3_LIK{P!2iCwr!kP~XGHzU3gtek$bbsWkZMD<0|L}B zRf<0smM@WlQfO)d&NlfY|Gs8I2uRozTo)E32ASP{T%7Z@A|1mnj!7Y ze>R-uCj-XH0Uha8Kon%;RHoee6+kH;eg_P$i;Ig%y?_c1oERFeR+2RIS~@y>fC6X( zXJ8wp?`5lV!qGZaui^rgu)J+SJN|D^PDAl2{w}Ju_sB>YXZ2uQA+V0W>gNKxvVeYD z&(AcQfo9up?=s2E9MybtwZ4;eWKhxn#(!E|Yu3)3xW$@ly3mRd^y4BPVxR8GPPKAv-4F9voX@D z=NCt_qR?m`v4D*Kior`G&(;%UVv3VY$r}9%DAD&$j88FMBwLweMIQ*D?>xHm(OU%C z^tv8^B4;ujFCEjW#dzQSe;iEHOFm8VtABcI4NmM>8aooBT+`0+A{PJ`d7?94Gc$WLUxAm~k;v>r~AZ21_hy5rW(<@H)ALeot&gfU5qFWvhE_fmah#`w);d1LZz*&0B zXJRO{18q!iPM;JxK6Nofe1%5@a%4bU2yny-^?RLngq*UP1S6{kil~3x2X>ZKU2jh` z{C}mJ)||$GLUnhbvXKb~$ysL1osY8(EAL#dA3}q;RB&iQa&2B=Er0mWj{`+4M$Ve# z-qdz8=*B%;y;a0?8-|MOI{7-gK%;;lVqXa3;`etv_(`592hJ99OiJ56m`I$pQNQ9s_#aw z=gU?mk^ik9UOE!~MriHV7_xDKx@Glaw0G_e>)$bWwD+{S8{blqJe)S7tg$U4EDplcZ>hl}cOFfyWEEJZo8o+s78K7#WiW`zVDVZoI zn%A4N8i0CMOc^IKE-Ikih#@%Q(iT|=-B;qKLTMvw1N1z$3QMYRUDwHWEY%uJq{I%^ z+!Tb0w_!lj+Ea(l`MLs%8)yj3=ze~o$T{+D7VDD!RP+<|iZX zh_+8enN}r4(80~)_Dr10Hz0aaMt`X= ziKpRI6!+W$tQMI){zP$|Xmw0+WwvId=P@UKbP-CAgNE27AnU zbW9h(K+}{hZR*hO{hy`U#9>6+MQ0m-K&&BKTBKyYgtb^*Doki-J#1jn%wRp^0n*Ub zfVYu|2sFSJq(!73KVl-w#jjxJ7(cuLcCULo0}+7zj0KCMwzMTXJ)v8$W%|L^<*%xfeh3j8`_VV*TRsI7OSs(!u z2feegosv6?Bmz-@3;aU?NM` zfB*y{0zn#Ouw9UE!1{bM07TSCNl8B!hS!#ih990e+xM&jSvPn0&`@CfVE$~S^EEcs zz~~tA`#GW&Zx%2o|5OG%8p~8bSmBKVs=wRuG%DAT zr;7{lbtU!vySwE)rKp7<`kfj(y1eb-lcMF#P2e4;%TZfQW%Emup8qe*3J_y~%#m{> z3;I9;dgTiOg<-QTjt)={dgb2U(tyQcXA%A9XbFMsrlrns_hySpQ2M%2(Q@RkbaxjL_+7TXX01KDc4 zGXfP&Xz!P3#3UpT-5VPu6buIuK)!NO-r2>4J7c1L0SFuV-p)ue3wU1ThLE-b<7dFr z4ZNjh!Cu1(k039PMA4LCoW0W!`O6L{L98h#bMMV`^Ar|UNGRM)Kd}By@>lthp(@yw$W-4X3MH%E) zpXT?G>b2;U9Tj6g+?!1)kmg#c;mF9K$ALFA6H{=SVYhwZX zbo0(sMQTjED3uynEktO+mp;K4V3+|52KcgdfcvJb4A_yS7ePR-A6ep19ne!9*_=v9 z_}1H<`SHY}4FvBj@1jMEgMMp{mzO~cng0l2{6#r2$Wu^Mlc|R?`it8U6`3_+01~~y zE<6u@O((EU)#vbrXUX+%xd(SbjaB-9agU;<3f}qEJ#ijLHvs>0qb7qK>EhoMtJ+`H zL}H)V@TmUd=W!sJL>Wu($}d}4TLSgx(XMdb&Y}4-{S*ZHpnyF~OP2G&;nmgE%*?iF ztpG`eKn1A?(WL6!XRdW-!W-C`swEL+;e$iqe1wLE7Lk`Kw;+d$f|1cuQ-eDH2IKc3 zBxYtv$RqQMYo#uE)Mx_T*qbc?;o$t`AZzmtz%zLt^?dl0;Eg*SM*mEd#D2U@swyiT6r63CEq-Hb7q`fTx6sPvinLw1BNwggZtJ+o;Z=fD|fZzLIh+KSfBw! zmzv2tw59E$z<>9DS(6g^qm}VV-lot3d#(rW&d$y?c;#;SFc1Se^mEj*vZWtW z-Hw?k{E0ddTGZ{OY~05Z$kXHOhAVeZZ{5Vg7WvL{`aJB$DMTO%7p(Pb%$j7f>fa!A zNg}Yq!GXAB(j+`!F`YJ($v9szKG8EqZDX0J{UI__SGTpXNu8el=ktXcHBd3sGXHa- z8Wpi5Zd3LC`bX{dVb|6p5a<5!Hg2)ueK3w+IG@ID0W!30H!qUvZ*>WvE2l+bcR9E} zcBdKEN!B((D|NP}jhe7ZAFL;M7^B^>lL>L4`%vzIRd8ZLUW|iDhHihb+v~I0Q?v|S zU3g_#Sy?R(8Nqjl0&yt91v0Q7eolr$@s84?ilHa*jHLycKdlbBf}S!KkmLlyYCj=j z%}t%BPA7o30h|b{e z2xtSYl*`M@*#TKxW<779Iq|&xW)hCn`*KE-^goD*F;g7W<|weYN%P6y)`U`EBeDUs znfNY#_tBUatBNUU_3)P_Ts2mrt0d&a;dLG}khIf{7v@yY!vz4nwWJ$U;mvoiCV#0oEjk`yw>*gy+VUcJH zVye@GB-0)}wgpV^`hRjRES!Pys?>ber%S3BPBOzjjUd-%0n0H@8#o_)EkU>vOBqF? zEIg}2?htdCXjtsGrW;9@x=|&>#V~hf|7^F()vE5oh_N{W^(&7y@^4)#_b6rK7P*Eo9)R55+a{&8VcTVZ>~FJECEk*e2}{`qF={h*%FBjWQgm z{N^qh3_{#yt0)YU*VTMRY;ZfZ&ah**znAIP+Fd`D(j4;XeYu;pB_x*--X^TKW;I+= zC&`0d4h8E_{!I-(6M`3O9v<32)Jir}hqsv*UY(Ae!gVJX_Wfbx_aB(* z%XvHU*FVEh^2mR$AhB=NQ=CU%1ZGS4 zA8ukLM#Xq2oso#A%GtbTJnI zq64DOFeSHu05En8Nm2p!J;28L9q4-aU*QArXBZk90$t7mL)sPV>g^X7WHQJmt;Vr~ z23OShRFZh&D$YUU?g4XQWoQ9{e*rvIQ5580+UrDaZ;&rPWOZ7fX>TkC%l#5qIYZg1 z($Nn+hL{S*Uey+v5nK8qsNeFZ`e>A*=8tU#qxq65Z;R%~vEeZ3B&WQ-p_{hvh-VMI{G42t!XWj3UWD~IMS;tOzRtY8FNT5PRRL+jg}m>Y{hQEn`^{8Erm zbE42+;l^HtN%Ny_>{*cf*TN;%Zz+K@!;lqK_3oOpi|fzf6ypVH`FMOu7OV4e+J!XF zb5BN=)UFXpcTL08LVdCAE@65OjUS=g427^6FAZNEL+5%L>DRbAeX{3Hb^yEcKq!#T zA=~U0a;JxbNiK!mR;iIPKa7;dZ zcXzkzA)<>m{2B-jt2EmT;jeWQd|!VT;!MINo7IMDy_zke9d&c52}ud#b`M^LBUv)F z#Ml#BaF@%*AM~DU8cv=!t*zR4fSxNgrCwM)CR!Jv`u&f7TS_94n=@e$jE*_9;7?1P zuY2qtE6nL5BE^dAIV9rz8R@#(hJn1)EjToB0w;{BmY6S;fbQ zFzm&4gST7!fVHR*wmd15k3C)3(=XjpckzXVh3tP77Wlo9CMKvWTwXb!A#^@#NOP3^ zg-rp=3x?p8p@Q=izw(YT3f__9Z1{u4gx*`EO{0ylHQJ@O@?oFz`NI-5?`4>1Zt}<8 z{o@!qu{ETIa6OC<$bHZ{*@O$VGilhI*PvX;@@VDPG|%k0D5a*kR0;FZ)-!6X?AY7P zg+ax%%P>?D59PIj)JmV+SV3!J?K5QEEDFZ8t z9+kWx0y3J0vb&SuOJoYy7jhrghK*7f?Zr1klXa4eCYQ!n%4095xOE& zRdi-lOF}GfnOUUpZHi|X==xbz$BokBg&`A$Z4IU9yr=Z9JKIh$8rWH&H%e3w#(e{5 zIJU5CQ`xN*X%~z~?or(Kis4IRC_(b3=Eba>51_5Z3~q~!6?W)%s3p-oe1*jlcTOid zc>TEk6Uw$qi>+BRjOUdwuY!Kf8=+h{G|@qPLi6vRM)kfbl?|z!4$;oKynR-(wl@9zCR2yx(g@a3>xD|JIiaUYg?poa4-5rX%Ym2)}ad$25RL-<1i z5i-wA?!EW5Lrfh;mf-kxuW%!qBui-;KlimadISap)Fzqq){BjoOWyKBsf=Kwjb~ZI zsT3CvmkEYYFqQl*AU95>j|zNsB?$6W*rJeOEyOL09-<7PX>5q&X?%@EKq`jsH@lX~ z*DGgiSpGKoEfeajA>X7_9h@8-4O`a> z$;-AQX6`0RX29Dv5#o}gcfDv>(*h>6=lindYiDU8?CFmrq@M0#9$F})@e0eIW?`Bx z8BAfW4kX`S1|(PTrPIYpTWI}?dOUTX6mlsP_p$V&E#N8A7x2GgXM#N*3!lrQ;fTFWWxj0%vHe%cs`6Kq&^9z8R)4wmC1>^tng3BMa7p|Q zwTT1`qT`{{&)^mn&on__@CjQG(^O)HQ9iWiElH2t7=BIWo*m68351K6qFGjpEHDAD z$LT_wC<3_`P)zvE8+yVp)T`j|L}tn#8wG8UKdRWxZ|SQ*4Uh6qEo7KZojFplpb+oN zu1nxa`+L6tee`7;tCp#DnR2&>x=&faVO9-DjQrPWi?ObchJZ9^Mb)T(TwCbtpW%_% zVk1ESxn)K~BhWjYu^$+eTF1?4iZ9x>IM+L2u%E%M{Z;Xt*2MBP_U*eq=Y3=l`*8>< z-vxp&@&Pyf)iEA5p9ZlBnN2*5>pGP8T!s! zc6;Gie@;mC&)Y?)k#N`acJI_*2(X9wSH;a}|30_1?|QpmiBo{9 zHd~{p21&L!)I5B1W4Z}*9pzO;if1e_U^%FPXtgQQa%L(tTyg^C903Yg;{$#h&;_y}_gNL7eZ)7~%}rFj@%R?oAz@2Q(V@3PnznQX~oMYI_7=bWLNX z4UJ7rU3(wG_hjRhyRzpoPndGdPU>)c?>aF+fJS5CGOMa6`T&YB?KVjQ+UD(mPyDuQ z82}+?$QmH$2ym-mpaL@~gQpaOm9;fK2yvyDzaQGpm(N^EsOVGOuwsi+_$XUV^VlL% z-IZ5Y*{qqlqNaQMDLk=h*EC+FHJcD*_WBsFP=r9PwQ zR@xDv?B6Wf#H1g)Ms;U%9dB@H2`l4WtbS3bHsf#&fBmLZYwxe?a}mS=@LEWPZ)X zd7rQqQb}3#sneV|YIv$F%X+!^eJS*I;r|TOrAiAIpY*~JzYZF_mbiD{5dKsSCMY}B zz+x9UuqCz$>;Ln!U^tg6q70O|H}kb{m-_W{`8Olq7bHh&J-jx(u>p8f6PD-_gj>=e zfoe`dK^9w*$sy0%b1B#B=6ED-LUW8O>PBCwP&oFI&=4-M&gzGPZoClDea`v{XM(Mg zU0z94`^ZnC^!nAl+eL!o+O6GXts! zOM;i4(;KV2#`fVnz6NPTuMq(exK%c1wS&4A1T9&mn`>(or|n(KLH~7q{{tr7M?+K) z0TFiHPlxz+tvkqoy5El?WTV>y(0{@K&f)Y5J$4$5{3mmvwhE0zmJ}Z32w0t}PSN-o z%3;+pQ!j1slJ$@#7%34YBH@tq>bL0g)V59QJBCNIlYIgvD>Nl*VyNzub2(J}ax_X{ zEq;s5d-_!b4G4$Jbgp=WVNBo3C_EERHt$?8P#zkpQXvoB0b?SYV7cvp#PE}j-e7mA zOWsTiPcnj0bdK+FbB3-`2=vC0NYd>(_2W|hPsW7yZ-0xK7!ok#uuuQpKK@r5r0}+& z@D}a=@5g`XFS&Wm=qP|nHVI71xw%`3@iFZr+KaZ{rL?Y057ft z%$v*U^js>VAmzBir1&8O4gjXzii`oQ&DIW1_f_b8{-6jDpxOjC%Vctyw9bX>?Ij8e ziVY4WFfTs>FWqlZXMjQW=r7Pnx$LRgA2k$I*o*{wXG~}4^N;bX zYS(Idc`7AE{cxk=;!wkqHwXb5SW($XOzki+O_6JgA3$v?y6W83eu{4FyQ_`m=)}i8 zEY`@o$bb$H^~;Qc7LAs&m()EsPrpe6md|w{A<7d&H$T_osbSz3PnQdB=N6c@`4nvq zCm!8Hyp39D_An66qvrK&sJGr%%`nrPc(aS73WpZq&ErA)=NRNagW>Qq7H=N_+Q|O( z=;Kx4_f_bVkv=929R-~IPE6ag=V@=Y3_rLjba>Fatt zJIH21T=+W_vE0hnt|`S~*GpDA25#-8QBw=}C?a_HLseI^@*J6X>Va!A5eAY`6%s9( z=9;D77g%U{N|FPt_1)AO2T9`YmXAmhu^cyxmNcYxUUHStq|IsY48X@1A$ z`+d#Z>hG5cb3uW;X$WE3yZ=CD@3X*>G$*G)t_UYuTq_kw!Hu0luz$2^GE5w@@5yPv zl4&zw14dE?y&Jj#?b8#NRgPEzJ(QN_serD8nw(&9<5&yTSl!pKfD0PtJSSWWIc+XE z6%DlmyY%^XrSh(iWyM{ho_OqA7VVY>O$L|w7zy%k=I$YQe*c0tIlKh(VkPzpX;`q- zuU(4a19!5S55cMcK^e2!N?B0eI$GG;7FK|xX}GxQs8TsSQY|FNJ%(XSpsl@0A*)QOX54s1a@iB6e=7)=!T`7k;BT;ln}=>{}PdaLQY)5K#LX& zhW;j}(&{~^vC1R>8}R;}f613v7=PvE0&tv+r97|;h(W=BU)8hLOGzP}&i*#y6L8v( zaD8IpU8jlbRc=+RY6VB`SNl_uD6^CmCPlogNj+4X=~sOjKtp5|w6-=@k$qsp7?A{! zl7Je(@x_ymIdxo-&1khkH_$?9S#F-DB>N2ldp6VX8!Nnc*4%#iX}je_{N^?WOK}t) zKhUiCY9bgTFj3k7Ov}s5o2P8l)KX50?q$w(tBG*ciCxZ8!@C zOndji{!m@FM5$r8t=;q>80UTIe)-TOhrgP0ksgkQ4a?xo&ksvcWVk98^9{_>JitBY zAsitYj4GCHP`5`aif8J9jQj7AHE{HM&;UGI!FEsF_pH%kTR6N30&0G^_2#vWt-bE4 zuA^){Yrjgb%JTp2WPWTZe#<5P8s(k6$gn@GZ6oI|P)3 zdBaL}P7djA4xjtsji;T2gsg#V$BNC=)bvX?b>WjwwX2UB(o{l-#_8SjY|%H6!{ugI zvn{(d8`{kFv)9}4EV=R3#fEq9pE8dy1k;1vwZFg~Xr(fA`4a{wV+F7-0Ii!}<(!?I zlqCvD31p+vozz@OQ}HO*cRE^IHLKLe53T`WGii#g^6KLK z?Pcx!et&=e>Iyaa&7o&b(g!KL18~wfDZMjByJ5(KgnfVe?u6oGmezsg)&SM{V;VTW z+4>JQQqJtR=p(pg!?lE-U`jP%w!sI0-3E=OWawjiQGhos4o+IuWLQM=+Bp$lQNv3& zPbI!qBYRkU(c^2m8VItrwH01ytyzGl?X<=Q^nK^ywX?Nzo7>{@#jUO4+-(`{?k&}~ zjoCn(0#S_q%wTLjs;X%K2NgqU)SS6EnD<1wv6dLR1H9xc+5=;VQ7_m#f127v*F+tM^HeP?iZF69f%tEua&HHK?D_xPrkb=yY^t& z$9eD3j^GeIa@%Fm3nc8=tk*R<&U`F=x2Qrb{@57XUA~9+2ESe;QHhJ)PJ(_)qd-~**w>C2tA=GmUX0#Q)z3h zlr`cp)Bw1A+!=fT|BVRbi>IfjPt2WHKp4fTV}q=Zs3_UVrQ($L0_L;J#LpO1r`v(# z@uW`STm0dDSqiv4kp#>b*6{$2<`4hOf^ zec3L*3WG#X_vvgUm77eI!*&hO{@XQC6JqL2Myb-4}hjYDsTkah^7> zy)CQNbF4c&GYaGGPskzc4jzc(5@${0;0CSJ1j9pvUA(-ks$8ibaXW$df3-=-Re0B) zR~HqT@fTuF5v!cOB>ohGA>~?KB2=y0$+Qq1?KtXPm)uRQoP%qUh)`ky44%#&q(1^v zP5heDpHWsvWr=53iBORRhC=#1tWMg+oYefnn={K@&%ElZAE#dCKsFI7 z9l0thT05}h@VKE{uneRZ1&o@ZAGb3h-;PGDwkaXX#TbDiMhySiaN^^lOgIimh=W8$ z!L>_(-w*FsnLvmxkAUCpEl4<>r-Kx*Ee#q$@c%2j-BCujDJE_De=k4`tClrSoy>EF zC!U=P?mFZ?b)L`lxAz^P&hGZzAid86OSr!YK%y=EtM8H2x$v1_Xuq8><72<&NfxOy zFFf4`9)4K@)PDjNY7eN}v;E=n{gFT7E^oVB-%v2e>kvSOP1*%qmf#n61t=Fioc79Y zTq*5Zr31Tw_%JArsIW4Z@ z*3RK7GrRq3fB-Ys5rsx96I4;2W1rQ!ULYc1{7l3?BBY=~rlJ8&YjAy0azyACwiWEaunhZBI<=B@(4m(i|j}hJ`LJwPatMSl0;)RNnWN8sUb9l${se-4QO+ zqQEIaiCFxFOVq4Lk(Ii~Cjw0$$0{d$nwGr{xI7TZ*kCosUDKrw4ER9{R zGoGDFNz9$*?v#LL4AG6svPft};>*bXN5@|hZqhE_Fe=$Z_kl?_J}(*PB=RX#0V58| zbQ2pXCVkKY!RsZ5R&LdB*dt&ohEJ_TVm2vT zjB0};g6dFW5m(lxBTY>FMqT;qhic=xmLbdcL=82YKt;pn#BhX!(_B=RXm&YCpBRd7 z_V`eZ4pibLITWQ7bYs5UkXHl@UyNfc|K#~T_7fkj$bhpa55vRZvL=U`j*;DJ#Uq*V zQ{X|sp>}gbfT&fwO0;O|h@H&(g=l>@rz$3@1ojIOJ=pGZG9s2_fn3e2I%8KW{bywa zEXTBk<3_1pRM=0#lxlmS{MyL>Qd3(;=%hYPeJ$8K%lEq3#zE7 z$l6ZBh6?B~wViJ)wM@UKipfgACwFsh26vqw6!zkaX+>*y6%%9F*OxNqxyC44l*sIR zu)C^@f6wt7^;fV?M?kYZY@1)kIIqjqv_dvTs7F;V`YJ|=Q$R7Oj&`;!D^2)~^V*Jv zZ3^B@ny(FMc5eQJPTQ2D%}mt^Es==j)0SR|u63j}X2UD=->(g>xkzm-ij5!9l#^np z4mf^P?hpU&EE-uL&lX#UJ5MD&qDrx~6au6|&5&56C8P(bK5=nyQIa;QTjDEG#7pw< zv%$V}fAqi!UhPIRLxRW}ZC{4Cx&c32i*0zz%6KG6Dg|jCr5lED4f$F8TY0mG9}h(Q z8XU^_V4|mpaO#;^Lz|^3nMoJIiql`;nT!R)&EtcHi1$xY$n9A!KOJ;u$yT*fN<{_= zj=e*n7fzMsDsi%?=;&hb4AmB@-Ia%Oc}c~$%(VrIgCCgi1TvZ&$SmSD>u)8k_svq4`B}dfYk^% z(@cCMA)n_UNby~X>QfcG!2TPTRkN|Gd!l~8O|uxVAye__nv zT8=CEWIW>@g_bIIh=MSI^BF%1oRn=;6xOTizT6RPiDjD#`j^Q3<17- zq3RaBh>WTc39J^j{;sZfDnfTE|FQnt_3gPIvNmr^0alWfF;ZIB7TuU3yuS0;%qgbF z8~$d`O9^OuwrJiR;1}k-FZ_fDq2ad}AkTd7yjWBiLB6DFgE(dl+rmoA_*z4}^7n7l zQsHAR_Rjz(tiQ*QOMUIJBIqus9E*%I;4Zv`#ANbNb^1e^>DXs?Rf|eBvo95M;THI# z_%9RXve8|ioIBxUmj(hoSy0WeKBAgL`((Ru+@=gwvLz;|+>Gz)96-hN zf9oOLHLCM@S=-9ZA#yt1XmuH9+$8wW0HD!b*Q3->&(nVQPsGpO{+C6>PZ0;srEm3i z#uLFWDA_60WVl;q-Q+Z3f+_l<0!ZQq8kA0B(BC@e{SV>FRIPN42O4n|5wO2GpJQV$ zIY<}apoz{N;W}U%d4qRwX^k}CXESY4%gZ&pR|iqqFWwd{D9q;?`K{G8FZmlqNP9A3 zAMogA#X^Ig7wuk7ueM19l{R~knv~@=(C)^R`@hRjN$`DYkfb(3A^GP%tSYWp3R904 zX_V)Ww~bUAIA<;!6)GwwMIkG|lQ+2Ne`ZV!aO&PxCe1MH#NMVZU#I?K<80Y+`MGCw z*%HUApQgqO-TyHbdM*-b*JScsPHMUrdJq4&67u_a_%Qgm&C{<^_X$IVSlN7E6MAfM z^k?c#nq}TZOePD`>WGrMV@t%a`1Qy$LqEG1?sEh-bfP_NBU@HcCy_oncNte*fXX8^ z3?5>6B6(_CT$_RppEK<(t4 z{(wi&l?)5qgL3bGiAdt-f{#eOCRXGxjm`d-)7=j*?-vhmtH9_BD7MvFTf@=!*a2Xr zEG=g99000WLFn!FTy8L>SH8N=4?52_)5ZyXOW-r!V*#r2Anq@>wS%9!wdhFblAf9H z=?UpYbMV>v@ak3oC#D2RGc>a-BDW3O^l;Q2p^CjI@Jpl!0ZU3Wf+^ULWCe15a<>@q zrSF%Gos@)#iV`GBg$b89{HF>J#MmCh*^+zY=U&=846;C1x;S{H#%({6lRxLGnRJp( z@nOYAOsX}hw0W4i3~|H87CgwK453xyTTr03TBGDx)1|AVh{_V66Po<;3GQQjWreoT z@{4eY_XE)jU^uECGzx@&&(@*%8)+9f`=dOqlrI953J(G32_I%%o39houeS$-l&Cf> z0>U4|{;$ITY?9jV`RB(&(q7W(-QCFvZ659SD&Ky5{jKKnb2$#P>%c+wkhK<8uLh20 z1+wDu1uRHK?HL+{0~dkcH2CDprg^x-;!GBPgPiBv$e0UJUl}7}R57zLT);W>-O6Bb zt|IOtRA`L-@kR$d%b%9AL4wi#KM&={hjcdwFv^jJ7__SDLF?f~l7I6Z4DV~+RRUCh zB|?65kJL1C!G`DJo_ZbBH_t=YY3G{s%b3wMz==qoIMK*u@w64FV^rX?Q53XJNE#*T zPHJH1j(+ZF>Av(oN%K4L1$s1!zQtun6nO4N0ue{xQugy*V(URZYWC{i74r#=DTVig z^1!UY_ZU)Zh-1F)J-+Va=Nl?jyIQp_s0%sQL=R6iM|%FIY31Xx`GJ)H@DMgPhzo!88CK zxu9kJpUx!C1-#Y`!l?-8$x^SLpN?gLR6AG)&73g+{Vbgh+jD?2xBo=uT}@xz=W7!? zIS;&6k)bICdAyeOf!DA8RC7g+Vv|&~7#ll=f%DX72U=y+;YV6s^w9<%m@gn)lQK6U zU3LG(HLLKUGG$B_7}$H?kJp=NA)m*q7QfRLzXJ_FN&&>2T+hSbY(qZJ^Lh7hy@P5$ zmR74ziTqz3o2Xtyn%hl;xRMUoVs}as4IW$#9&Us_ZiH?&^E~gj_`SW{+E;86$M0Wl zzx-x+2Q;pxW@gfapRy1d}^Q(#5XDASlprm2HeC(D3^oAp06v zXa4{*4yz`%QV5b0Grzaxk4pfWx@D6|b>q+({e1E>&kuM*@eTBee2-J^uCc{RcS@2E z8a~){)-JQ0z^L)r)${)VXjUI@2QPjHzQ3QQ{n>}apaW)HH(LB(TKxaZG63_grb+}w z3+Em0xekKUxym7hbe~=dm|{v;vB1%6;#5y(2B}EP0#~z9_Jf7XmERpb!WgE8WCu&7 zlG?0V`gi*^uTqnR=&E$xx8zVi7>iWDWUKs=_l}p*6kZ`~R-c3{lEYV- zNP1I~Y;tR)A(Et!)km9{l^VPxCPaTNqgh|GWyn>vWSW41CWAIr<_*S~n2@RRx-hSY zqo*N=RNL1g#UrK5C<%oM7)n2Pdx`$fw)oQVdpt=2gsQ7C;^pN<=k#s+)+b?cGvBK| z(_qE;NO%_>^~vF8(CG<~XrJ{i{g(YdrriA=`={RlVB07l1)l%|RA34U%$g4AyLahR z$4w{iEze!>>_QrCg5uG03ktD>g$A#rV?|?3U?O8PPuxovWxGKS>QV?&eg?UMY z^-|88?^Id!pfEjokIr}QQM4Y(3I4?SGoq9l{X%B+%=YAuv=7t|7gWh~GU7Q|g2O~c zS|j3E^bao@wxVlVwI7BbI_Z)B5FL0)oy#9mG-4v?#=8fF*D)xhZT3xl1|$C#LQ8H+ z!M?yLXvh+4pR1oKD^BtNmJ6{-4>?f)W?*)mJ-;Y#>BC#@7%XyX1oh5volysfkI z6&Sj=t=MFil9Fvc4{dN~a1uBUe!A!{(C;2@|D!xlKO*i7s$Qpr|w>CJnuptu^ z2A}Kow+u+2=fMV?o2@l7LL^YiG;Y}0TXwixwyS%51!kuraL}C!hy{n=cW6!Zy!U?)&BkZ zcsx?JqL66-A%`A4whK z5tHM@)2@KuB+jTwA2XppwudsE5nUh{sBU{THMlqB-!X~Fm^8CpYqs5E#=H|G`>ahy z7Pd(ganof7iI+H2&`HXDP9Y49QN4k_6>}NXNQmY8}~8QVpDlE-De3499i# zVp-BVu~GH~ZDBLY`qT)9;wR;^MT4D`n_GP?nkwTU9oPQeI8CyvwOmtKWlmoyxC7k; zw%^hIpC%GZ-59SmXt`nRuT&$;w(p_akdYXY5hFJIqL@mxa{YMn<8dPg=QU&8;ZYt%T z66ssYmp;7k4&m6P|N90|Zh%!u=&=_?Uso5@!{vX&r#CvND;5{sI^NFA^ZbEZ zET7(4HT``d0=@WIS9R1jT4oAVBOq_v>xlE5Q!`%64Iv~vAf)f}>Mw`iu#%e?l3%Qp z;6m3geVKnumu&X6+y`?CT_zW1x&H1 zx}mg>FPgHb#8-bEn!KPz7>h-wNrQ}|kqFtROVE!$VVeB?XKH(|95dw!A*n*A$!xndItRAFNz`*S+_K-w`RtI{!TKA`igVFf4~&piT$0BuLP ze7wBRbIfnb5~KamRUapu&-`>M$BI zwt`aK$R=r-3CQLNL9;}f;daK^o(Kzlay;&rsC?e!yfmI&T-1b-`tSJ0V~qv2>q32n zbwT@lDZ{4;Dm3Rp#fvVNv{+T%& z6Yf^`i$1lDgg>YKi-k=Yp*sE&CW1T1Rw$$cjh59+Dx)Y-0$NqiShxA4erfa1ttAO} zHLwvDt&tWc6`NX*C!+-V`-23u6OlZ2(}tbxR#xfBsya5`*_y62*{Rrg_vK6X(fDRD zjQ{ID4gU8>dWzYdM33gF+?QFbf9H-|1T$-PExubfAWI}46HNZut4L1yR|H6q1ocsd zsK^S;o{c@DR`*N*^S>4E>VMCfH3k8LMhRYH%AeVYQRmPgHDylkT$f$PT>qA6V2C1? zdGEPhwr8;P9;YOCPR56+m!&nib!?z39l_R#vARAbU96UjNpU3_Ku;nHuxadM> z2dMCw%_5@4vQvW$kf^!}WYC3oUXu_8^Bk)qvVB;IG=1J+vbBdL?Vkqk7=1mmv4=6X z_TFnyBBjM_lQZ}z>-w;>9CH0hr`ov1=;Bi}9hyd6`uN7Mur@Rw)U|@>Vqo7b4B=(h z`ZRV{8jwE)FFtWM3Rns=Xl3SDb0IS)t@qq)+*k>QwJosg3I5<8T>l+>JYt7=&)(B{Q zW%Q9rd##ik)F9|m)(3;u>C_7V?z$`uag|_JyJ5%7%>3M)H+`hXwWpu0kcg*8LkZjE zefsjgyL%1XCGaTfuDE!96(k}G-Zw4*iA;Es6rC9}c<rFNSI0>UK{L>+0UliB86ec$!1<_P|7ryh3xAq4F5%|m z6C2Xv_T5L~ahJ@2-{=r9X za12$dSHPhVyV-glJ$kU_h5vYQSo@|hVqH*ax;M`;36#fj3D#}-#IY&Ew9y8V-uCAQo_ zBcN&(agU&B!CfhEms4c<8Voi8p2_m5+;UT#zzol9$^c0V*NNaAS z;BGT&1Ai{mIbj-rKoy)YjBbjQzzRKn>Yl2qbUu0UYgnmVUVi80)qgT1MJokGsvWW- z|91|ubozBVfXWh1JEz{iR~wMFmrqa6-THH4W=bO@Tt#8nO7mJrubXjC@E(Jo!N$5( z)qTQDNKC8Al!_t>_AlpdS!eF~yw>w@c$i~ei^jCFbQyO$xSxPY2KnVzup_q=Oa(56 z#5R_Y2zevv@NNO9T5{`QZIaWzMyf7k7z!jTi*#DnuXs#GXH*)5V1AeJaCIFd#|ZfTQhtXUA=4(Ip#kXcUNNj< zJ%py%ePd%d@a4PY4DnWbDT^dVTlOt$-MbECeGZsE+lNem7lJG6+-+Rw<{gzfZ_;d- znp$t|nxt5jo#OM)Z#>)SpHa6TA2pe+fyF;{Vl@A_OA|29vZ;!=DhiV16m$Hu8DBvXgX6-P1WeaTxid$cKab;DGeA`*m9d>qq)et~lU^zX z50!%c3$JenM65Q4)&`4uh(L4~fec9%kuKJ%`M9~yUTirtHJa7lS&^7gL47uY9p0Br zpb4`EiZANqa}>Jr-vJv8NBj@O&pOD9p1?jkb@8|44!m14k_k=O@UXej5%K4G_ng%g z&|c5`f=d8jiKv-w^cW{03|N;b6(HPi_pF|fw2xHSjKwBLwCXZtHQTPaExB@7P{MXn z#)Sj0=MmBifgarc3ClIkDh+f@V;`Di>`3^S-UBBdKv5PU&QysP%C5k$I@|{Q6YE^A zR)urtwklmAmOU~ur6rTMw5eecfkZz}P2(JXw$ZOpq7XK*ETZUFesgTL1(uZTTjzL3 zi3jYil+Mq8D(FAQl7UX;6K;>nAd1a{)V!Ih z-v?2I3@8zm2K2=ko^%y~RGD`L7@f1S`P}YK3 z`=1Bhh_Ql{4kBg=gYylEgo7fyk>txgTqv=4DOAC*<+JH4A6C=9BH`ORU@rsLG_ha}15Fj2P(?Ll`l$ z4_u;4O?JU#Gx63zZ@*^$VLN!S#Zt@N-OQi(JNhX{d?K~oq+P2JRetKjH8IQ%PluvC zf5SKGGNZ!p5uy|6#w^{0g0V)#14}g1qZDZ`My#gfM_8Kv4>7I%4nkh*Q~B!kVt7&6 zy|pOAp>0*;3rR0L+u*JTf=P?FNtXU-j)^UY`7aI|*m49dLDv%8khu-_9S? z$x=SITx^0wd+2y{wVmF>J0Gf*l%D@)hq5)XRK&yoc!>iXw|+vpvCo0+$ikaQ2)T2x z`S*g%nPM9{|5{0YI={Zu*B33O{lkW4hN$kK`c|?#p$l)VOx=>kH5jAe`x~am!O$in zp9O*q`BClA5#Olk50c0|VS-aMY7d_(7hE#*Dw``AtKc@tmU7*eSkGQ~HgfF0FmT6H zVSXvBr@FY|e0Y4pzWXiVD70;(JLZ|5{`bGJ&-?RK((b zp)r#3W&(Nkr(=`wu4bl;0ihfx7qN~PN1GBybs&FK+r=AZe0iI z$O!WSnWq8&uYeTdOsz2+U%j+WRWrL8gvJQC0UYUTn)Ekmu-`e_|9b&Av0;so9yVuO z2UTzqu!YsU;F181|)t4Z7m)j z#!=vvrySN?Xq^|fl zA%6ObLz9>aDwC2GXwIoU^PdZhA!&}FVm4C;it_s~Z6T*^mf_+SCrVe5ec6vKE2Z%- z9@8uSW&JlIu7=N&hA}|r^vfmxUTqi(+=%?bsN>?OcOb4 z_3err{t9GDZEG6l@N_}(ygx~NQWl{K7~_SWd|aSmBGf;oGHE#-L^qX0Z9KjIM*9gD zwbg3>0bN9Jm>xSN6)G|1sm%nM?Xh{E+FF!TotAOTY4mTkkB$ch=hm~MeVksS7 zf+gc=m64o`6wEKBj{F^((LczCODDrrg>i|f3R@IbDF1x88tn$k!bI>;d zdsft9wn5Xeqs!}uhecBBkbOiLt?dy-!a{P!5;6v@N<3K!sa&tF8ktdf4zvWcO|n0U zK1?Y=R(whI@>h;6+pLXB59+gb_tFT##xufFCe{slj%3~)w zXgI?%&GJS>ECeBZ7#{2jp#Q{cTZAro!ayB!(s-5KL|`J+)Xde;f&9{qK9H-0)Xz$B zBjCJ+x#A^5QtLyB3lX4mEr|F0Xp^>I;aQ6;QmMNnl7i~G)I*mm zsstFYepkXVDkWC+9Rg|uD@0b=F3D`v?kdDPYkHc+zhqta%aF%~MDEqK?el`K?YU}3 zK^}gF%KNw6eE6WJ`UnOOeu0Nb6B;^g2_cB8pKPdnu9x zqIX2MdXfYCvo$vIo8}4_h=kS4po1|!NFWtb3}1N75v$a)e6JOf)uzvLAYxg)At@PZ zFfhGSL?9q`SmggTZ(8VSIWJQgi8%A>A5Z|laq0H}$T7s5=1DrP--qLI*BdL~;_cKw zT`(pyy;<0%`0HB<$Zb8u5eYy#JcJPt5p@GSP}4u~jNvA59yUACMrXqZn(}mHNPn7niJ5%GkEu+~)0E5a#$)pDq_w!J zcnJcbV$z*=8LDy2pSz&DDH7 z*L(npE|}t}p#rdMI16b7l6&f7Qu?rH28422yXXC$gd-KvC5`XwSl z!nZyD*WUm`xrQCK-%(mn!|bO^Ly5j^k`rTOo>eaRSa)*S;y|_`M!dX}f%3RYjINZ{ zxc;}XJ94`X} zS&8hRhF6ESFe}kiu+5A}HaTQwG8NT$mqs)O^r~4D=fXf*L=>{$ESzpg)_CkXqUV4CW1Z1~`RY zOE%q#4hRrPXrT=dz0-EU+@|~E?b06*ewno(mDq%x?GG>|^z>@u*T_7ruK!|q(;W)P z85<4Cq^!be4F!+3*29w>B7a+p_c)0aNhN2VMJsBSxmI?L?t@g%lr5Hsz*{%?dY?-0 zLsLohW=Nl@z|rUzWa5<+tJ-x*Uljs8Rd0Yd{z3}_>|LJX@g38(Cq9X9mN)9&9vj|< zbcQxF*4}Ar2phr-wI{cw&+h}B?t=&akB5en>TS@U?Vw{P1mzw+{?i-M#|##lA!?|@ zRih-9`r$}ZYK0PAzgekn>ANoFZ0~z+`d>aNEli`Yg?+rR(O~F zIxq@3vB}#1+(S!l<+tpKh`yO9G8$$Dwd z{!I72n|#_S!+P|nV)y;;pPG^hRB`m~%CsAaW_0|d5>wZ-w>U9QH7n(XS4@7zd}f$K zIJeDGW3Dt1G~+zIhrhDFovSp(+MR8ZWm>^L6Xe_ujXt z+OXmD`E79Sr*svbV2+OdN?<@Q{Vv_*P?761ed6gl>eiuGv;2w`f)9U@D#Ti;PJcrE z2w5;bK7N$z&D6PX$rx&9?hZfVO^EZWkaApxEcOJD8Qj)xQYLr4)2>j1!N%*k*r||Y zkdWQBK2D#&)ZdXHIo9o|3cG)fTk?zdOjyDwzB>}5qMs*1cMvs@jDY8UiIjlSetwrI9XW0Ylo zV}cz_G0S=)u_9UANwTc3KrWS6mgT{`$!AQtq^77Zbp=}tO8n7DfUnx2Vw%bjd-gZ5wTDCymXG z)7VC1+h}Z~Nt&jylQ+Nj&YN@guRS|Ev-j?u@BM!CX`h64&{Dq5;;A$0=ked(pBldU z#Slqt1S;3Fxh!Pz8381+yaW@x5wBs6&T49s!wO}RgAZnJe^^)-QvSk5Zz>p;akU4r zCf(w)2=JFuDCpW2&N!x`4k}Y78QYnOR+QbIA%wey(|^&fP#=CuRri6qqbQt1u~dmb z%r1?3<1$XjP^j-s@yc@gCjmn@T|7?_ z3)3q%s&m~NB_bm(Y^6SdkBJG>sf(<8ZHt#ES}nmPh7Q?Qq=*puB}N??BIciKPvlj{ zgnJEs@XxKUrK-r5)z`d{JDz64^?MK@rIeC`A^yN zguqi*0&VaDBIGWZqunefa>%GXo%RdtHx46@oJoGH_|YLJ)_a%ZwL)tQHhU@U}e)-AD+&yiphEwpMEff ztjzTVwW)lzOG`$fhGP1#7NazKCT>=6BR%>ht#O!I63)&ji=Spwx;4+Pyg>pi>fAZ{0Jm;`0xq@ZevEw^z>$j`8D+nzz)H;o{XTZBZ#jX2OqFO&G%>JouK8_#$@b zL6@WynL=J|^+}-OLi2cdvZNuy$}~s0@~wN+nu>!T_pl49CuRz|@?jE6H{MYA1`su!preuQ}v zRB(ijU2=&eOAo)0QOH=-G#7Q|-m-;;Pe6K*>p>}Ms%Gg?KwL|iAVy7Lg}plEA`hyy9}GK)#J@+y=l!V5nce^I<37{U1U!mpQ#k@} zp`h;O^ScgKKy0nNfBJjbVBzauviD89Akgx9ezC%=3Fm~!XF7rES}piKDfa|@fsoC6|5+D&rGm;E zZ3xoud%%Tbz`Xxtg9)KtuU-KFs+*^-bH3Y$i@&?de)X>I?#+5Nv8*@k{B%R#hIuF< z7hZaLJ37o}-MqZUB7#DXsMK>rRa$_@7;v=MCnO~37ewS#Z_i_RjgNnA=HnMWUw3F2 zOMpfq#NRa9hnzQOuB)wU*#NH84|?2UCrv_4qF%2CaBp;J&zL^8#go3HI8ufLeLHn= zZ#Swtxp|uMZ6mjr{Q>@l8Y1E5?A);B0QBF-_;Cm(%RFuNCrp276Ea}wmH;Gjudg}Ph9tzqpFYLKbBOKM_08PoIse~K7p$I6DcWF zo{@}g?cAfp&kJ9I*ATs2T27VNNWU-e4>{E(7cI1ih4GXbY9{AWW*Z_p^1K+U%wbqe zPoN}Zgn`9xL+v<33y+^mC(*(xP}v=3a81rW;Kw=)-Qq3pnpipi3E~X$PjjE&Wi6o@ zM9^bFYd3ymvnSdoZ5U#3;l=->kp14{EH00;m|ULob3jte4GOQDr+p+f6A~T)4bHfT zv|Lg`=n$-Hur^wll9(iw#?eCW9j32MJ((cRs9vK>D>y^w!aPW_d@d#2pI^;BO%Zj9A0WJYQ|~Za(qLo$0haQrp@H>J!GA64-P<4ZlO|j zf3lc0F}xro%S>V8L^<9~O24Zvn8GW?^Zx}!9nG^*-7C=0v<`e`5JL(RqX5KEhi-AK zbVTHFvg(7GhKGoefaz_YFDjSxfZoOK*~yJJPdY)&G^hw&iW8XVZ60Uf4e;^ad}nQ^ z>xq(B_+^7^z@YQh{#dAF~F#tZ;rOvkj?nQ@JMjNyJF2 zc7cp(tC6}pVuT!Z2#Ldse-?AZOlUT;evw>WCn=xbQf@7Bhu$_?0F`sUpOEp?$u2J% zeNm2sh@HH%Q{LcYHv}a7ZLAosK;s;tIUqQG?jikjR;@85y5detOS`RyA(iAy|N6Abk?iwSSC)Si1o zal->rGplhkF9H`XxI7U({St3$0&7{?PBI(;CJ86M%x`zsEY*3X) zB;%G>MH_WQ$dzgCgbrJVsL-E`vV1_Z3yCQ~jPHZEYu-VnfS$+s-SfQH^#K-sau_qM z{#!b@A^aMBy1&2i@&tw(5kuzs7@H`hNf&NTw6b5E$|84;GJEy}9o1>P+&Q9SX*rjw zPpTiM@FFNwr!gjYnA)ONMT_KG29Z}ogwsTE0q8`qp(M&Sgo`fgK@!2>{d+e2NJMgN z4oaNjINmimT^w>X5-KZiW0vVD`Dv6QGDpV=c6SxZql`}ob7C37j!YGe-?2NU;?B7P zA**{AexGv;n3-Yh0|scj8;?DDXhFvrj`z4AmoKF(W}FRf8x>kgYB0(rER<0fC0OHl1Mr&O|mXP zFC;@)9ZZEyQ0$2|E~QtGG<6s)s)vnY$Kb71w3hfMqC&R>j*WM5Bt3ZN0v^VnN^h&1 zH<>q5>!JP1m@lVbU=Gm96#Ec+(=CR!k#&78uYgiUC`X$7_lH4?iAJo&k zIfb*qJSgwCGTN+=$(NKJZ#P0D^vPZaq6dW%r)Au5L!^JLoHv-sSFLt}(Z81KQ0NU3 zK_%0SuDRV4tMQjf4$Om8N`A{IHk!k?**dT8E!da(r53IAcPnD@H$l3us5U{A75FEC z6i)L`pMIUM3>ibe0-WpRXNp=STE@z5sBe^2sqfcW&^M`~D=EMbAcN9dgfift||;N&Y})E+BQ{ATMoObgB3pqy$H=pOtj7>|Iy+x! z2mYsfXQ<{Tn9f)nu-;3h5txh)NLI)F$vtKdwf53h+4tnv>%KsG>X%{$bsU{XZpdL) zUFhn<5IE^p@#@_fY3piE9r2;VH>r_cEM@x0u9Kd9Mp`;s-c1SvxpO!0ubPTb@`pBp zYKkCA{Ug$;03ZC1>FA;TZ_{?jxPS9hy%*Wq5wsyG8clB>P+r}F& zdGdJ(Xf9%K5wysVC>>|Jy}wCMdURuRv8xvw<`L9~HG+vskYzM!(&Fe9 zkDc^O79jbh$xX4ZphzFPNk6Xg+Pb>@?g0G*rSLUnmzoC!rnW~`k8Ku<+&GpmAai(e zN5={_)K&2FgAEdXY5I@R{n1qSepctbHfao7$nI(0Nn|2|w74DNr@Yq6HYn3ThNyh= zlF-Z_2yrb77I*hQ8T(vWJ;=mu!AYeAkd2 z+V`$^TEYj35SuUE6yCD<7#FIUFdSQ+8FZ+fx+nZrMY#bp^a?07=gE1Wk#DxH`yw?5 zb9fXaGbYmboaXCE(AZSWpw(0Bwoy!DYc$HbWy+X6&qQ1tIzQVaQNe{s6YOsf4-W$( zn2)FbOv*t*&%Y9cUj8)wM@K(TohSFItFLr#+LlQlVVrO{JA^!kQGf3FSTcUI7QR^! zwvSSZPYC=o8u*8?_nI-)lt{j)j3puU0{<@@vu*uwBkU~3g$fh=P}auss|qH~mX3Ea zBl|7(>7dex8Qm303mn8CzG+1VJPae_Dv|>wx6ou?4=k(7PkE2=Egzw!=9fE~6nNa8 z%?}d9Z_#D8wuc~x$e(obS#$bI-L#e(n;Y1xouAyvd-g@lF>mjG4B+rYVV z>;1_1{m7)mjjjx3pqbw^YKz21Gx05eqOGIjy?f`Sd)i~eu@#L(;BhWO2uy`aRO6s0 zgd14k#`h@HBgdsp>*o7 zza6d_K#01CVbkwbk2kn1(wAsHi4~7g*`vM0>IDk}aoo#62sD=!CHDhcp~g++q4QBG zPWN_(wA$&v7v*_g*&~lv7`BR{JOz%iqal=EzC3ha`U^j}3a>o80jXUHZ>tG`fO0Es z6gFziu_RQV^#-fp@@3kCa_1l0DcK=?dU5$&LZ*Uk^G_<`Rz#7)l)8^!pWt5gZN=f=9tJ3>k)LaFR%4x3Va62a7h~ zQ}wLUoE1()u$K21=v@?H`Z^f0pvwapj3tnuxXsYGsi+Tu;o+^BpK%A>uUkDE9uvQV z3yQEd+o|p&7H0gcwq0fcF!o{CO3vE}Hey)TOyQ?v*rlMtKVK~TML}Y~2z^X9%>pdF zMf?%?Pu7ISUC)d zPLAlqQE_Nu6HYMUVGp=bp9({wBMdDzEORpHok&DFm=e(9*Rlvbs3prTvNrP{$q!sXonu;=o$nqe`Lkn z)l`wX9jlxWT3Q5~YqQ-G$D%K#q{?XGSIL!AOSz;$583P-E3~-s?>Haqi09&8+q;a?4pL80acYi!zoRl*Q0_A ztkCmsuCo2EAnILy4~gZd#zYZ`%{m+-#8q-9%3lr{Ex9uL&J&UL=x;wwv}OJ>4`pFx z_pSqBWC`m#$ymJREKAHuhIihqQ9Vee_{D4P&7yc!7f2QU6ruvuIQ;@hzc;D=9oP;2 z$yNA4>jaG_$CpybzMXhYIVw0Y^Xc(NB!pxUR`72HYTE2)H4|fsRm%O`zs@K@EDDKi zW?aq?Bmd6@Aat%Y9N*M%+(PAomf(2*P17DB_?imt99cUzs3PBO1~;N{-<{>y?xIVs z90f$MhAb?oJ6++Dm%ctLgBC~TzN=9uCZ`-*+soIiLEmL!8t_AvB*j*EX**q*GF9nL z@X3ZRitSG&dH3V(DQD&W^g+SkM__3~ll2-?93IrDZUogZtF*Yr@xS6vJ?MC=GYB?N z2#GL;)Z!PS?PXgGny%C)yWa1k5T%oGHTKEjNrY`gekvV6S7)$W2<~BcRGpYFxv+GS zPabHx>&6YNMu1nUJgeF(%O>Hc5WU}X_%%qKQ)HF{0%82!?#@0LClRWvZyFrd2$gd@ zF)IId=!p0mu`2Af5QzZ3ioffJ51bsEZq86fl4{H=dkA$&*%TXo)brKwC;fR>_4^Z- z#s>#Mxujyl)t{fJ*K8A%35YOmBLW>%C(y|r2rD+U`b%a{#|W}}b`(#OO+p1+4}F#0 zaHEt$(m4)EE~PXN?Oi^Q$SwzyXb8;5+_n@bzdq2fA>hfRGG|9OzErJ;WV7W(9?GS7 ziM+&-*NL#Gh?z$9k&T3PvfTti);E0y|1w)I82Gsaca|BLAtFI2E^VHvEsk<7xRpwy2!2~g@;z-0v%E7Eh4|s2!#*E57m1rFr8^V!OOGcQK z$Fu_Rixli2WbF!Vte`6+Zj=~q2_tXh1l~yPb`SK z;v3bDDP_G;kS8=RN~FDBQBx4$1TI`gN3wI_GddAhUp(Cthllkt|JLf$Wl*MrN;3X3 z81uuMHHZ{PEX3PgxGs_1zf2&1QOxU}{6%ps9l;_JMD9=Yhg|vSn#CJMmB1h_JQLDQ zm&sRbPY~BEcbPVeSyqL*etJSdSgxroq&YNTR;zKHzDeBjmQRz1u0l*I#!*<53z2tR z0Ghw{YtxY8lw9&Yu{=e&oBN-h?9h8!?>~qX&{w= z4-KJvl-6YgOYz$+&NUb&_{*vC!~}HUH!QmADZDX*tmH(maP`FcXtw7OV5aHV+TjAv zgkk#^*p$MY-mif`8?V#apx}y0`ZA_~z0UZtgG2l^GR*$rVHgY@A`ZRRH@^^rJw*QT zl%K~&mIoEf2n!Q3+c?pfdqaitY?iAf9vN(OzN-7(i&c7^jE&`Yg13F-zL`4wq%|Qd z=i=K83;nEt@FEf;CTwfk^7``vnr1M=miWb_`YD}2fXe{On9~?#mHII6ANqxIiVj9W zd6G=>H0^;-7WtwIIca)3hsOv|(Ab%&C2o2w0&+RzYjQvKaA{%cs3ZX>n$hevlcuB} zqVJz^MP6db6uk&YK6IDQ!4BuJS!!7KSoT6KYv5=G_ZRw|ghzsS%Rn6OYl^ZFs&Sb? z;6&f3UbsAh2Af>P@L`n7W>@0I{w$o6;lSxGmBJa-e6cRGpSe?J0aErhuDDunVKt5~ z?N&k*6_YWQZL>228+?gG(2C?;*A+_7AhY`WilBrl<Ed9oY~V{*(m64O}ZOg%fYPSUwTNz1l2S}LoR`~)=#NPB0oOogdwkc8W{BN zZLjSEue*<3eL?k}+o7Z7qZoR4aJ1c8=rJqtB=c7Z7KBr=AW=LQcYCKAAft@C9NSE$eedDud3yv`Axg$!rc6 z(tq)mT%#bo&W&SI&2&kW7)f2{;YIU&_`4Owoe%qEOpv#mEYc7cwscjmOa<`CnNu6@ z6%Wcerre*rxu2@r&q0UCp@k0n>%TkBQkWDWoo1!T0s{p(~bdF^~>QK#hUmi zvyerWB2$_i3t;VIoExXG8J%x+bwHVXEXCLuXSOJ8uKm)!tl(9zgJkoCQ0Ek$?2k*}TWjDIhhnIi%-d%-iD6@3f?W8+SK7`Udx7Ha#so=c!BuLEDx zoW_(VOai47H5}z3U@|xDiHVMJ6TuA5xg@5U%{XrQ;&%@a6+Tu1E>;3|p-5NlmaWUI ztCmtJ#cPGi75EVUisS>=#Ufbnkj9m!#UJ_0fowxhujX@Ioo;)5enF$CN-g9ac~bEx z=_Q#VHg$VrRzo!)ac}^X6unK6X37fg9{s9iL7$SnpuV(#wr zsFdWh=GP!}9J#8N&H&L(ICr{3>jv;1pdN58&Z6Oo{Jy<$ch}5rHh{1QnFFEYTQ&%V z327u74&rxIWF;7r?ll7=qud`q+EroWcX$gYoRfA#n3O9s zaYx(Xh^=6VQet9afPyaYAM02u4d8xeCa?c(c4me|(8tZgqm)L4em9!P^Nol(9f^!b z(Es+|-XMU3R0`*S{^9Yx#PY^9z==w`%dd8{f@*m87l0jFQ~8{s-d2J*Zm-qp>D0K;UZ zWthq8hnpxG2tpS!bcAC(RnXx~4oUSqC=$>`7+S}+k3SZ(mf8~D*`>?MyiLJju%=8N zqjbdR&iouaAn9tAiWFxZY#~RKA}50?63;lSzWM(~A{6?vL z)(8iUQ9u>{_A410{Ssnxswd!oM@%wf-85=^g$UBATM4|C4!kuEm~4F=`0~1M)#MEf zY^|VS%biXAw@xyF0F%V(<{{KB30YN!v2!l#TSA8JM4Qj|nsQh#hwy!(_B)dVqRmfL zai>M@@6n# z>xkid0ol;zvDxhrZe^etR5VuQqLj$G>Z|7?nM6NwozLlZ-q|ggJn{(@MXh&(5vtVKpX&bHppcP=w;LIN4oH#3oyMOixKm-7P%qfD_ zV`+Wv&b0%(`b*pFnmmHLS4J8;^N1!4`PD z=TRf|_zlSb(2RA49jqCqDlw9wyE2Uz1K1C&V-lD@+oR2Wqy%0EzIFyajP|}x_WF5y z^BUrTHltOb4VVBgLb7-`On*^zOPpsKPkQHe1Fkq=`fOOyozZO(Q7Zx{kCKv7-%W%f zuh}}=e&aDFF9yDO+9b8PO%`qtdJ_0&5^7=28#D+$<|vpF)IyY{2Y5)=$1 z^^NeZl3G4DIY`Zw3GnfCjEgD}^RWbG6uV^3Yjl1$iRI-J$Z~ILu_s8t;p5wa!ukc+ zih4yRU;RWN&;1f-n-*jFIONMi9K+aeirG=01Y-l>;)L=)dwSw;OnKuA9cyUn za2bf#*~cWAM7e~Uz91I>G^K~}T_x)*mY2mIC98Fom*_F(lh`^|E3O#%0CK}D)-_pH z!H}ER6cLBae2sxpGYOHtC$qneqJOzVkJEnD+Hiu9ZzHKV<)9tJcKj`#4Xc+q$iobx zjjFV*A$$>HxPGZre+#WF@Nsl%8kkG5X+u;=?RluNZp{wYY@f+3$AY^nrxjQ&nDH<= zG&!(|ZO72tyCGdAzJwyeR#>%)nf4`7iW`+r(!h^@c~OL^s1_SKj4%uCH+4Xjy7}c7 zmPR&2qcT**KF|)fUjR^8MM8hMlf5OTWN!s&ofyf(nZMCilepnrmx1vj`4Gbs4R0dL zs9~y^6sEGj8b5*h(1gKPj&wCr$Q0L+pO5!Ev+yM{5*t64=k>3OF2*SAO!j@DM1GsN zfk?hpruUGrYnY}SQo}lE(zh;X(a6U=uaN>7ZhS^V?RnI!``QWU!93sIJpEsHK3)I@ z4{-diSTcL$5xzTf{_zZ6lND2C7h{{jym^-Hcsuz$4n7e&x0nb|4e4SoQXw#gg+EpE zJ3aG{yfvxseII z(6rSnler07ixo?E_rf9|_Oc87y4z^&<2?6bn;2~0sOWYaH0!m3l{}>p~3se zk8|J&QMA)+ADg*qs!V~+Y*zL3RcHcwvk3^c#qLR+Z!JnuAK!oqPUza369^I$#u-H2 z);N@ftG+S0t8BD*&4=7nFvYx|hv!m5NOlZa#nt*uGd7>n+7qdvOGb9rMumpq`wggN z00D0g;KA|u>0^sO_hr!)FjFvoUNui>wqM~8;KJ8*MAub4>e$gtRPjUN^{|$yM9IC| z8!$0vkkhr2oTWmcm;)1PM3A$ENFSSWgS9mDgG%Vq-d#UJT(crAYkG zkFY^cc7H1wM@TVKJo%kha#i9>6z=KoJgEa@!K!W4^l-eE@Vm+;biOWnO=o)(Jm7Z(IcKG+ z&m}sH;(JY6v-E{V?v9zAVWG)-;>!0SON(?|_dDqLA$bug>vbI@GDp8sqoDdyDW(7ItX-&vhxq6_qpoh&;I`Y6;N>UoyKWsYZD&k+|K$P zFPQ%E5=PV35=jF~_HMe^am|^SxNA(#ONY$dq+@?=kLb>8j)e3|cpzma+~9Rd~i#>f56`ypW8dv*0=%??&1 zp!08rHxXU+gh5=|fHDqh{m^g7*H=Rf?$pEsiXd>htVNwhdShUjSaY0&N!c9%ZTV*L z@{Z`PyL%3zhW$kUe)Qv23o^;Ul|N58{BMqw{P5zaQHj?UN8fXzoyWYu*8|dzv%04& z-?g_qKKn$|Zh&+Sto)DNXa{nnT)z{Cr=D(R1D7qu?KZR&I{wM_PmMJin*)tgksVRhqAWv-wyV%V zT%QMYv$jOs;0YP_G%wnuqWmZ_yo%~ms$igOivI7FWHW27NbX4yvVq$O_b;BA{vP0L zJ9jH?0Jg8uaQhdqRPSkW2%wwcef^K+o#znYM<{5oKilRzkH&uHYGGL^Rk|Isykm%e z6CvEbV|-D;sxE8^Zo;yora{9FhXIAdwa;LcDg+hg~@!T6nh06?h)`EPp z#Y7RTgq{cTFN^xbjDuYGuH;BO&5iBw8-jTynPnAsF~_mB9O@Fe*i$He_`qrRd+H($ zQP!w1x%}jJtz${a6#845F)SE+5qljm;tlWxud|ztSqB&e$GWBr=#uS4F#24cx zL8|6(PRHf@M1d1u(@K5zkC^fQVN9}Ah{|1R!Wx-_;|aeBhTIc+EEOSWKwR?d-6Jp@ zijfnvmZ%fS`m3R67e%wxX-VsLk~=fZnO|{-h&WQD0M6Zzmp_lZJQ{QqjDun%E5JA^ z=!D-CD`F?xM6!}%74sY)T7<{`NrOfl6J2It^bpuRlYN9Vg72kO#0W|*5`N;gXrh=E zlNZ1{%bdNXtM)tdxIC1WW<|QNg|jR8x=BkF$H8s=%Ge|SOB{pF znnV7tVq`7bnBSAgaLKK;OP7$Nn*8Ek;Sw6B z8Y{yyVk#?LFvix0+s@UTZ*E=QuUC>5&q9J&DoEA1P4mEbnq^#1wgpZa&m4v37{C@AsP>I_?< zK}f>|f3iAPPJ6$Wxb!vM<`o>FI}~!&pBE4IZl;$Xy2mt`g;6ya7E0))1SQ8Y#|=*x zy9ZK|!_>tJ(yDM)%!%GK$lFqejrG2oOw2p8^%lRNIg-8U`eY-PidbOm9-?Z@qrqrB z*6!EISd?_G`e@W(iF|otiLr?0c$LOzZ+Vku3M4~z&T|mI(swa7L%zL;n2n? zD-LG}8=IP-*+FcpVk|-E@eWntEEt$9Cr#Cp)$QL`e3r2l;!PvDA3~ewhG6mVNvU<* zmPArzX~$ROCv_>Nl5r&q`pc+U6G7FCoc)uoV2DpQ+`L%VYMj9!{xvbH){YkYE_-a4 zh{O3hF&u@LfN+I9-=Jw!ZdT0Wd$G}&gUT}{d=Z!+qA3gZn(cV(wlU)mH7**=*m?v* z)eJ^+Z)K2)s8A3$;+LLBGaii^+pONJ!xX<`nYb~wc?QdlYDcXUiD(v~-;&##RMxj! z_zs8mKgcQnNjrXn_&l~Emo=cM)!Wp+fco8^9x{BdrSL4FBHsgjAlBP}R!g*YM9D`K zdlVlQMMv>;L|!H~lADo`;@0{j)p#hF8bfCJHJZ+sZ#b;J*rWa09G;H+8FuKREMort z1)`Xu8Z&A%dbQ>v#QjTTuOUCJym@46vt^5Zv?qaL>TN~R%wH5$+|*OdrJawD3;*eO zDp{A@Olb)#Elq9Z%j5yX$y6`$k`T9jQy3x05~wfG#iP65WblMyLzi?rWOgO_FsafE zf(-tI8O*qOYQBeOqrO{PIsC=QOcf+dHn-7`mTJq+&fb_kAtAx2)ZHe(*xf4upYpx^ zmKKgas(vWQ^tZF5W*7eEKs@$&AcLDaEgXG^Et@0va57>*r}b-bA-`SMf_D-;e!ViS z!-bgex+i3?gA&BJhoZyWSacI4_D5}aVvPTax^XU%>bhIzl_5^HZrzd13UAw!Q>70T z|KXS)x3i?1k#r0JJFdPrmQn!C7(CzOMJ6Q?wFP@U2A-tc-Py3&#$&U2K(Ab=>HWjWoeQkf7}X4 z_=6_QiX%(pdM;Eq(3QQ6A-Bt0YQF>+mS|)FU{T<``Z}hjEpb6fP-^Di@YvOpR<{Ck z+G(U_ey-h`0UO?8T1q{f{n|pco{@G*R2Yhz)A;!tGr9x%_QP4bh6P=^`>0_iWE$PC z5!Ju5Zt)@_o|p8DyUIICk!liKl82X9*)X8Vz}n5(-?OsUHyXs0kjvXEg5Gh}!V6bB z{1h{YsmawY_%@Dia>V)1AI7I@ax58f$}M2kl2Vx@K)X2`fdO|C@GQokQLl`FE$T)0 z3B>3hNkdT8^`^jAEwgiaE~?=PmtK|1&fJUVpZdqRyesIIot5EDBs~md^`DL=**1N% zWt)Cs^Vd2k6G$KZE&a4S0(*L6N0XwrdR}ftmrRIfP3_1V(7bVob!6=iF>HG*F(e*b z67>xd`y3<7dhjx}RBJDgqyyJ-|ChxZ9Ru8=g5ULZF0k-QhM;n78`vg9e_@E@ zQv1vBdAh6oovTo`%;Q-VGtij+9D;7gg@P+Lk>hH$C){@HL~h~HIegCmjjrA%$8$Wn zg;frX=PIN2cb2m>i0qmg$b%eQ?XCfW!o$;mL;~iCrLV=9sL{!iLCLe=2WwAgKNc z4~xrgW&WD(2e1WE8GWDyXw3?XQ$Y-yLis2SQ*&OOn&RqaGr8@L%BhGhkKx__a{*Kj zFfpD+RtD^7?3q8KuE|*+=5;|py3zH3>7e)4 zW&q3dN0AA1RF<^lx=m?Ei*sSB4c984QPxJ&Mtz)FX-GmAa-*2CU zA?lxySCvTP@|Mq_gnQ8qfD&YICV8~d9HXIxG%IALe#j%|mC$>h$z%YQ-KV+m1r_)e?tfPJRWivbx#j&R^FKE!4gmo%uFklCVKaJ&%zE_lNK8ux^1hT${>HU| z%gF;dxfa<{f$b0(`MVp9KPlwOqD$xIOR{sGDJ|WV1ad;Hm{K0EbMw(kqo_ERAqq}F z_lR1`z2e+N3o)O_+(ZLeDK1zQ#34?0S~ftF!qBiRi;*+tn=Uj$BgauZL2XEwd)rt0lS#U^hsb;|LuGjXRSJFxlk2pJ_qHnSc zEfWSW?INyL|L`q$5gW|s)sOX4Dob&7$SR#!6K7@GuP`dni3K%1q));GmD*xe{#Hyq zvK8nI*%KD_g+#nBimpLwK82+Xe%LOEA*z{_*SyC1j^p}G;bcd`@rMEW;I!h_&- za6fEwPXZ6Rz{6bgd7yQe2t zsSId&1KwEMOPKF^?!{m=Re&TodT<5M>j3eE#~njDqjzvg!29cyOS?d~FJR#sJxQhc z3HNP5o)7bq1^4^x6AaKKAt5pQ_la#nU&&=nU%6~y z#W+w=!nph6>qGq{v-^CG_o*A7|NE`?Js^N_mEDf(V7UG#M3OL?kSE0FhL(V)tgI}; zGMkS7sl!l>!titYTpi%izf%q;NXgEwKYJs9EbgT|x99Zucy+*`2uOGC^^G)lQ~ng1 zVtzu6NKeO;@bd9V?|CHuRMf5W1DzE#aOL*;I4#ZH2KfEkRZ_uKg_9uId~|%gUS|sU zKmIe#q0yw_v88UWD8TBTO0y>BV6~I}=P9Mpi5;8PK>a-N@MD(&%`(|&7-UKdw@WW|AhK%I zVNQ|KL#;&hZX`#NOMYLVUqTBn0?5nWUQSH$&oo7~GNaio$QMLGRN2$VZ!Zs#Jc>o& zmBy0jYsnJ>k*jHM@fC1z zk*`AU{m&fmhdy$V&0WeUW~ZMzC$|w05|Tnf^-R}qrQPuV6ux(Q3M?<=oAY|ff@}vd z-wF&x9?#xhfZiX<3=9I|m+gokA1yIj@CNtwPx_r-2v6;M!fryw43xM{-6r}A9AW+v zeaD}f$t${kaJ>u1hX9Y70H+Wl1Cf-&)2h0j>uspuUTlOXzq~FC&Jj~+D?{FtiWOSb zXNDp#1St8O>}jdPU*H+Dl?gi*#=$uOP-va5-dVGZjkc41Pu!@Nn?d_){W_#KjE4LGmtdo@dsAxATh5i zPl6q}vgx1@c+jhdt@k{-)~URO=g@`6hKmQa1}y~-HAciuF3w0RU(T-K?K5hjHDng`bbIF z%9kLRteQeV`@a(SeiDcZGR=b&S+j$js-NO-1o6zewyn`f(!r5ihF7OuMxP*SE6%c( zwt5kC(MmY|7I>Pv#_N5o0^trI?tQ!)f4sQy6^IM_GLCCCgiLciK`R-`VUCknw^)3t z-;T^*;M&-7c<2Niz=dD;&@Lu9w-Q+y=(VmyD!5C>r5xldwpn1yLk8rO!%HgcY5zrU zhe{?m8=!55X_swYz@EUS-_D(XZ%o%CVQ?&q)h`Ju*D(>NqSl$&`El*-83v;b4nlJ7 z_?7wW&4cCcHd1D#YX!y3tSzK{Hj)z)6gsAg(U?0D71G~ig&+JCp$5kRw_wmCm^yn@ z>+Di>2J^c0^Bj?OtXJXqD=PK_p5^AO0Hd-^n}qBiz`1;~_i0HH1ry`#KU4Ap;r9a| z93C&xRZeej+H$^wA$#PIV^cyke6j+^yT?K0OC|-l?1KgGH`5TAzNpn;qtjr{M|Dk# zMdrGchUpsikZxRFXdJAzjG3mNxC2~f&00>8 z`f{!Qhk+;?$;cgn2ONa~JEkP_7>;gXwbvRbT)Y6HOG#V0xH%{*-bQS}{*`=No9;d7=QIQuGPEp~^i||uUGzvEa z;5**i>@vJi3IG6Q{{_LktpuWgo?O3?cVAiCk#kkfqd@+fI$45mxvVPCr6HZPgL@*- zigiq-p7OnN(Sq_QQ;h!^U{FDF;x`*xokCVuY4E!$g{;Q*M>9}UQaciC z{W+VtHRGrNd*15!0#soa&!`*b@$Ge`n41xUfs~syk!hPY)B*GN;=FWlZIFbPkG{Pl z1DjR+6P?Sv4~*^WX_{FnwllUIn{fGx5=^=~&h{o7{%73 zULHe?OvOCik?(9XZb2K*huRJ)Mnn)y5O;fsV&~Rd-_MXIVxEfW@VPQWw+m1qqa9{$ zn%}qv{E1-Pq$d%>1m6)aoXcXeOSGs}+gc3bxGmsa>`d^Yg?X3GJugPV7>b?EeW{IHbq1AEf%}Fh;YmPXy!J1RQxEUY!%u8^Ab@ zhy7u**_!?E#Q92WAjCLrB{1|Bhwd%+;SlkBK7ac3=`a8CFT=*u zKNe+x-#Gj0C! zfBDbTIK}(_C^j{SP3k6g?f;CuZNJ>99$%JXA-u?-g*}s6e&=_7=l%QljRw95T?eXj z9au!BD#)O!U5Ws}(hS$QT0gzer^cxD9bNhV#QEc*2VN|N%0oR zpwFAfAq5R(lC)5Sv_U(gfb>3nUZ~FX)~cC)pXZG%sX^j&^?Nh~Mp+vcJX; z<9GLTZP@H|*T8C+qWr-SGQ`DT=g2=Y9~kB2D)-vF^*$T`jN|yjAO7$MKlnku11I+u zA^>|`h|#4edy=R!WdZhn z)!a(H50^lZd;qx}t+3*@o^aBFI&6c)OT8tDy$rliuARH#eK zTXC&nsN?^2$=tkVn=(foS5q70F7c}opNRp5t7I$@pWMUvuybVRrgbG<5g*A`6j_!b3+0h$Gc7~*jNWp4KaV7S*O%l>T%)PRJ zYG(8ZN-43^h{_>A z^IZbBXSka3R>_ovR3=mEYQ_Gy$q*$0fVdnI10-gRh_%1)Q@kxy`J0lF50gqxW}>Qt zJCEMA=v0;bLez7Q1-iNtH)d(x4GZ9&X$4Yta0|dzAc>2lKnaO@YwT56fg16aaJ7w9 zqyRFCB`*}^Rs`|esFjbdYo7CBKdovg+9Zfi|Ewls=wZ44se`Pv?4em@sre9x+VSF|LX(n$k_r$2;dneI(pgzEqND}F+w)fQvixUb&T zS@X(5pfH@MHcVP*qno+OIJbg2V~4y&0st!S>nKIIw8y`#0j0Rkd8ozCHu_x@pLy~fnU*PWs1q%oCIOaO4J!(L6w@)<-H340xnwL^Gg zPnQ}=*sUW*uQe8)V>?z@c-HJm+?N`zO8;0w@QTaYj9eLO ziOSbgN?(h3;F=WL&2FepP;+=2?KQ<e3f^JODCcX^>s5{o+kFilf@BeUv3{#hFdKQ?olDxgSJ zA$h58=q_Y(R>?ct&AP$4VhG6)0GWoWETUnB(H7&`kt8!OW#Xhq)-(Z)kawAkTu7Fk z)CH*Su`P^EWpcBk?3<0tbcm$Cw)K>#+ibrPsWbS>OS5lA9oNDv9#X9W%`Q=Wgm&W= zi@v5-pv|INo{MXfy;86thl-x)Znr< zb=YlH>5;1b<>RZg87!Nsndq9T*R*p3&-M#=#D7Jzy)K|ujozVsoowaQk``EY?MYUo zvTm_iBF3Wq_E+@~t9w*hwA=~Xyv*dimRNZ^h1wzkJ17B>ORNUCWV@=3db?N-uKdzn z=5VBqTwKZmKnGLYm!gi6s!CMBc=C8UX774_dN#z=sGyCNvGKD`W1WG9s)_q5i3gNB zfsHF_t6@iRr9$rNxFIN0*J4*#fff|AYbms|hL%g3%2&`w8Kfu~@LF1+Am}_vtXg=x zP1OofXL{QOGazS=InOimH5NoF5u3l3TIoZYwPR^#RTZadti7tG zs=K`^>)?i+Ce)MuQD|gC&7C6kChyi)0kxLyE^|081z0_~Empi$rhM0}0IY<{zWL@O z00cbs{QNF{>xV0ecLmwM%J1S|Zb)mo$lXZg!Y1l^14;W3?bcGQ8=@6zpp z_2fm{xq4NEFtuWpJ7SSAOUu4QMdW2LC&=G96j1>d#_rmVbogXJ@;}zO_KW5Uz-mgN zfC%M>d%_v^GLoxaXLkcY5#N}M^7MHj^gD+92ve$Ww7xV_?Z*xj?glnKmJ@{!g!y%L zVd1l-jIAA_il>dHcw5|wDj>YTsP)#a%jI%B9>;Oq?RM?DRkPwJ20pK^FVi&bb~{8Q zg7o@IxXSP@m&@sNa?U+GSUdYA>CPu?Jh&+Fw=0J?k@!{cd zvzfGhN&iwh%ikuP=lSz~KhN{Kr>Ak65Rk|tIwq5??xHFpK%D3K_4O419v&WAde$aW z!y|%up7)3SJkO60kJB`j43@vdLO?|M8BO_-MFK$b9-TX%PA@Mn0Py(uxY=wL!%U03 z_n}`;Pfu%J7*rWfRNs|dsU5s!T}J#htH>6&inm71jBx2tzQe8@+APm;c)PNM#MUZ zUFG`c^XYZJ-%QhPw_|!%S)|sruu392o=!2yZ+GZg&-66}WzxRx_viDO1^F;YW}p#V z@|%+hfIJqH2j~`!NUM`o*k~|h6%zj3I zZ@&Kea=HB3pZ(e8GJ8Ke=bRgU@WUSz4YDfs0Rj=7&*#_I*AQO>a;iH~W8DHn=&(P$ z?q3gwL;CuOjkNlde1Z{H%K*!Y%HPEeaP4$Fp3Y}B%=HY!kRwWshye3EpU>yR;ZS|Q{u)B? z+9?3bOHqaT2%Ha!;G_3{43I)&*%N&a5x?p<*99%)9G~j{Q2`r=W2mB1UMd# zpFe$m-M=1>M`b^8MvAfvC|o8SdhbuC)8TM9okG75fZ`{wnE&t{i7i8z=lSL3B_wa7 z8*Osw)qo)roQ^RV8efQ1DiGttt|0i?AC8A_zTrU(YvC7NpMZ|X(_z2g@Aq=NxPvLH zj+gkL%-$akhr{7;IbRIeQJ<(MhX4TJQ}8*RP7OQc*tU$f_%Hwg5uHz`{r+{o-_MsB z@(|~7Pw9<+AL6Vs-9+<`IYyY3^}?Y7~Jsq^!PvzAq4l8&>`pC z{%k`W*9BifupPq=QEWLJ#6x(z-xZ(NvdA`h> z?Ir*VfaujxHuHnIl;#xaw&KIXgBu1v&x`U%t!vutcA?$HrD@J5i0fm_jeJ6>X_{Qi zo?~Sx4m)(trJzCMIHr$qA+kV-tN;KY07*naRId@Be6Rp3OGX;U@xzA?SzXzr`!R3SNyr2Q|L6bwAAj-Z ze*pkQ-l6;L-~R1?_M88#*SQ*w5QMpxQMi@o>Y;J~04w{|Cq&$Cx6AtEJ*sCv2uL`N z<2a6Scf%4tKIE7na~N55`?gF{WxEX=ALb-(7y{ZAu7bRHTS%^rpr0UExua8fHo&|j z0&vb}(NvXx?ixfmt zc6NT>=qd^-n5L-;w^wpPK!ELbv)N42!d(@Fx#@`Jl7-%3?fY=^Jc}8<(qrjghHQvo zhnt_h*n>p9S}N^jz#h7@UKK4`1sCe!QgW)?yr$iy0!G(t>~2=2G*w{B7^->JqtY|E zzLzyzuz4x22CPY)IZ(gWqKZ^F$koc11wqIiS6o@I-(o*`2{&l0eLUWx1v=*M#BPHRMvHk zULX#`uwv;X4cd>Aw0eM5b*o=Fvh;g&H^QWNto%zj@2bt%M*2=Y0(M4MXyg>b zGa@q0EBmO6tqbfz$%ttIP06urR5uW%y9O*-X+lI$i(5&kU}?>r;jwT;lXn!mMH~Wg z#W71jhYr|%M3L{L%*yt1G%5FrO5Oapx1!#++4#yH01P~N$BDwSdRPQ=hz__)vHUNr zyb%@TNz3utl-0nj7xh&u_p`#HAw-M{S>cHW%SJI7%_ygUpt{_cPHJl7P#8M`@6)p~ z$>7XnUdsS%^xyK0Z)w{Fm2fdI1*zCWwmuv5?yrFmt7OV;1C$4cGIsd)|KZ>N?ce?F zFMs*VfBvH%{m~!&kmf!ddSX>29m?SyZ=4>he*$N)!$gAvyGLAPGtTQ46ps=k$u_$?q1=SYW zGMgB^*+X`LR!Lvu=!$(ra*`o4wP+0_$}9u|CB$~S{pH{MYIS+l0bt@@5ii1|RXXM! zoUvAVenN%34~W=%at{6M-H;$mKdbfK_a8KIW!==f+f{z9?X0@aY zmmgaMfVip{GG)D&a#2pu{!Ne`A77K<*m#w;+EbsD$t&#>my-0APS!{{lg}0uFV2*o zY?=Ux{~A}V->X5MN(~`ZRg;jcsJ4;CiOTii=C^+GTW^`ewJfUcxb8vNZ1RPYMpS3| z6kJ5gai2@X#4){Pp;VHq<@(2$-rx?&`zi#j+f9dLSWFF)%1=Yy)eN z2%y*9Hx;otx;q9YUw(a?1A^8pR*dKJ3U^O!Ni%WwR$#qz;61Wt(~=e5V8tjOW#N*U zO!&$hB>B{~lO$PEl99wytug_tk+rUrZ|el6M38TNhV^M?0wnq5Hr2@mvu)(qa%~kC zT@Y0jk@3*Vehh)~OV@_0dwo5JrwGggC`(fMTkoy71J*>=0B7lnjpXOefvDP#t!%gs zuy?`3-$D8|lef|*TYEww2#=y-B(!~-hPEU^4YxH5Wyoz->Oit;Ri+f*nzxbkjjPNx zB>+Un(_8C4+}p=ir8lTlF2WXRKM~s(U4BnA8&#ejt%RMSaGu+xnvh;@vZ@!7Ddamu zy<%-nDamNKR(>~lA2BO=RAU1W2k?L6D4em6HBD< z4}tvpt8hbeR>)i*wUV!(H)c4hdcp-TBS0-7ABL+liAqe_fPyRKZR)`sUHV;~lQ#tc zJ}$smd{3IL$S-x6gyN3Yz$?SInvz%6SdX4q3E`^5yJGYkteWEFrwBUBizV`6B{3!D zap495bfmt;kt$M-tNXBB-Z3nWSXtvA^7KLdhB*cV? z*b9Wwv}MY&WT1rnQc31$_Vzln(jX4w1O`~PYtUOFdo$%&axu*lfB&+@L;`Y#PTH+u zYA9~3OpO|ojkRR%&0MAuqe^zI#9c_*kOnYzpGq$kDwiDC9k{ICz$x1<|Cx(X%}Zc{ zYn-tG5bZ9q2+w^au}W@KZnMc~jsR^CxR&mf;S`xL)-=l=+{81ienN{H%)y4il~fB< zBV5sh!SLqbpipWHnQ&RSw!-aio!g5{Y|jAmK1*7Tn^Bd)l-K9b z#iS;0_|8vlV#!q%ca&-Yb-RUqC`a{J3(up*6^>tyF-0Esfp4*yR@#ivJ@?eB1^K5-*J5XNfT)dwmEi8y zo)!=^FEtt$lmivAQVbz6^Pq&4NtjCtzpN|DdYYoGa$u_1v?m~M0cN}kN>=rxLZS5Z zuM4|LsaiDIhB#Q4C3ao_jrAR`+PfxjvmZ=TqBr>|V5?;+Mar&yiDA@`i;JNiv6NPc zxB^$zgIWvB;9s*$vjr}EnRJkBz2syPs}j8O&Gg0$ht^+YHlK;urCirUgf-cTQzW*0 zOf1Q9`%{^ag;&AL8uIUHk=Di(lBy1#Lwa!f?3;G5P7EsoCf_28k&~olVhAP-D+K_Y z;#0)n7}=+_&V`QD{V;0P*eid9j+oX0fF?r+G&&o z`C&B`3z$q)?!YvqRM|>9vl#%d?KPq?6JEhVf#T*6#WvPC2;lR3ds;_pwN-l*CfLvTByP${+Idixy>95raI3||3^@tJ`w#Om zir8+XA0=Z8450ealRrn(1_Hk!M%Qv+!wJ++?yJ&`#9m76y6xzN#$i%&oN%f1Cb+Z^ zM3a{B(yGcLg{Lzd@`S@L5>eE6t6?jSWCUR|yBYRF-K)!D88xzAge}VgcFpVQE^|1Q z(rUC@i<-?`m8pjd)WGD1IKbqYEB?b0cElr*oK2nE?g$?KY0%YSh1U!uGe*0SIL^8Z z3ENqeM_(gFBVUhgyk8=Q+vY;?-ort6BiF0!%G4W)&C%E1ZvWk|RMEe(@t z1gVjm&HSGvU8k))l4!V#h0JTT)ON8Ib2u%nilR2a5(iigbRyI(g^~!%k~iek9l?}* zH5MaXWCal$jZ&Eau)1f$rU0rvlK)gc?ZnGb%38%loL{|>(x`bA{AQL)XZn>)_3S_xP_R#^GtIK8Ty43)%t1(o@`8#4rKvZ33d*GJ=b+XOg8~v9 zRHt-9yw5y)_1dpE=i|86j|nq#laD)Z6OuNVaVdCfuiDQDcc- zFISFS#u)L#ECl4)qsJh7Oyz`%P5d8^yE+6Y7v=p_@*7_a3otgn39{KmGxg=K@Mx`7 zrq}oWD!qX&Zh{=vT>8}9)iK0QO)V=Bss@HBgv=x}W&Hsj&224lFsfmXiC8HMaI1c7 zB7!^JhvVI-B?o}?Iv;7VZH7<Pz5{?7mCS z<&!-!%cSaJzsX(_=S@p7h?ON3qR}b@5S8-wco+vOap`?qVBHvSB!*IKu0sMSUw&dq zMigMffbuVIE`%Y>@ApfSIaU+_c#`wddwC;fo~wnjl4AdZ$SdgvLpLdSGW-6>jl!t! z2VNlnQ&0XB`!EbfIbc>}!SZyvm;`${A@c||9s${OZ|U>O^?+8s%pKSxVtDUu<;)tT zk~p7=C5Y@0Wx#F%bUPv=l^-p)tTp(894rlOb37i}@+ z*V+s@7JJ9*#Dm0erAgQDBDlF#y%trETF6J)x&tdpxOOps=y>XkT^TF;#gvXjK2&sw z3p$nkNy8AWPJLaE6$wMRD3Uk`f8QQdhhYdwGQ9WI&T!}R`E)ut=eFDJQj>M+&Ifcp zU(V+fBJOs(Y-uc1nMsZx$1{~Y1;^&xC30igu$==70KoBdJRMKtIBvEZhwLNWW}XA4 zd+Fqd!(pE1VHkG1T~|2^wBPSDpW859sC76TE|<$Vj@#|_=Je*hKOT?X`@m;?MQ!6m zfzLEe&2O?BxW%|~IPB-yPt&y7Y_jJ-+)$UQ@@ZX_xxDwzxtEuh;Lmxy>O5$rydo5$ zyIjua^VxgaZnxt&Nf?F05QGIm&@^Z1i;N^ z8ppAAre?!_XWfCQ5;~$K&xb&%-cmHdAUZYVR1(6;$@ysrxO4r zryxK3@U8RCa{@|C0=S&d0nR@?Jt>)`C_T!?jEFfHI#ek-0|vu>C>1yy4(IcE8mEVc zhxOBx8k3z)r_=E?jKhlHY{`<6)9G}Y=NZujXU{lED}_NelS1$rh6Q<4WY=O5F`SYh~+Bk>X?T!_QlwXTc+bjb30G9~%ultvmmxsrPX_|1vqU;)r zO75&%FwgUTzdsxf(=@#?!@az`TrQXGb~{beI9~m&KJR@1EQiD4_4W1X=_$x#VXIZ# zUSD6&=ksQ>*=#m98`M+R z*&sq#S~r9X!JqL40O#E0a(Q`qan1$j=}6w_aQGA_&fb51dGYf+PU8pzKu%h@cCn`f z-t)!6`*=LPzP`@hkK-6ztRs((IP3xQ!{PAp<3|8^|NcE9I_F|iT^cwJ+X&!vJOw^e za8l(F(DsWo9SJR7E|*WAKaa!k`1JVj@BjehJ($aJ`7JP#l|%GIudlD4K79(YGVnoH z?@DX-F$;b=pI={Ih-kar4#QxnMNPLj7>*QR-}!uY&JDw`-Kt=yb3yDJyAt(G5S%o? zwP6_4Jb01vN1IQ_)7Rg8z1eI6f?RNRX+0T`c<*0cUiSO_X1fi1co(eB2{aSWAQI8b z%gf<#*zI;HSs0UV#Rn?;@Ta6L2 zs73xzeVV3m9P(G#%SU@jFVxFk=bwP+#&MXY%{Y$3zPe#WPPiDso7g=ahI z6QNVnG!4U;K9tp%rD&6p&KT0fH<#?eHiHm!sua)tI z!F-&zdxRf4cd}_-7_V_0AlZX_Wav4H2K1K{2h-esx zP?*-(j+6&dJVZoKo`BSCTUFSIX(@!dAq3U&)*A{40K+g0!{COYz9T3SqQyJT_EKg| z5zMj0^1M}keFled97Df?pWb{oZW>2QDGUg3yWRfsZ+^u~gd4?|%O!-EbxBSD*nIYK zna}4_H4%&(2Uyqwc>v0*y!V&O97ZMl6n+FiV&#g`$vCY`_bljqzRZ`)IE`Zrnhkua z&X5$Ur02J;8qf0_CivqxhV``D_*^cR%;zn6E^MX<<9=;j@^Nt=l6CgFqcVcbaOo0V zE*BzlZV2%%l=FV}-UHx}Z;+&F`3`&>uH+=)4!@pFE<~v)PE05cfgl+3Fbv7WQWL0N z02M{mFW?CAk?3?j6VWORUPol_iO3B@&`($mM!jyfOmUupFkj}&d_lnMU$#?P)2D#G z!>U~{Lg#R^*@Rxl?Td&-JqUXC#+)k@xm+&Z&xmdq1j0^F=H)o5;HQu(T=w%!L}5aZ z^(^79g1UtRv9BecPABjE=rfw>B~q0O;@bt#}dzVZ8VKRgFG{HfQfI=kqvC zgL6Or$#2;i?#d|H)-Az2&(0Nems+5d%du`a za4b-&6QvDnSZ1ZSXOz;&P3wwxq?`HYc~->) z&yqbQ3`AbCA-p_`F~yO0=m63CIV^W4`-*bMOh(+8kR=g@y(r$F&rz?V;g(ZzZE+4) zB{|Cfp**D=1oY@|%4LZtV0ceuc9Ms_TFoWhXj6W5Il~3zy-nGS$xwX;Ikyxj=NZ^m zDX!;?n_GgDaSr$$#1KXTY-;vL!i%_GRauL$whk3g5Qc>i(R=dbF;2D{R+K8Dd6kW_ z^|L9IF|BxW3=DWHb=7o`++}Sw;Sfo+IfQyd%s>Zf#j^?}nQ=*~lKQ-)#3Vi~5R#qugor?%FPx$nO=5pB z*<|S?0($ZQ5VB^Y@gjo`5(y_K=m$g*QY?l!UW@0L>Pc$WgB1)Z1Ea_eJ&*{RD!paq z*||tt1gntR!Q{)OSWkPGc}B#+xv);&TM)K3{_(ZAJTKu+&(iinH0OOG@`#Rq%9KYd zg>v{Z^5BLt$&*i^a9%CAkhm2=l3Er7Y2%D5s0L%%<`Cmc zVVgJfu8Ei`Kkx%`ZjiaEE}WUPJk&T(ltWJ$Af-2vD$|h%a)3nSiJU`JZy8k8jIPF5 zfZ>L+Q;E1rjcvO7r0tDKj)SjTSRwkb2U<j}7247VFx8&?! z4q}JQ!2=%w;4lnqbXj;obJ}A35WI4a&PDG4| zan}|3^t6Qv9%PLg004Li;aTw3y`zXVr8`UiOV_B9Af{#c64Rcu<>{BoZFOm-wv@p5 zjgYKwR+v;J(Wm@$dMOca%{U#gc#i5sLCIfrq!m?#0I5iRS|HRH_eTPFLTLjg=SrfG zyca~jE14RAavKX_%@g0(-0`F8ARouv#?fb+53({OPqy4RxW2I73@TKHj{=2VopoTX z&?RSw1tqi~P5Y8+C#~R>JMeFyx97{8NN&rNAt;Q)fX<0+1pt|CJedKX>a_I6tmWEm z0zfhJM)^-$O428cG5`qz3Va+^EK{Q-?K70iiX&-BMLtT(P`RNYNEJH);ub5+ZW8T$ zl?@??s1RPXk%j})CK~O^$f_$M5zN^~n?dj5kn&~$O6V1b)wzT(nPg38!?s&B)U8i1 z+#EIFbj41Vkq@7tsHDV1`L`0pr5iuI2Ab;7b)(5)Mr0%qK#Gm_LmB;`K$La90^q-y zG)zfpmWcR6O3Rxv-xfMG0%R#h1)Gw3Dkk}SPIAD`@P>4^NtVm-#It@0Oi7KJinThg zu*5orDTMfTx>u6Bjf6_-y9NAA9l4VZxp6SY98ed~VtDcz@%v@eXv$Q~!IISnV3mbE z6KgmJ7qq9XhB)$+ZHPw678Oro4-xafDErNaq&9Ey+)qepn35ZE;bQVkJ4Q^DlTK85 zRp+XOktPCcSThGtu`F>kV}M@XY!-w)bKfki`sh&Uv?>gihO2_mC}QG9c}j#WC4bPE zPq16PuYR3@)u`_NRQq1>x@yc`>w z%1r?itL8RIc14MgRh7Db|3K-QUR+__wJn%$7K+4&ntvLmMTVGPgPV?_;EhIJ(w#swy4Eaj^6N*Je!^93>cUbZ=Jzq0H5dk6 zR_3*Y)d7GoN}f%UmLt?369-AXof z11MG%NEWV|p%f()>MKsbF=C#>)kQ0=al~~}hh|3MToD?JZM++?7-^6PJv zin01@i%?YBk5Wt0SSdbpz?6sy$QwOwiii9z(4ENyBebHw-_DIeKBCwdpbQZWv@Q)1 ztAkL25=0EwP&pHCwQe4PX%3hQv&ib$1j0NP+y>IWYjkBVR#`VOHL{t3vJb`zr3o!G zwNm8Oj;N+EwSYSEBId1JrKAyTNmpJaDl%nRw!OfFDtW=mG0J6mfo=!}00R9M|8mDL zmZ$)M<|#t~sw!wntVQXd=?paDU$M2j$F>N9sUH%#sKQ-ZGibU3EQJ;WT5BPfn}C$A z@-tDeO4eZfjTiO3fw=kbthT0^Z*%L58d39DIaXbahZSy=#Z%c2p8SLyoCG$tvuD)_ zUX1&N^1D?5`8!Nz48Jc~a9UnzK_a|SE;AafpfuEk&0#K)mvlr1{^jc^#ySaPDYi;^ zGhXKKA`7!vxL+&@2LPxSQJ7Eiv#N0wzumTyKHmruXII4)1g7FO7`O%<3(bV|K)kqagze(1xfu#7*BTJ0 z79s1lQG2W`p8x;`DM>^@RD@JhQD#10v1%gQT9W)dWV@CwG5<&EJjcb$v~svaqYIo? z0EJ~dR?ji+Ov+jpLuq~KTYY>10IGC>@+YVXnM@rjjUhYFIb(VaId3EGLjg+*Dn02( zUg{Qjwfa2oYZmiM*}#_}?vtyt!Rk~f*)rX>=M@I%5CxdPwVF}<*OsUmGsC+Dvhl?@ zPWnbqF;No^nsKvl6jhQ)Q;93@j;nAk403&rrRt1L2qy11&~m;e%|P~)Dk}k6<4CMX zTTeBPBKFI!*GaM+nJn`Q=JZ8iZ_5o0>|GTV0IjEHH40x4zw@kcLo@A<9o%~@H8Yl( zfhQ`GS5>VVDYxcX#Nl>2j<0RamsENxu+tn`l0J#DCd#g;zEXAk#pvzN)fKva{1-F6 zD5tVM8fMX`V>QAm7@k~mJR3n55L#$0uryX-OCpb}l#{`e0 z86p}`fvlg(5qSQqQ6}%`KP(#m~hnNGMBrLYN3W+w!jFtBxH5mF@9d+CE?PoYMIn{Uy znEAK*i`6Cmn#wva5yyZkB`P^e`zmjl=2jz4US2uFKT=xTxvcbtPTE&c4v7hiyRxwY zhTAkK$y0?i@nn?DZMg;ULPlwm%$z!bM%pCfX}wgsPsAq^JoEM|n+D&jV)ceQQN9ny zB_ROuwtj_k5P-h`tcH+R$Wlp0sVvt;?^CP!tsTS$(N55;nd*AU_AQWuEPkvH9xd%8 z3AI5reu>oBXni3)-$u&QboW(&SZaSc!(pNuWVNV{U@FBd!`}26Rn9Y1M>e`q0m*Pn zZZnf42P7hfn8_Ec!KLb$V~uZx?!2~qjrFcATkDg=FAJ76^2d!5i01N7y{4#3W@{iR zY<(+^V`gC`&1pefPHBTFrN&=tQ@qiw+E(92@?Aw$Yo5&?fR$R+bQzfRqK&SRE4WGK zT}zc$5Xvh&qGaY^m31Kmpz>rAbRSOOS+wGZoe!5^mDqT5-BU$@%7Rw6mHYa|)0?4H z6|$G;+n&RvccbJvjtCZ^NULfnmfvj2-hn2HWh0c4GlS+>MOhVAq6pY!YO@9#Do(G; z*WY2f-o2JO-%#|KepJlSYK6#47g7FSTvhL-T&G?m3Wco5awAm= zs+k!0?kd9KLS0FXu&jZXdb4ZF5Da3H_cNEBJVlRR3~byh^M+ST)$#?Yn4Vcr;brkY zC+A6gwYi;Q^c4ySsfC1ZL&$mn+Llr8G$|}ttBuy_3L{=eeCWh5OI7P0c18IAli~6k zhnbp`zBr!ZXY$*&C>?X-iQhqG$%UXSi-cm)d~1xB1CU5>BxMmeuhg`jWJvvpr0>$KBN@SO6k8H4Bybn`LCmuOo6u(@3E5ynU zx-2mppgK)(RLU@|!0hp}A^9?)a{&2e8?ex0*2E>AkC+h#u_rMYaz3~CvxWjRSdKKeMM0Hwlf@CN$2^gm~twZVtNUv|^ z6FAw^2-$PwgmfSSPlVO%@f`$i4=CH`5W^N*P`C+Y*0OE-0z&ex*|_nuOjO}Xr6)mjz@@;||SEv6JR=N)^0aIIz6wc4|lGmLRTitrm zE>CG#>8O*ubHQnv?kwi_^gVq~-_!T>J$(o0{{d5*KxlfS8sY!|002ovPDHLkV1kMh B$N~TW literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_01296884686849f0dd6a6f5f6e642ce4594a1438.png b/ltximg/org-ltximg_01296884686849f0dd6a6f5f6e642ce4594a1438.png new file mode 100644 index 0000000000000000000000000000000000000000..76e7c5ae05dfeef36bd4fb045c4912f636f96acd GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^AT}opGm!k*u|NSx83g!*xT+~BzI%2#IxL{9AR{9w zdSX|DuZPR(r86GhJbrBddIuYe9UB)n)fQhqz1v7nXYTaw4LS9_AcG1#B8wRq_>O=u z<5X=vX`rCBr;B3|^U)W}FNc13WadKJ_C*iq}AQa5JAsD1MO%97G+!f&HQ`dCQ z(^CcW9J56%a$qV$N;feIN~wrFQFx&1MyYl2@zw8OzlcWMnA~t(oCaJ6rr|()9+Mv-M zT1TLV5~FW>mOy{*2hdn@$@p3n_V?U^-}IV}kfgm5eF!I(gDG?n3Qr?5azdV}(YN~# zz{~qGNhj`DZ#;v|TP(IwjF<#ohZSrO(M54iP894#gqWw1M>$#fnPprqTF2Ja?uWT(gwAtC)L$mdM00009 za7bBm000ie000ie0hKEb8vph z0@Rd{KqR;70DUMNL018hEUXxoLz5NcdwEWh(W0@54nHs4%4bF9p_!Ul=p&P6CXrn5 wAAcLx_9Xw#+wJK=cIJzxL; literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_1d6de057eb18f33d9ce2df46505051a77488698f.png b/ltximg/org-ltximg_1d6de057eb18f33d9ce2df46505051a77488698f.png new file mode 100644 index 0000000000000000000000000000000000000000..1958f4c2a4a7d5401aa747f9bb551386317cfbe3 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^ftCJCJ8o0yoYv7?6Z%##G88`~Kf^3L)totnf4w1a`c)78&qol`;+ E06d&URsaA1 literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_205d81a43ad57fe5da4c786cb565a1a6ab8bb626.png b/ltximg/org-ltximg_205d81a43ad57fe5da4c786cb565a1a6ab8bb626.png new file mode 100644 index 0000000000000000000000000000000000000000..b766082a815c7685973d23f00fba81dab0bebd78 GIT binary patch literal 468 zcmV;_0W1EAP)Vn$nK?Z|EiyJ!R$8E;q{qn02rzHg@rAkEsE;nKvnx^!dQvN08Cf znO6H$r1oiLn@#8wxmZkM`nnO0j}~wxf>^&nO^Vb$tsD^F^I>z20w~o>fnVoW`d+k* z*DH(hdd1>e0Wp@P&;L9}-$+b2yjZWF&vNt=63|^U)W}FNc13WadKJ_C*iq}AQa5JAsD1MO%97G+!f&HQ`dCQ z(^CcW9J56%a$qV$N;feIN~wrFQFx&1MyYl2@zw8OzlcWMnA~t(oCaJ6rr|()9+Mv-M zT1TLV5~FW>mOy{*2hdn@$@p3n_V?U^-}IV}kfgm5eF!I(gDG?n3Qr?5azdV}(YN~# zz{~qGNhj`DZ#;v|TP(IwjF<#ohZSrO(M54iP894#gqWw1M>$#fnPprqTF2Ja?uWT}oL5)0sQHJ31_&skV5>#>EeB9>08g_msaEB7k~13p^r=85sDE zfH31!Z9ZwB;4V)W#}En0%^_nvfXB`9z-KQ>>)Kq#TDwcUXCN zc1uX?5Ndc+!q&!phRdPNFhG97;qwPL7wzP}p~t}L*v82E+$g0vV;-vx|AVGEr+XVF zi8(m>F|K$JqQJ}IGndDPwP31`Zi3^vs|v=ARtM6Gav8Xr&hRA!B`|Z5 z-4GfYxqtt`)2GiBigOiD?@*Y|)9mlL^$wS>O>_3^eQr2s2LA z=92~rPVjVb4B?Pf?bYQw(vdj{*H zXUDj5lnxg-^4x#e93y4p^Yl&P>-*E62i&>+wbZjek4HWve$%7REUTrMotKM|ihyWhTgJbyf_-y#aA?!ZyG=+$Ks-2GR#4&D$GEYh|NTNl00009 za7bBm000ie000ie0hKEb8vp)j|8UO#o&Uf& zuqY>3BsL7KtDo7cb}}(2c1Fi}z0j`KHC(Et>t3i*DcfAFOwP#c09-#av3Q%F>bH2J<7G5&^-k8%^M0>s zVyDFoG)OsgRXy&LIiVFG3Q@*(Vq%MDFPkbW{}i!xUz;Fd4gJD$&O1C{M{PP|W_}_M z{I0hZ$kpHjaWqN?5Scr_QkC`RlW(5m<=Px# literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_3e3ac398ecab748a277726f7718afae46fe8b82f.png b/ltximg/org-ltximg_3e3ac398ecab748a277726f7718afae46fe8b82f.png new file mode 100644 index 0000000000000000000000000000000000000000..3774d30b8540909084be0347a749195258ff5fa0 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^96-#*!VDyNv=5yCQn~>?A+BmlitnCXHqz56E6AAG z)es#P;OpU%kre&#=5Yrbi>BJ*)k|kwKD~R##>I1|ceDGbfK1^m@Q5sCVBk9f!i-b3 z`J{n@YMw5RAsn*F0cE~{2^ue+7$qd!J}~#dfz$(s4;-*o%#&i)KfH&DA(Ds9_{*<9 Q0ze%Mp00i_>zopr00QDSq5uE@ literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_40fa37ebf75968e3cae8fa02423eeef19f520817.png b/ltximg/org-ltximg_40fa37ebf75968e3cae8fa02423eeef19f520817.png new file mode 100644 index 0000000000000000000000000000000000000000..d83ed6a22b88c4e4e358147a9a200a300e774147 GIT binary patch literal 350 zcmV-k0iphhP)Vn$nK?Z|EiyJ!R$8E;q{qn02h z0@Rd{KqR;70DUMNL018hEUXxoLz5NcdwEWh(W0@54nHs4%4bF9p_!Ul=p&P6CXrn5 wAAcLx_9Xw#+wJK*dVGK_Fg9&&bCi{tAR;Ncy1ijyXP}{^M@dhvuCa!QjK|2zy1^v*00009 za7bBm000ie000ie0hKEb8vp|^U)W}FNc13WadKJ_C*iq}AQa5JAsD1MO%97G+!f&HQ`dCQ z(^CcW9J56%a$qV$N;feIN~wrFQFx&1MyYl2@zw8OzlcWMnA~t(oCaJ6rr|()9+Mv-M zT1TLV5~FW>mOy{*2hdn@$@p3n_V?U^-}IV}kfgm5eF!I(gDG?n3Qr?5azdV}(YN~# zz{~qGNhj`DZ#;v|TP(IwjF<#ohZSrO(M54iP894#gqWw1M>$#fnPprqTF2Ja?uWT{8<*r=0rl6u(Rojr8 zU+nJfzi$1;UAy)srlhxZ^h}vH)6&*S*T^h5ENa2RCDU6nYJnO#3p^r=frcFcVaBQ2 ze9}O{37#&FAsn)*y}Epd90XeT>+Dw4xnP`gNlQpZXd_$vVO9%A)goJymx8YheG61n zA_6#G3COh0{HFTe|BQ5iPVvl9{&tQG@ z>=;*$(%}L}p8F4*W29_+p1w(ZeSiA%fIGLpmU{N*@yLh7Z#oy*(J8_iDblwn@reBW Xw~`tKdY2M`Ze#Ft^>bP0l+XkK^^Rum literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_6026e5c1fa1d520353950d71af186956514e8701.png b/ltximg/org-ltximg_6026e5c1fa1d520353950d71af186956514e8701.png new file mode 100644 index 0000000000000000000000000000000000000000..72012fe4b7fa39f1b6a2c5d01d2fe48770f6554f GIT binary patch literal 407 zcmV;I0cie-P)*dVGK_Fg9&&bCi{tAR;Ncy1ijyXP}{^M@dh|$jYv+v4)6@3ri0_00009 za7bBm000ie000ie0hKEb8vpw?Fl7-8aZ6w>3A*<$ zWN_y@Pt6<%jM4Q-WUjoHU`iI^0gZYJL|JymS^bq+*hC)D1-ym`4wkdV*r#f<1}A<; zT?wQZ9ipakJz-O@g-?}n!`pvPTKZ;uA#N2VE@&9!ngnsrQNDVg?@L{=Hgq|iQuD@} zZGu82J3{UmyD$7hc}Nq*jN-aP16GDFYt&gW?X?_wfUrhf<~S$ zjv*Yf$q7cB#n%&NoD?|p;J}84M1BF|4><`8Ow$+yPQGGL+R5K=;K0b&bWMf_p$x!AKpBkkreIg;S#uMQYTO&XMsm#G0?yxAj~*b zn@<`j=;i6+7{Vc&oRDBt#+l5})Wy)2>Cjaw$lPo_;aOQi0tdsTE-nYB$&CxyJTyZL z42~EWY+x@iFenf)XfbBUY|}<*r=0mY9?t92%u- zV76}EMoSx~DN|=w)ifw5X|{FrxO@8N<`pkkxa9bWQ@eKUeLqW&8>pAFz$3Dlfr0M` z2s2LA=92~r?(%eT43UsbPHPvjXs#Y##{%5ivfhn0tC zw}iwFp@uglY;D|UxE$IH1LP+hK7W97(N69gdJL?NZH%nXjZ&I3=CSJVKWLhBy0>AH zn1iDq7RERl+Uf_-yaR#3*juhYxBc5rB&my4^Vm`zATKs-2TVq3Veqv6@d;+NOX00009 za7bBm000ie000ie0hKEb8vph z0@Rd{KqR;70DUMNL018hEUXxoLz5NcdwEWh(W0@54nHs4%4bF9p_!Ul=p&P6CXrn5 wAAcLx_9Xw#+wJK44=V@g#vIC`KUQ+L9_O%;qC zJRa>FWiOjD&T%hw*fcrOl)0ISnfW)9LVM%F{)eW_!p>HQBMtf;wHaKZ4gauCnr)$$ zb7LCAqviPwLXKy+cU+dZvG%k?o^}I^}qJL zEjH5Ai4F@mwtxNQ)4S(R?_RxhhOdWzopr0Dan9bpQYW literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_81a6befc0e7d8c06857316dc32fb3d6545f3e479.png b/ltximg/org-ltximg_81a6befc0e7d8c06857316dc32fb3d6545f3e479.png new file mode 100644 index 0000000000000000000000000000000000000000..c0b9e3c110fb682b59e7348ba6595dd52c6fc5d3 GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^ia^ZA!VDyX4KnrvDct~{5LXdNxhq$$C8nfT)i&hj z7b~b}x_kStTfcGFuDxv?JyWL5w6t~7H8Kkhi(0U7N%farO`t~30*}aIpkYTqm~pB$ zpEOW#wx^3@2#0KPLPPUv2eH?z64S4?H0m-QxydG+=*j1bqOD0Gx+jSssW4|FDjr>mdKI;Vst0CCM)VgLXD literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_8aec0d26a12708fe99cdd5876863ff43a1c627d7.png b/ltximg/org-ltximg_8aec0d26a12708fe99cdd5876863ff43a1c627d7.png new file mode 100644 index 0000000000000000000000000000000000000000..9a68b0b39e7cf421590c944da7479638bb58c15c GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^5|}<*r=0rl6!*Rnw50 zSM2WTzi!>eUAy)sCZ)G^^h}vL)6&LC*T5_|G-|=ZC6V0<1wf6Q1s;*bK*NrJFymBh zK53xf1Wy;o5Dr<@UR}OJ4g#(Fb#^Q2TrkeLq$MOHw2>|TFsp^5YLTtUOTkx$z6B~O z5dj>p1Y}xgep7w#e?~e$r};!wu-whn=e;N1Z4Be?-H2QG~&;5tZF;X@@Pv0cIzCZnWz@6J)OFjGZc;rLkH=T>@=oI0M6zN-(ctrmG XTS<)qy-SHew=sCS`njxgN@xNAe-UO= literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_8c4e482436a1dd4e34355f6ae5193641b99c4e3d.png b/ltximg/org-ltximg_8c4e482436a1dd4e34355f6ae5193641b99c4e3d.png new file mode 100644 index 0000000000000000000000000000000000000000..4e1ed32b250944c2d582ba739cf13a4b190027ca GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^ia^ZA!VDyX4KnrvDct~{5LZP7wP(*>6yz6ob@kR% zH|XjZg@#7%-+%D*>2uSj&04Z#xx1T>wUvERV%o+HTLN-cIRiCv7I;J!0}VR@!i-b3 z`J{n@vproLLpWrU6B?RVJBYnzm6(3DrBRph$W1okL{I()Oq(qem1KB$+7IL`;|);c zW@XD~dv`irb_eeQrI|cD!IBX(_KI)NO9(JCGfPY;NJ^+UAaH>7$|r_ZX{OAFgV@;k z+8Ekc117Suu}QNnuinF6p{C$cBv~|ho#6*H2Nwr3hZv?({_{!;Ci<{DY*G|ZUE{D? hLPF*NOGhIML!qNoYkb)4c%U;GJYD@<);T3K0RSd^TtWZ< literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_91ff4f41cef3c8d6b7c75380b409a7fdd5ce36b9.png b/ltximg/org-ltximg_91ff4f41cef3c8d6b7c75380b409a7fdd5ce36b9.png new file mode 100644 index 0000000000000000000000000000000000000000..ce50028eab7ee9ab45084b1b832d730f947b3474 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^fznb8Uq|QNuHZ^ z^gzM+(^-ZSrX(lqm?UtTZ(?Gq#*P}sGfxtXZfs{{$UDoobZQbG&<+L$Pgg&ebxsLQ E05+IL;{X5v literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_925319670cdf886edbfb7200e6b4dab22965b101.png b/ltximg/org-ltximg_925319670cdf886edbfb7200e6b4dab22965b101.png new file mode 100644 index 0000000000000000000000000000000000000000..2e186e24d6323751a39b386b83043c114bac4281 GIT binary patch literal 407 zcmV;I0cie-P)w?Fl7-8aZ6w>3A*<$ zWN_y@Pt6<%jM4Q-WUjoHU`iI^0gZYJL|JymS^bq+*hC)D1-ym`4wkdV*r#f<1}A<; zT?wQZ9ipakJz-O@g-?}n!`pvPTKZ;uA#N2VE@&9!ngnsrQNDVg?@L{=Hgq|iQuD@} zZGu82J3{=WX literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_93b88f8eb4efd76fc90d4bd25d1ed1b7dd7a5be0.png b/ltximg/org-ltximg_93b88f8eb4efd76fc90d4bd25d1ed1b7dd7a5be0.png new file mode 100644 index 0000000000000000000000000000000000000000..2fe28a6437365f9cf4fd3a084c4e954ac5da30ec GIT binary patch literal 407 zcmV;I0cie-P)w?Fl7-8aZ6w>3A*<$ zWN_y@Pt6<%jM4Q-WUjoHU`iI^0gZYJL|JymS^bq+*hC)D1-ym`4wkdV*r#f<1}A<; zT?wQZ9ipakJz-O@g-?}n!`pvPTKZ;uA#N2VE@&9!ngnsrQNDVg?@L{=Hgq|iQuD@} zZGu82J3{ literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_9f34d39b4a163d0e868354be903873bcc6d09644.png b/ltximg/org-ltximg_9f34d39b4a163d0e868354be903873bcc6d09644.png new file mode 100644 index 0000000000000000000000000000000000000000..3c9efdbe092703468000c8b29a7d863d74e0bc6d GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)M!VDz;D$H~RQtAOdA+CxFYR{g%aCh@bN=)nO z>b17Auc>ZWvShigj?wAU=L+(RH*VMx8XDPu^2Q>d7R~~X$YKTtz9S&aI8~cZ8Yrmd z>Eal|A)B0F#OariknE|IkdY9ckdW{oB_rX)rZm0;i<(nyj0|4AtlK@G_Jjg;FnGH9 KxvX_E)M!VDz;D$H~RQtAOdA+BmlitnCX_VsYdNQ$1= z)!<-b(NtT!dg%-!J)O&^cb64p?AW+CIxJwv)`gltEt~}&k;M!Qd`Cc-ajG_-G*D2@ z)5S4_LpC|Vh|@12A=y(aAtNC?AtB*GN=CwoO=)}y7B#2Z7#X~JS+{#W?Fj|yVDNPH Kb6Mw<&;$T5H!^bo literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_a38b7f9ba4927f1b464c9524a68d0a691854379f.png b/ltximg/org-ltximg_a38b7f9ba4927f1b464c9524a68d0a691854379f.png new file mode 100644 index 0000000000000000000000000000000000000000..f943f6e160610640131b5d9fc1b68518e869c3ec GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^fC_}XpdAbhp00i_>zopr E0AOOkzjGpRCucY||MOmN!0U_{^lo#%5;F-r8u~ z$a*L-C?VklOD6Nl0*04IPsnIX9A`fBskMAPO8k__kd1m7J_d6Nyam%-E3&t;ucLK6VYCsvRE literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_b430ab391bb9b6d4b8ba2c1db82d8eaa789b83b1.png b/ltximg/org-ltximg_b430ab391bb9b6d4b8ba2c1db82d8eaa789b83b1.png new file mode 100644 index 0000000000000000000000000000000000000000..53810440f0fec5395437438ea50afa44f751e25d GIT binary patch literal 407 zcmV;I0cie-P)w?Fl7-8aZ6w>3A*<$ zWN_y@Pt6<%jM4Q-WUjoHU`iI^0gZYJL|JymS^bq+*hC)D1-ym`4wkdV*r#f<1}A<; zT?wQZ9ipakJz-O@g-?}n!`pvPTKZ;uA#N2VE@&9!ngnsrQNDVg?@L{=Hgq|iQuD@} zZGu82J3{OjoR!VDz&9(Q^JDT4r?5LY!N#dpsxH`NwrBt@@Y zI>Xn)rK})h?(}X48;i@QcTenUhz<)lwtu~mp3aVqiyz)R&T{ShYM@@u0*}aIph-tS zm~pB$pEOXg$lY1KeGfmjtnS7|vWP^eB z1+_3%Z9awmySsW0ODvkk?4cXh@bR7#%R-eY>_v&!R)wBcSag(!fp4+c4c$+^ML^du Nc)I$ztaD0e0stscV|M@m literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_b9a5e90acb8406cda2b0a9e46f45738e7fc64394.png b/ltximg/org-ltximg_b9a5e90acb8406cda2b0a9e46f45738e7fc64394.png new file mode 100644 index 0000000000000000000000000000000000000000..fa27305efb9d605111dfc87cc42c55ee4bec5dd3 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mg;3?#$mNPz@&1AIbU6&2K;J$s?6W7O5vTaaJ8 zWXbZR#I%hYwoIEg>-6b!p`nrPZa(|>AGEfzuc>ax*&zcmg|omTvY3H^?+6GpPSxg< z1`0ZRx;Tb#$R;NQh!yfBF)(doVha{Ho5--xQrzGS+egvMlgt}l$Otg9oE7Lw6k}#y sf0DJWx`>CzDkedcM>9ZkYOXlL=JnjZDX%|X0UF2P>FVdQ&MBb@0OC_T>;M1& literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_bc3ebf35ab016a6c7144cc6250d8f0e85d777ce6.png b/ltximg/org-ltximg_bc3ebf35ab016a6c7144cc6250d8f0e85d777ce6.png new file mode 100644 index 0000000000000000000000000000000000000000..50f8b543537feabf2a0e644c29fe1f547580be09 GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{Y!VDyhG`#)-DT4r?5LY!N#dpsxM~4NhUOFQq zDf-y{^$s=`mrw7W*wygx=JB$EjHcRRUk?`}J)IpJ7tfvEy(_`X7pRxBz$3C4Xx5(HL%y9LN;L7YR+8=?oF?hQAxvXTN$X4v%n*=7--lL5N4dJ z%_j{MoZ#u=7{Vc|+N;ZV$U&fWzs_z&oeRb}m$Zargf_CpA7-_1R4uYKc`5kH(6>NE zB_e?1m4Hm^%x|ji{m)1T=ro^*3YNRM`n>nVyNzMoy&IAyniMyk6uez{zivlU_6*iX z&yI2BC><_vK0b&bWMf_p$x!AKpBkkreIg;WBr6_c57ui-3AL3p^r=fo2{7 zVaBQ2e9}O{U{4pv5DwYogao59&SZwBE{3*DhptjV=4R^&&&m=KI2bNGX6E^hoHN)~u``&2@TF|OxS$GX OJcFmJpUXO@geCyPO-rZ% literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_c206c0d84a3df817d72c9bfc9d1bed3d99b83308.png b/ltximg/org-ltximg_c206c0d84a3df817d72c9bfc9d1bed3d99b83308.png new file mode 100644 index 0000000000000000000000000000000000000000..5b17b7939df805e662000fccff50de742d79ecd6 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CJ!VDz8OuLW{q|^g^LR{696yH6&Y^0|%v8%z? z!{yli^>e3pJJ?ucBt@@YI-{&0BRVYL;mzYyR-aP?=`ZkzEM{QfI|9OtQ?>b|fr7T4 zE{-7_vdIYnVu=O5=?M=uq&!GUNO%ww@_->oW)9me2d~*r52z_zJs@zAVcE2%6|6iq j(h?G<4oS`sm0)-hz;WZz9QV~ggBUzr{an^LB{Ts5o8&(= literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_c3bb0e35c6ebe236afab1ca47229361e22b4e241.png b/ltximg/org-ltximg_c3bb0e35c6ebe236afab1ca47229361e22b4e241.png new file mode 100644 index 0000000000000000000000000000000000000000..0e0e17f39aa8dd1f533f9b7d027b7ac8d5272f7a GIT binary patch literal 587 zcmV-R0<`^!P)|^U)W}FNc13WadKJ_C*iq}AQa5JAsD1MO%97G+!f&HQ`dCQ z(^CcW9J56%a$qV$N;feIN~wrFQFx&1MyYl2@zw8OzlcWMnA~t(oCaJ6rr|()9+Mv-M zT1TLV5~FW>mOy{*2hdn@$@p3n_V?U^-}IV}kfgm5eF!I(gDG?n3Qr?5azdV}(YN~# zz{~qGNhj`DZ#;v|TP(IwjF<#ohZSrO(M54iP894#gqWw1M>$#fnPprqTF2Ja?uWTy7ku{G4MXL8cUVL>4nJ@ErkR#;MwT z(m+9HPZ!4!4%y^{fV712xrYxNcyQ`~+)+D5SHX?Cx(p9C7m;OXk;vd$@?2>`{OKKTFu literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_c91b4d45bde34f58aaec819408c75071c356821b.png b/ltximg/org-ltximg_c91b4d45bde34f58aaec819408c75071c356821b.png new file mode 100644 index 0000000000000000000000000000000000000000..f7291e6849288437c012742f5ef312f0e47c0b80 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mg;3?#$mNPz@&1AIbUMa1Q0-P7OF#%bNUjk*SAxp~E2udgZrHF6esL>4nJ@ErkR#;MwT z(m+9HPZ!4!4%y^{0I@>8BnGB!Ol-jdXA>C~T8bN-Vf!e0d6Id<3mE}Mma_s~iDJym t>rb+_RTuH_Sj8lW@@NKVPR$i(*u0+GH|6!mD?sBIJYD@<);T3K0RZ&BJ6`|* literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_c9200c4e7dce25a1e27e01e1ae86f4105c2fa2dc.png b/ltximg/org-ltximg_c9200c4e7dce25a1e27e01e1ae86f4105c2fa2dc.png new file mode 100644 index 0000000000000000000000000000000000000000..783e82cb297e450d5d973ba8bc664ffe4bb4cd7c GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^ftCJCJ8o0yoYv7?6Z%##G88`~Kf^3L)totnf4w1a`c)78&qol`;+ E0DJUB)c^nh literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_c92b1f9a19d301ad86f57d82beb069e849b679fd.png b/ltximg/org-ltximg_c92b1f9a19d301ad86f57d82beb069e849b679fd.png new file mode 100644 index 0000000000000000000000000000000000000000..b95ec95d822bb7b7ccb418399eff9e81626cd294 GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<-!VDy*{ZyC-qznRlLR>{8<*r=0mY9+r92TW( zWVUYoMoU|#Dbr?F)ix-oXts6qxO@BO<`*wmxa9bWQ@eKU{kker9H^JGz$3Dlfr0M` z2s2LA=92~r?(%eT43UsbPHPvjXs#Y##{%5ivfhn0tC zw}iwFp@uglY;D|UxE$IH1LP+hK7W97(N69gdJL?NZH%nXjZ&I3=CSJVKWLhBy0>AH zn1iDq_E)M!VDz;D$H~RQtAOdA+92la#yZgv$S;z4vVU) zZO}C`%gryIGHs@Uisr6edlOUA7c5-j?(NU;F(0UdfwRCPvY3H^?+6GpPSxg<1`4Wq zx;Tb#$R;Nkarz}BBztNlWF&+qBqTgY$w)Y{DUC0|qUKZ^BZF5j>vqqlJ)t0TJYD@< J);T3K0RSnEFV_G7 literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_cbbbbd9603cb09800c1ce9bd9e87995d7c609b1d.png b/ltximg/org-ltximg_cbbbbd9603cb09800c1ce9bd9e87995d7c609b1d.png new file mode 100644 index 0000000000000000000000000000000000000000..fdcc858a8042e5701ea942ef94296b595c6dddf1 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2ZGmxy8xzq=wbOU@sT-B5m-#xn=9TrelkdcuT zJ+Z67*TZG?(isnL9zV8!y@QR#j*W|(YKt$Q-fg6(b56&|9H^1Az$3Dlfr0M`2s2LA z=92~rI(oV|hH%IxCj^wGCL|x>FG@DYG|r0 zjt&dRNQ&OEaq-;g-Iq`A_VsXau(2pB$k?f9QV7yt;1OBOz`%C|gc+x5^GO2*O*~y3 zLpWrU69U9I6M#UQL5N3&PhnCqV@C*!AkRx49xfi9vphKtMOw`4%!kD$9=zopr0BoW$K>z>% literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_cc02e6245b6185abae501586409d2f30fc5fa61b.png b/ltximg/org-ltximg_cc02e6245b6185abae501586409d2f30fc5fa61b.png new file mode 100644 index 0000000000000000000000000000000000000000..61bf067e235da04ae183f4e8404690c22e259cfe GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)M!VDz;D$H~RQtAOdA+93ga#yZgv$Syv4vng+ zY0xz=%grmEGIgeclIE^mdlQq=7c5-j?&MNcPl9$VdoJNJw~)l96y?QyO1_Ma`);Mh355*6p58dqROa7(8A5 KT-G@yGywo)nlO$4 literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_cc9ee8e3dc18ceac67ab9b63fe21ea4ed4c0e563.png b/ltximg/org-ltximg_cc9ee8e3dc18ceac67ab9b63fe21ea4ed4c0e563.png new file mode 100644 index 0000000000000000000000000000000000000000..90299bfa797a5bceb3cf423d3c196fc278919e93 GIT binary patch literal 350 zcmV-k0iphhP)ZEkZ%Nl&h>vAVjwVPa>7h>Vn#nK?W{Eig7yRa&5-q{qn0s4O`=00009 za7bBm000ie000ie0hKEb8vph z0@Rd{KqR;70DUMNL018hEUXxoLz5NcdwEWh(W0@54nHs4%4bF9p_!Ul=p&P6CXrn5 wAAcLx_9Xw#+wJK&dSvj6}9 literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_cfec4e7d4520ebfff12e08231870330d66e166cc.png b/ltximg/org-ltximg_cfec4e7d4520ebfff12e08231870330d66e166cc.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2d4996e7052a9d36245f2ecfc3c8a92cee4577 GIT binary patch literal 468 zcmV;_0W1EAP)7RERl+Uf_-yaR#3*juhYxBc5rB&my4^Vm`zATKs-2TVq3Veqv6@d;+NOX00009 za7bBm000ie000ie0hKEb8vprzHg@rAkEsE;nKvnx^!dQvN08Cf znO6H$r1oiLn@#8wxmZkM`nnO0j}~wxf>^&nO^Vb$tsD^F^I>z20w~o>fnVoW`d+k* z*DH(hdd1>e0Wp@P&;L9}-$+b2yjZWF&vNt=63 literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_d856e3330a950cdef271d8c83a94b334a11a8837.png b/ltximg/org-ltximg_d856e3330a950cdef271d8c83a94b334a11a8837.png new file mode 100644 index 0000000000000000000000000000000000000000..010985677863bf7210bc99cc5057d22204b2e26c GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^ia^ZA!VDyX4KnrvDct~{5LXd#xhq$$B_^d;)imVh z6)Pxdx_kPsTeor7uDxv?JyWL6w6t;3H82Yfjasm93I8Np9-v0f0*}aIpkYTqm~pB$ zpEOW#wx^3@2#0KPLPPUv2eH?z64S4?H0m-QxydG+=*j1bqOD0Gx+jSssW4|FDjr>mdKI;Vst0BN~d7XSbN literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_df2f698fcba37b4bb5ca9e15873f9f205ca53b99.png b/ltximg/org-ltximg_df2f698fcba37b4bb5ca9e15873f9f205ca53b99.png new file mode 100644 index 0000000000000000000000000000000000000000..95039b141985c49d007ad62742dc924a7d7eaa83 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^8bHj)!VDzWt2&ngDT4r?5LY!N#dpsxH`NwrBt@@Y zI>Xn)rK})h?(}X48;i@QcTenUhz<)lwtu~mp3aVqiyz)R&T{ShYM@@u0*}aIpm|3? zm~pB$pEOW#s;7%%h=gQvLIabTM02Ae6UT3? zJl+yj2bxZ~C0uoQJ4ae#nG;JS)1|~F@!qve3Qco)R!d6!;E`z1YCLA>z;apgoRPtX zI0nwJgRJI-J~tR1F|ejLzwn#j`sP}yf?2=@PY#d5_2(T*)gy#FG!958yfs+Bkend? fq}AIvhJoRon8ey|lK)eH4rK6j^>bP0l+XkKyR~F| literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_e4d27eaf08385a5653d47c5353e882fec619834d.png b/ltximg/org-ltximg_e4d27eaf08385a5653d47c5353e882fec619834d.png new file mode 100644 index 0000000000000000000000000000000000000000..c7dc60beea10a7541cbbd6c34ad49433d206ef70 GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<-!VDy*{ZyC-qznRlLR=LU)Sf+iQIKDpl$d61 zWxs#_L3cNwB}O8+rn+I{hAlU5-adW$oaX9x&Op7K1s;*b3=Din zK$vl=HlH+5aF?fxV~B)ga)JYU&hCq@4K>pk6b_~|O-PL6d?L^ADOOTqQjWu;JFGlB zyCo!c2sOMZVQb?)!{yLs7$864@c9Fri*|C~&|_eAY-417Zj{oTF^^S;|3TB7)4dIo z#2g&`7*{+9QQ&3qnag9tS}@f|H^K4TRR!Zls{?68xeVM*XZR9=5}3K_5)wYNb~Lhl zzhUq}F5$+<6O2a~nKgJXvJ02ApIFGXsd?v}1kH0<9b9Z|{u0fNj2W^V3=HqjD;h77 SSUDf)3kFYDKbLh*2~7Y*kaJT2 literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_e53730ba461b03f192d1c5d7adf2c8ea141ef862.png b/ltximg/org-ltximg_e53730ba461b03f192d1c5d7adf2c8ea141ef862.png new file mode 100644 index 0000000000000000000000000000000000000000..658409187da2a69ffc4f51fb462724cd1946930e GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mg;3?#$mNPz@&1AIbUMI_~}T)C#8qFGhjkeHG_ zW!lW(u&4zKm$Y^C?Ao>0-P_;N)@j}Pjk-o=x%tIEpVT=3HF6esL>4nJ@ErkR#;MwT z(m+9HPZ!4!4%y^{0I@>8BnGB!Ol-jdXA>C~T8bN-Vf!e0d6Id<3mE}Mma_s~iDJym t>rb+_RTuH_Sj8lW@@NKVPR$i(*u0+GH|6!mD?sBIJYD@<);T3K0RS*AJKg{Q literal 0 HcmV?d00001 diff --git a/ltximg/org-ltximg_eddc76bce6183940e7887fa7869970cce9c992e4.png b/ltximg/org-ltximg_eddc76bce6183940e7887fa7869970cce9c992e4.png new file mode 100644 index 0000000000000000000000000000000000000000..61f24a892ed2b70cd6233531f731203c467f976b GIT binary patch literal 468 zcmV;_0W1EAP)ZEkZ%Nl&h>vAVjwVPa>7h>Vn#nK?W{Eig7yRa&5-q{qn0s4O`=00009 za7bBm000ie000ie0hKEb8vprzHg@rAkEsE;nKvnx^!dQvN08Cf znO6H$r1oiLn@#8wxmZkM`nnO0j}~wxf>^&nO^Vb$tsD^F^I>z20w~o>fnVoW`d+k* z*DH(hdd1>e0Wp@P&;L9}-$+b2yjZWF&vNt=63(gwAtC)L$mdM00009 za7bBm000ie000ie0hKEb8vprzHg@rAkEsE;nKvnx^!dQvN08Cf znO6H$r1oiLn@#8wxmZkM`nnO0j}~wxf>^&nO^Vb$tsD^F^I>z20w~o>fnVoW`d+k* z*DH(hdd1>e0Wp@P&;L9}-$+b2yjZWF&vNt=63