The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── README.md
├── lines.sh
├── pics
    ├── agile
    │   ├── kanban.jpg
    │   └── scrum.jpg
    ├── ai
    │   ├── ai_chain_of_thought.png
    │   └── ai_control_flow.png
    ├── architecture
    │   ├── architecture_c4model_maps.jpg
    │   ├── architecture_c4model_scope.jpg
    │   └── architecture_web_101.png
    ├── arduino_led.jpg
    ├── binary
    │   └── binary_calculator.jpg
    ├── blockchain
    │   └── blockchain_bitcoin_transaction.jpg
    ├── breadboard.png
    ├── comics
    │   ├── automation.png
    │   ├── dependency.png
    │   ├── dependency_2.jpg
    │   ├── interruption_1.png
    │   ├── interruption_2.png
    │   ├── is_it_worth_the_time.png
    │   ├── password_strength.png
    │   └── standards.png
    ├── css
    │   ├── css_area_desktop.jpg
    │   ├── css_area_mobile.jpg
    │   └── css_grid.jpg
    ├── database
    │   ├── database_1nf.jpg
    │   ├── database_2nf.jpg
    │   ├── database_3nf.jpg
    │   ├── database_denormalization.jpg
    │   ├── database_many_to_many_1.jpg
    │   ├── database_many_to_many_2.jpg
    │   ├── database_normalization.jpg
    │   ├── database_one_to_many_1.jpg
    │   ├── database_one_to_many_2.jpg
    │   ├── database_one_to_one_1.jpg
    │   ├── database_one_to_one_2.jpg
    │   └── database_sql_execution_order.jpg
    ├── electronics
    │   ├── khan_current.jpg
    │   └── khan_voltage.jpg
    ├── elm
    │   ├── TEA.png
    │   └── elm_arch.png
    ├── express
    │   └── express_middleware.jpg
    ├── git
    │   ├── git_feature1.png
    │   ├── git_feature2.jpg
    │   ├── git_trunk1a.png
    │   ├── git_trunk1b.png
    │   ├── git_trunk2.jpg
    │   └── git_workflow.jpg
    ├── github_commits.jpg
    ├── graphTheory
    │   ├── graphTheory_graphs.jpg
    │   ├── graphTheory_traversal.jpg
    │   ├── graphTheory_traversal_breadth.jpg
    │   └── graphTheory_traversal_depth.jpg
    ├── inherit.jpg
    ├── js_event_loop.png
    ├── mobile
    │   ├── mobile_appTypes.jpg
    │   ├── mobile_comparison1.jpg
    │   ├── mobile_comparison2.jpg
    │   ├── mobile_comparison3.jpg
    │   ├── mobile_comparison4.jpg
    │   ├── mobile_compiledApps.jpg
    │   └── mobile_pwa.jpg
    ├── mvc_full_stack.jpg
    ├── networking
    │   ├── OSI-7-layers.jpg
    │   ├── OSI-vs.-TCPIP-models.jpg
    │   ├── OSI.png
    │   ├── TCPIP.jpg
    │   ├── data_flow.jpg
    │   ├── ddns.jpg
    │   ├── dns.jpg
    │   └── http.jpg
    ├── react
    │   └── react_components.jpg
    ├── rfid_wiegand_arduino.jpg
    ├── sql
    │   └── pivot_unpivot.png
    ├── startup
    │   ├── business
    │   │   ├── business_startup_top100YC.jpg
    │   │   └── startup_motivation_pyramid_of_clarity.png
    │   ├── market_fit
    │   │   ├── market_fit_startup_curve.jpg
    │   │   └── market_fit_startup_stages.jpg
    │   ├── marketing
    │   │   ├── advertising_creative_order.jpg
    │   │   ├── advertising_long_form_founder_ad.jpg
    │   │   ├── advertising_stealth_ad.jpg
    │   │   ├── advertising_value_formula.jpg
    │   │   ├── advertising_value_formula_ad_example.jpg
    │   │   ├── advertising_value_formula_example.jpg
    │   │   ├── analytics-account.jpg
    │   │   ├── copywriting_framework_4cs.webp
    │   │   ├── copywriting_framework_aida.webp
    │   │   ├── copywriting_framework_bab.webp
    │   │   ├── copywriting_framework_fab.webp
    │   │   ├── copywriting_framework_pas.webp
    │   │   ├── copywriting_framework_pppp.webp
    │   │   ├── copywriting_framework_slap.webp
    │   │   ├── copywriting_framework_so-what.webp
    │   │   ├── copywriting_framework_sss.webp
    │   │   ├── langing-page-action-plan-example.jpg
    │   │   ├── langing-page-action-plan.jpg
    │   │   ├── langing-page-benefits-example.jpg
    │   │   ├── langing-page-benefits.jpg
    │   │   ├── langing-page-cta.jpg
    │   │   ├── langing-page-faq.jpg
    │   │   ├── langing-page-hero-example.jpg
    │   │   ├── langing-page-navigation.jpg
    │   │   ├── langing-page-problem-example.jpg
    │   │   ├── langing-page-problem.jpg
    │   │   ├── langing-page-solution-example.jpg
    │   │   ├── langing-page-solution.jpg
    │   │   ├── langing-page-testimonials.jpg
    │   │   ├── tag-manager_account.jpg
    │   │   └── tag-manager_tags.jpg
    │   ├── mvp
    │   │   ├── mvp.jpg
    │   │   ├── mvp_airbnb.jpg
    │   │   ├── mvp_stripe.jpg
    │   │   └── mvp_twitch.jpg
    │   ├── pricing
    │   │   ├── pricing_billion_formula.jpg
    │   │   ├── pricing_optimization.jpg
    │   │   ├── pricing_quadrants.jpg
    │   │   ├── pricing_rule.jpg
    │   │   ├── pricing_sales_stages.jpg
    │   │   └── pricing_thermometer.jpg
    │   ├── product_design
    │   │   ├── object_model.jpg
    │   │   └── responsibilities.jpg
    │   └── sales
    │   │   ├── email_example.jpg
    │   │   ├── email_open_hour.jpg
    │   │   ├── email_response_hour.jpg
    │   │   ├── linkedin_about.jpg
    │   │   ├── linkedin_banner.jpg
    │   │   ├── linkedin_connection.jpg
    │   │   ├── linkedin_custom-button.jpg
    │   │   ├── linkedin_experience.jpg
    │   │   ├── linkedin_fatures.jpg
    │   │   ├── linkedin_headline.jpg
    │   │   ├── linkedin_recommendation.jpg
    │   │   ├── sales_conversations_phone.jpg
    │   │   ├── sales_conversions.jpg
    │   │   ├── sales_cycle.jpg
    │   │   ├── sales_expectations.jpg
    │   │   ├── sales_follow_up.jpg
    │   │   ├── sales_map.jpg
    │   │   ├── sales_marketing-buyer-journey.jpg
    │   │   ├── sales_process.jpg
    │   │   ├── sales_reality.jpg
    │   │   └── sales_time_spent.jpg
    ├── svelte
    │   ├── svelte_degit.jpg
    │   └── svelte_vite.jpg
    ├── uiux
    │   └── uiux_fonts.jpg
    └── vim
    │   └── vim_graphical_cheat_sheet.jpg
└── topics
    ├── agile.md
    ├── ai
        ├── apiChatGPT.md
        ├── concepts.md
        ├── embeddings.md
        ├── langchain.md
        ├── mcp.md
        └── prompting.md
    ├── ansible.md
    ├── assembly.md
    ├── babel.md
    ├── binary
        ├── ascii.md
        ├── binary.md
        └── bitwise.md
    ├── blockchain.md
    ├── caching.md
    ├── cryptojs.md
    ├── css.md
    ├── cybersecurity
        ├── cors.md
        ├── csrf.md
        ├── cybersecurity.md
        ├── jwt.md
        ├── sqlinjection.md
        └── xss.md
    ├── database
        ├── conventions.md
        ├── mysql.md
        ├── node-mssql.md
        ├── node-mysql.md
        ├── normalization.md
        ├── optimizationDiagnostics.md
        ├── optimizationEngine.md
        ├── optimizationHardware.md
        ├── optimizationIndexing.md
        ├── optimizationQuerying.md
        ├── queriesAdmin.md
        ├── queriesAggregate.md
        ├── queriesCRUD.md
        ├── queriesLogic.md
        ├── queriesPivot.md
        ├── queriesSchema.md
        ├── queriesUtilities.md
        ├── queriesVarious.md
        ├── queriesWindow.md
        ├── sqlserver.md
        └── terminology.md
    ├── docker.md
    ├── dotenv.md
    ├── dotnet.md
    ├── electron.md
    ├── electronics
        ├── arduino.md
        ├── electricity.md
        ├── electronics.md
        ├── nodemcu.md
        ├── raspberrypi.md
        └── rfid.md
    ├── elm.md
    ├── excel.md
    ├── express-structure.md
    ├── express.md
    ├── ftp.md
    ├── git.md
    ├── googleapi.md
    ├── googling.md
    ├── graphql.md
    ├── javascript
        ├── async.md
        ├── basics.md
        ├── debugging.md
        ├── dom.md
        ├── es6.md
        └── language.md
    ├── libraries-frontend.md
    ├── linux
        ├── bash.md
        ├── cron.md
        ├── ffmpeg.md
        ├── filesystem.md
        ├── fzf.md
        ├── grep.md
        ├── gzip.md
        ├── linux.md
        ├── rsync.md
        ├── services.md
        ├── ssh.md
        ├── terminal.md
        ├── terminology.md
        ├── tmux.md
        ├── users.md
        └── vim.md
    ├── logging.md
    ├── messageBrokers.md
    ├── microservices.md
    ├── middleware.md
    ├── mobile.md
    ├── mobileAndroid.md
    ├── mobileCapacitor.md
    ├── mobileCordova.md
    ├── mobilePWA.md
    ├── mobileiOS.md
    ├── multiTenancy.md
    ├── mvc.md
    ├── networkingDevices.md
    ├── networkingLayer2LinkMAC.md
    ├── networkingLayer3NetworkIP.md
    ├── networkingLayer4TransferTCP.md
    ├── networkingLayer5ApplicationHTTP.md
    ├── networkingModelOSI.md
    ├── networkingModelTCPIP.md
    ├── networkingOverview.md
    ├── networkingRoles.md
    ├── networkingTools.md
    ├── node.md
    ├── nodemailer.md
    ├── notifications.md
    ├── npm.md
    ├── optimization
        ├── algorithms.md
        ├── codeGolf.md
        ├── comments.md
        ├── dependencyInjection.md
        ├── graphs.md
        ├── naming.md
        ├── nesting.md
        └── premature.md
    ├── pdfmake.md
    ├── puppeteer.md
    ├── react.md
    ├── reddit.md
    ├── restful.md
    ├── serverless.md
    ├── sheetjs.md
    ├── startup
        ├── copywritingAdCreatives.md
        ├── copywritingBestPractices.md
        ├── copywritingDirectResponse.md
        ├── copywritingFrameworks.md
        ├── marketingAdvertising.md
        ├── marketingFacebookPixel.md
        ├── marketingGoogleAnalytics.md
        ├── marketingGoogleTagManager.md
        ├── marketingLandingPage.md
        ├── marketingSeo.md
        ├── productBusinessModel.md
        ├── productDesign.md
        ├── productMVP.md
        ├── productMarketFit.md
        ├── salesColdCalling.md
        ├── salesEmail.md
        ├── salesEnterprise.md
        ├── salesLinkedin.md
        ├── salesMeetings.md
        ├── salesObjections.md
        ├── salesOverview.md
        ├── salesPricing.md
        ├── startupEquity.md
        ├── startupFocus.md
        ├── startupIdeas.md
        ├── startupMotivation.md
        └── startupProblemSolving.md
    ├── statistics.md
    ├── styles
        ├── fp.md
        └── oop.md
    ├── svelte.md
    ├── tabulator.md
    ├── tagify.md
    ├── testing
        ├── jest.md
        ├── mocha.md
        └── testing.md
    ├── uiux.md
    ├── vagrant.md
    ├── vm.md
    ├── vscode.md
    ├── vue.md
    ├── wasm.md
    ├── webComponents.md
    ├── webpack.md
    ├── webserver
        ├── nginx.md
        └── ssl.md
    ├── websockets.md
    └── workflow
        ├── deployment.md
        ├── development.md
        └── environment.md


/lines.sh:
--------------------------------------------------------------------------------
1 | find src topics -name '*.md' | xargs wc -l


--------------------------------------------------------------------------------
/pics/agile/kanban.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/agile/kanban.jpg


--------------------------------------------------------------------------------
/pics/agile/scrum.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/agile/scrum.jpg


--------------------------------------------------------------------------------
/pics/ai/ai_chain_of_thought.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/ai/ai_chain_of_thought.png


--------------------------------------------------------------------------------
/pics/ai/ai_control_flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/ai/ai_control_flow.png


--------------------------------------------------------------------------------
/pics/architecture/architecture_c4model_maps.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/architecture/architecture_c4model_maps.jpg


--------------------------------------------------------------------------------
/pics/architecture/architecture_c4model_scope.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/architecture/architecture_c4model_scope.jpg


--------------------------------------------------------------------------------
/pics/architecture/architecture_web_101.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/architecture/architecture_web_101.png


--------------------------------------------------------------------------------
/pics/arduino_led.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/arduino_led.jpg


--------------------------------------------------------------------------------
/pics/binary/binary_calculator.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/binary/binary_calculator.jpg


--------------------------------------------------------------------------------
/pics/blockchain/blockchain_bitcoin_transaction.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/blockchain/blockchain_bitcoin_transaction.jpg


--------------------------------------------------------------------------------
/pics/breadboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/breadboard.png


--------------------------------------------------------------------------------
/pics/comics/automation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/comics/automation.png


--------------------------------------------------------------------------------
/pics/comics/dependency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/comics/dependency.png


--------------------------------------------------------------------------------
/pics/comics/dependency_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/comics/dependency_2.jpg


--------------------------------------------------------------------------------
/pics/comics/interruption_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/comics/interruption_1.png


--------------------------------------------------------------------------------
/pics/comics/interruption_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/comics/interruption_2.png


--------------------------------------------------------------------------------
/pics/comics/is_it_worth_the_time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/comics/is_it_worth_the_time.png


--------------------------------------------------------------------------------
/pics/comics/password_strength.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/comics/password_strength.png


--------------------------------------------------------------------------------
/pics/comics/standards.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/comics/standards.png


--------------------------------------------------------------------------------
/pics/css/css_area_desktop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/css/css_area_desktop.jpg


--------------------------------------------------------------------------------
/pics/css/css_area_mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/css/css_area_mobile.jpg


--------------------------------------------------------------------------------
/pics/css/css_grid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/css/css_grid.jpg


--------------------------------------------------------------------------------
/pics/database/database_1nf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_1nf.jpg


--------------------------------------------------------------------------------
/pics/database/database_2nf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_2nf.jpg


--------------------------------------------------------------------------------
/pics/database/database_3nf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_3nf.jpg


--------------------------------------------------------------------------------
/pics/database/database_denormalization.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_denormalization.jpg


--------------------------------------------------------------------------------
/pics/database/database_many_to_many_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_many_to_many_1.jpg


--------------------------------------------------------------------------------
/pics/database/database_many_to_many_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_many_to_many_2.jpg


--------------------------------------------------------------------------------
/pics/database/database_normalization.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_normalization.jpg


--------------------------------------------------------------------------------
/pics/database/database_one_to_many_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_one_to_many_1.jpg


--------------------------------------------------------------------------------
/pics/database/database_one_to_many_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_one_to_many_2.jpg


--------------------------------------------------------------------------------
/pics/database/database_one_to_one_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_one_to_one_1.jpg


--------------------------------------------------------------------------------
/pics/database/database_one_to_one_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_one_to_one_2.jpg


--------------------------------------------------------------------------------
/pics/database/database_sql_execution_order.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/database/database_sql_execution_order.jpg


--------------------------------------------------------------------------------
/pics/electronics/khan_current.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/electronics/khan_current.jpg


--------------------------------------------------------------------------------
/pics/electronics/khan_voltage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/electronics/khan_voltage.jpg


--------------------------------------------------------------------------------
/pics/elm/TEA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/elm/TEA.png


--------------------------------------------------------------------------------
/pics/elm/elm_arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/elm/elm_arch.png


--------------------------------------------------------------------------------
/pics/express/express_middleware.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/express/express_middleware.jpg


--------------------------------------------------------------------------------
/pics/git/git_feature1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/git/git_feature1.png


--------------------------------------------------------------------------------
/pics/git/git_feature2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/git/git_feature2.jpg


--------------------------------------------------------------------------------
/pics/git/git_trunk1a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/git/git_trunk1a.png


--------------------------------------------------------------------------------
/pics/git/git_trunk1b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/git/git_trunk1b.png


--------------------------------------------------------------------------------
/pics/git/git_trunk2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/git/git_trunk2.jpg


--------------------------------------------------------------------------------
/pics/git/git_workflow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/git/git_workflow.jpg


--------------------------------------------------------------------------------
/pics/github_commits.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/github_commits.jpg


--------------------------------------------------------------------------------
/pics/graphTheory/graphTheory_graphs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/graphTheory/graphTheory_graphs.jpg


--------------------------------------------------------------------------------
/pics/graphTheory/graphTheory_traversal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/graphTheory/graphTheory_traversal.jpg


--------------------------------------------------------------------------------
/pics/graphTheory/graphTheory_traversal_breadth.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/graphTheory/graphTheory_traversal_breadth.jpg


--------------------------------------------------------------------------------
/pics/graphTheory/graphTheory_traversal_depth.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/graphTheory/graphTheory_traversal_depth.jpg


--------------------------------------------------------------------------------
/pics/inherit.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/inherit.jpg


--------------------------------------------------------------------------------
/pics/js_event_loop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/js_event_loop.png


--------------------------------------------------------------------------------
/pics/mobile/mobile_appTypes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/mobile/mobile_appTypes.jpg


--------------------------------------------------------------------------------
/pics/mobile/mobile_comparison1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/mobile/mobile_comparison1.jpg


--------------------------------------------------------------------------------
/pics/mobile/mobile_comparison2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/mobile/mobile_comparison2.jpg


--------------------------------------------------------------------------------
/pics/mobile/mobile_comparison3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/mobile/mobile_comparison3.jpg


--------------------------------------------------------------------------------
/pics/mobile/mobile_comparison4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/mobile/mobile_comparison4.jpg


--------------------------------------------------------------------------------
/pics/mobile/mobile_compiledApps.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/mobile/mobile_compiledApps.jpg


--------------------------------------------------------------------------------
/pics/mobile/mobile_pwa.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/mobile/mobile_pwa.jpg


--------------------------------------------------------------------------------
/pics/mvc_full_stack.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/mvc_full_stack.jpg


--------------------------------------------------------------------------------
/pics/networking/OSI-7-layers.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/networking/OSI-7-layers.jpg


--------------------------------------------------------------------------------
/pics/networking/OSI-vs.-TCPIP-models.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/networking/OSI-vs.-TCPIP-models.jpg


--------------------------------------------------------------------------------
/pics/networking/OSI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/networking/OSI.png


--------------------------------------------------------------------------------
/pics/networking/TCPIP.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/networking/TCPIP.jpg


--------------------------------------------------------------------------------
/pics/networking/data_flow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/networking/data_flow.jpg


--------------------------------------------------------------------------------
/pics/networking/ddns.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/networking/ddns.jpg


--------------------------------------------------------------------------------
/pics/networking/dns.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/networking/dns.jpg


--------------------------------------------------------------------------------
/pics/networking/http.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/networking/http.jpg


--------------------------------------------------------------------------------
/pics/react/react_components.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/react/react_components.jpg


--------------------------------------------------------------------------------
/pics/rfid_wiegand_arduino.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/rfid_wiegand_arduino.jpg


--------------------------------------------------------------------------------
/pics/sql/pivot_unpivot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/sql/pivot_unpivot.png


--------------------------------------------------------------------------------
/pics/startup/business/business_startup_top100YC.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/business/business_startup_top100YC.jpg


--------------------------------------------------------------------------------
/pics/startup/business/startup_motivation_pyramid_of_clarity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/business/startup_motivation_pyramid_of_clarity.png


--------------------------------------------------------------------------------
/pics/startup/market_fit/market_fit_startup_curve.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/market_fit/market_fit_startup_curve.jpg


--------------------------------------------------------------------------------
/pics/startup/market_fit/market_fit_startup_stages.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/market_fit/market_fit_startup_stages.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/advertising_creative_order.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/advertising_creative_order.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/advertising_long_form_founder_ad.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/advertising_long_form_founder_ad.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/advertising_stealth_ad.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/advertising_stealth_ad.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/advertising_value_formula.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/advertising_value_formula.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/advertising_value_formula_ad_example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/advertising_value_formula_ad_example.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/advertising_value_formula_example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/advertising_value_formula_example.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/analytics-account.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/analytics-account.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/copywriting_framework_4cs.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/copywriting_framework_4cs.webp


--------------------------------------------------------------------------------
/pics/startup/marketing/copywriting_framework_aida.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/copywriting_framework_aida.webp


--------------------------------------------------------------------------------
/pics/startup/marketing/copywriting_framework_bab.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/copywriting_framework_bab.webp


--------------------------------------------------------------------------------
/pics/startup/marketing/copywriting_framework_fab.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/copywriting_framework_fab.webp


--------------------------------------------------------------------------------
/pics/startup/marketing/copywriting_framework_pas.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/copywriting_framework_pas.webp


--------------------------------------------------------------------------------
/pics/startup/marketing/copywriting_framework_pppp.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/copywriting_framework_pppp.webp


--------------------------------------------------------------------------------
/pics/startup/marketing/copywriting_framework_slap.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/copywriting_framework_slap.webp


--------------------------------------------------------------------------------
/pics/startup/marketing/copywriting_framework_so-what.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/copywriting_framework_so-what.webp


--------------------------------------------------------------------------------
/pics/startup/marketing/copywriting_framework_sss.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/copywriting_framework_sss.webp


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-action-plan-example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-action-plan-example.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-action-plan.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-action-plan.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-benefits-example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-benefits-example.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-benefits.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-benefits.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-cta.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-cta.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-faq.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-faq.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-hero-example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-hero-example.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-navigation.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-navigation.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-problem-example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-problem-example.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-problem.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-problem.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-solution-example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-solution-example.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-solution.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-solution.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/langing-page-testimonials.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/langing-page-testimonials.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/tag-manager_account.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/tag-manager_account.jpg


--------------------------------------------------------------------------------
/pics/startup/marketing/tag-manager_tags.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/marketing/tag-manager_tags.jpg


--------------------------------------------------------------------------------
/pics/startup/mvp/mvp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/mvp/mvp.jpg


--------------------------------------------------------------------------------
/pics/startup/mvp/mvp_airbnb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/mvp/mvp_airbnb.jpg


--------------------------------------------------------------------------------
/pics/startup/mvp/mvp_stripe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/mvp/mvp_stripe.jpg


--------------------------------------------------------------------------------
/pics/startup/mvp/mvp_twitch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/mvp/mvp_twitch.jpg


--------------------------------------------------------------------------------
/pics/startup/pricing/pricing_billion_formula.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/pricing/pricing_billion_formula.jpg


--------------------------------------------------------------------------------
/pics/startup/pricing/pricing_optimization.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/pricing/pricing_optimization.jpg


--------------------------------------------------------------------------------
/pics/startup/pricing/pricing_quadrants.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/pricing/pricing_quadrants.jpg


--------------------------------------------------------------------------------
/pics/startup/pricing/pricing_rule.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/pricing/pricing_rule.jpg


--------------------------------------------------------------------------------
/pics/startup/pricing/pricing_sales_stages.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/pricing/pricing_sales_stages.jpg


--------------------------------------------------------------------------------
/pics/startup/pricing/pricing_thermometer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/pricing/pricing_thermometer.jpg


--------------------------------------------------------------------------------
/pics/startup/product_design/object_model.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/product_design/object_model.jpg


--------------------------------------------------------------------------------
/pics/startup/product_design/responsibilities.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/product_design/responsibilities.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/email_example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/email_example.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/email_open_hour.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/email_open_hour.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/email_response_hour.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/email_response_hour.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/linkedin_about.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/linkedin_about.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/linkedin_banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/linkedin_banner.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/linkedin_connection.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/linkedin_connection.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/linkedin_custom-button.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/linkedin_custom-button.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/linkedin_experience.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/linkedin_experience.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/linkedin_fatures.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/linkedin_fatures.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/linkedin_headline.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/linkedin_headline.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/linkedin_recommendation.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/linkedin_recommendation.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_conversations_phone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_conversations_phone.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_conversions.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_conversions.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_cycle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_cycle.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_expectations.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_expectations.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_follow_up.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_follow_up.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_map.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_map.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_marketing-buyer-journey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_marketing-buyer-journey.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_process.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_process.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_reality.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_reality.jpg


--------------------------------------------------------------------------------
/pics/startup/sales/sales_time_spent.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/startup/sales/sales_time_spent.jpg


--------------------------------------------------------------------------------
/pics/svelte/svelte_degit.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/svelte/svelte_degit.jpg


--------------------------------------------------------------------------------
/pics/svelte/svelte_vite.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/svelte/svelte_vite.jpg


--------------------------------------------------------------------------------
/pics/uiux/uiux_fonts.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/uiux/uiux_fonts.jpg


--------------------------------------------------------------------------------
/pics/vim/vim_graphical_cheat_sheet.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/pics/vim/vim_graphical_cheat_sheet.jpg


--------------------------------------------------------------------------------
/topics/ai/apiChatGPT.md:
--------------------------------------------------------------------------------
 1 | # GPT 4
 2 | 
 3 | ```js
 4 | const { Configuration, OpenAIApi } = require("openai");
 5 | 
 6 | const { apiKey } = require("./config");
 7 | 
 8 | const configuration = new Configuration({
 9 |     apiKey: apiKey,
10 | });
11 | 
12 | const openai = new OpenAIApi(configuration);
13 | 
14 | async function run() {
15 |     const response = await openai.createChatCompletion({
16 |         model: "gpt-4",
17 |         messages: [
18 |             { role: "system", content: "You are a helpful assistant." },
19 |             { role: "user", content: "Who won the world series in 2020?" },
20 |             { role: "assistant", content: "The Los Angeles Dodgers." },
21 |         ],
22 |         max_tokens: 2000,
23 |         n: 1,
24 |         stop: null,
25 |         temperature: 0,
26 |     });
27 | 
28 |     console.log(response.data.choices[0].message.content);
29 | }
30 | 
31 | run();
32 | ```
33 | 
34 | # GPT 3
35 | 
36 | ```js
37 | const { Configuration, OpenAIApi } = require("openai");
38 | 
39 | const { organization, apiKey } = require("./config");
40 | 
41 | const configuration = new Configuration({
42 |     organization: organization,
43 |     apiKey: apiKey,
44 | });
45 | 
46 | const openai = new OpenAIApi(configuration);
47 | 
48 | async function run() {
49 |     const completion = await openai.createCompletion({
50 |         model: "text-davinci-003",
51 |         prompt: "Who won the world series in 2020?",
52 |         max_tokens: 3000,
53 |         temperature: 0,
54 |     });
55 | 
56 |     console.log(completion.data.choices[0].text);
57 | }
58 | 
59 | run();
60 | ```
61 | 
62 | # Notes
63 | 
64 | Remember that the model predicts which text is most likely to follow the text preceding it.
65 | 
66 | As a rough rule of thumb, 1 token is approximately 4 characters or 0.75 words for English text.
67 | 
68 | temperature = randomness. Smaller = less random. Lowering temperature means it will take fewer risks, and completions will be more accurate and deterministic. Increasing temperature will result in more diverse completions.
69 | 
70 | In the context of OpenAI's Chat API, the role and content parameters work together to define the conversation history.
71 | 
72 | role: This parameter is used to specify the role of a message sender in the conversation.
73 | It can take one of three values: 'system', 'user', or 'assistant'.
74 | 
75 | 'system': This role is typically used for instructions that set the behavior of the assistant. It often begins the conversation.
76 | 'user': This role is typically for the end user or human in the conversation.
77 | 'assistant': This role is for the AI model or assistant's responses.
78 | 
79 | content: This parameter holds the actual text of the message from the role.
80 | For example, for the 'user' role, the content would be what the user said or asked.
81 | For the 'assistant', it would be the assistant's response.
82 | 
83 | In the array of messages you provided:
84 | 
85 | ```
86 | messages: [
87 | { role: "system", content: "You are a helpful assistant." },
88 | { role: "user", content: "Who won the world series in 2020?" },
89 | { role: "assistant", content: "The Los Angeles Dodgers." },
90 | { role: "user", content: "Where was it played?" },
91 | ]
92 | ```
93 | 
94 | The 'system' role is telling the assistant that its role is to be helpful. Then the 'user' asks a question about who won the World Series in 2020, the 'assistant' provides the answer, and then the 'user' asks another question. These messages together represent the conversation history. When a new message is added to the conversation history and a chat completion is created, the AI model will generate a response in the context of this history.
95 | 


--------------------------------------------------------------------------------
/topics/ai/concepts.md:
--------------------------------------------------------------------------------
 1 | Forward propagation = Prediction  
 2 | Back propagation = Measuring i.e. learning
 3 | 
 4 | # IDE
 5 | 
 6 | jupyter - Online IDE
 7 | 
 8 | # Datasets
 9 | 
10 | kaggle - datasets
11 | 
12 | # Frameworks
13 | 
14 | Wrappers to simplify using AI models to do tasks. Basically write and orchestrate prompts indirectly.
15 | 
16 | OpenAI API is quite easy to use directly and gives you the most control, I don’t see much benefit of a wrapper langChain here tbh.
17 | 
18 | Example: Langchain, Haystack, Microsoft Guidance
19 | 
20 | # autoGPT
21 | 
22 | An agent talking to itself. A recursive LLM.
23 | 
24 | It’s a thinking AI basically, Chat GPT is just LLM. A LLM is like a baby without understanding, but using tools like Langchain and Pinecone you can teach the AI task. Auto GPT on has a few task, it’s really like a template to build your own thinking AI.
25 | 
26 | Research Langchain and Pinecone to get a better understanding of the potential.
27 | 
28 | # Agent
29 | 
30 | An LLM with a predefined behavior, a personality.
31 | 
32 | The word agent is being thrown around a lot to refer to an application that can execute multiple tasks according to a given control flow (see Control flows section). A task can leverage one or more tools. In the example above, SQL executor is an example of a tool.
33 | 
34 | In broad terms, with the Agent model, the LLM becomes an orchestrator, taking a question, decomposing it into chunks, then using appropriate tools to pull together an answer.
35 | 
36 | # Tools / Plugins
37 | 
38 | Ways in which the agent can choose to do things ex. search the web, query a database.
39 | 
40 | Tools and plugins are basically the same things.
41 | 
42 | Ex.
43 | 
44 | -   search (e.g. by using Google Search API or Bing API)
45 | -   web browser (e.g. given a URL, fetch its content)
46 | -   bash executor
47 | -   calculator
48 | 
49 | # Transformer
50 | 
51 | A transformer is a type of neural network, which have numbers as inputs. Both the input and output words need to be turned into numbers.
52 | 
53 | There are many ways to do the conversion, with the most common being word embedding.
54 | 
55 | # LLM
56 | 
57 | LLMs (Large language models) are text completion engines
58 | 
59 | Examples: gpt-3.5, gpt-4, hugginface, llama
60 | 
61 | # Custom AI
62 | 
63 | 2 ways to do this:
64 | 
65 | 1. Finetune LLM (Behave a certain way ex. talk like Trump) - Re-train the model. More complex, saves cost.
66 | 2. Knowledge base. (Gain domain knowledge) - Create embeddings and store them in a vector database, which is the searched for and fed into an LLM prompt.
67 | 


--------------------------------------------------------------------------------
/topics/ai/embeddings.md:
--------------------------------------------------------------------------------
 1 | One direction that I find very promising is to use LLMs to generate embeddings and then build your ML applications on top of these embeddings, e.g. for search and recsys. As of April 2023, the cost for embeddings using the smaller model text-embedding-ada-002 is $0.0004/1k tokens. If each item averages 250 tokens (187 words), this pricing means $1 for every 10k items or $100 for 1 million items.
 2 | 
 3 | # Embeddings
 4 | 
 5 | Embeddings are a numerical representation of text that can be used to measure the relatedness between two pieces of text.
 6 | 
 7 | Turn data into a vector with hundreds of dimensions.
 8 | 
 9 | Data, like words, converted into an array of numbers, known as a vector, which contains pattern of relationship between the data.
10 | 
11 | Open AI ada = 8,191 tokens i.e. 32,764 characters ~ 10 pages of text.
12 | 
13 | # Vector databases
14 | 
15 | > What pieces of text in the database have similar vectors to the prompt.
16 | 
17 | A vector database indexes and stores vector embeddings for fast retrieval and similarity search. It compares how close embeddings are.
18 | 
19 | It turns the user's question into a vector, which is compared to the vectors in the database.
20 | 
21 | Ex. Pinecone, Qdrant, Weaviate, Chroma, Faiss, Redis, Milvus, ScaNN.
22 | 


--------------------------------------------------------------------------------
/topics/ai/mcp.md:
--------------------------------------------------------------------------------
 1 | # Model Context Protocol (MCP)
 2 | 
 3 | A new standard for building APIs.
 4 | 
 5 | Other standards include REST, RPC, SOAP and GraphQL.
 6 | 
 7 | MCP is an API that calls other APIs.
 8 | 
 9 | The clients sends a prompt, and MPC figures out which API to call next.
10 | 
11 | To actually use MCP, you need a client that supports the MCP protocol, like Claude Desktop.
12 | 


--------------------------------------------------------------------------------
/topics/ansible.md:
--------------------------------------------------------------------------------
  1 | # Ansible
  2 | 
  3 | What should the server look like vs How to make it that way.  
  4 | 
  5 | We configure the state of a server, rather than the installation process with scripts, or god forbid manual installation by typing each command.  
  6 | 
  7 | More importantly, it offers built-in monitoring and alerting after deployment, instead of configuring our own for each machine. Ex. Which servers are running which version?  
  8 | 
  9 | The configuration scripts serve as documentation compared to reading cryptic bash scripts.  
 10 | 
 11 | Ansible is a **declarative** system. Instead of saying **Install something**, we say **I want something to be installed** i.e. if it's already isntalled, do nothing... Otherwise install it.  
 12 | 
 13 | Ansible commands are idempotent, meaning they always result in the same, no matter how many times they run.  
 14 | 
 15 | Ansible does not require anything to run on the remote servers, aside from SSH access with private/public RSA keys.  
 16 | 
 17 | Ansible uses the `jinja2` templating engine to inject variables with `{{variable}}`.  
 18 | 
 19 | ## Things needed
 20 | 
 21 | #### Inventory
 22 | 
 23 | A list of machines to do things on. Can be a simple text file.  
 24 | 
 25 | ```ansible
 26 | server1.company.com
 27 | server2.company.com
 28 | ```
 29 | 
 30 | Machines can be grouped by using `[group]`. Machines can belong to several groups.  
 31 | 
 32 | ```ansible
 33 | [database]
 34 | db1.company.com
 35 | db2.company.com
 36 | ```
 37 | ## Commands
 38 | 
 39 | `ansible database -i invetory -m ping` - Run the ping module (-m) on all the machines in the database group, located in the inventory (-i) list.  
 40 | 
 41 | `ansible database -i inventory -m apt -a "name=mysql-server state=present"` - If mysql is not installed, install it on all machines missing it in the database group.  
 42 | 
 43 | ## Playbook  
 44 | 
 45 | Instead of running commands one by one, we can define a playbook(.yml) with all the commands in one place.  
 46 | 
 47 | Each task should have a name, so that it's printed in the output as it runs, as well as serve as documentation.  
 48 | 
 49 | ```yml
 50 | --
 51 | - hosts: all
 52 |     tasks:
 53 |         - name: Update package list
 54 |             apt: update_cache=yes cache_valid_time=36000 # last 10 hours.
 55 | 
 56 | - hosts: database
 57 |     tasks:
 58 |         - name: Install MySQL
 59 |             apt: name=mysql-server state=present
 60 |         - name: Copy fixtures
 61 |             template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
 62 | ```
 63 | 
 64 | `ansible-playbook -i inventory playbook.yml` - Run the playbook.  
 65 | 
 66 | #### Variables
 67 | 
 68 | To prevent repetition, we can define variables and inject them where needed.  
 69 | 
 70 | ```yml
 71 | --
 72 | - hosts: database
 73 |     vars:
 74 |         fixture_name: fixtures.sql # Variable
 75 |     tasks:
 76 |         - name: Install MySQL
 77 |             apt: name=mysql-server state=present
 78 |         - name: Copy fixtures
 79 |             copy: src={{fixture_name}} dest=/tmp/{{fixture_name}}
 80 | ```
 81 | 
 82 | #### Loops
 83 | 
 84 | ```yml
 85 | --
 86 | - hosts: all
 87 |     tasks:
 88 |         - name: Install packages
 89 |             apt: name={{item}} state=present
 90 |             with_items: # Loop
 91 |                 - python
 92 |                 - python-pip
 93 |                 - vim
 94 | ```
 95 | 
 96 | #### Loops with Variables
 97 | 
 98 | ```yml
 99 | --
100 | - hosts: all
101 |     vars:
102 |         packages: # Variable
103 |             - python
104 |             - python-pip
105 |             - vim
106 |     tasks:        
107 |         - name: Install packages
108 |             apt: name={{item}} state=present
109 |             with_items: packages # Variable
110 | ```
111 | 
112 | ## File Organization Convention
113 | 


--------------------------------------------------------------------------------
/topics/assembly.md:
--------------------------------------------------------------------------------
 1 | Assembly language is still taught for specific platforms like ARM and x86/64. You can do a lot of interesting close-to-hardware operations with assembly for embedded code, but most high level code bases like business logic code don't really use it directly. An assembler is generally always involved for higher level coding languages that compile down to machine code (e.g. C++/C, Go), because a compiler generally converts high level code to machine specific assembly before an assembler converts it to the final machine code. Something that says "ADD(Register_6, Register_13)" is much better to a human than say some fictitious machine code binary of "011010010111011101100000011000001101".
 2 | 
 3 | C is pretty much a macro language for assembly.
 4 | 
 5 | Assembly languages are low-level programming languages where you are giving instructiins like
 6 | 
 7 | "load from memory location 123" "load from memory location 124" "add those together" "store the result at memory location 124" "compare to memory 77" "if that location equals 4, jump to instruction 60"
 8 | 
 9 | Different processors have different assembly languages, so you can't run the same assembly programs on, say, x86 and ARM machines.
10 | 
11 | But which assembly to choose?
12 | 
13 | Whatever processor you're writing for? Different architectures use different instruction sets
14 | 
15 | Let’s say I want one for an amd rizen 3200. Should I pick masm? Gas? Nasm? Yasm?
16 | 
17 | They’re all x86_64 assemblers. There isn’t “assembly language” so much as a whole family of assembly languages. It’s not like saying it’s programmed in C is all I’m saying.
18 | 
19 | For x86 there are two main dialects of assembly: AT&T and Intel. Personally I prefer Intel, I think it looks cleaner with less sigils, and putting the destination operator first makes more sense with instructions like `sub` and especially with comparison and jump. `sub eax 4` computes eax-4 and stores the result in eax, on AT&T syntax this is written `sub $4 %eax` so you have to read "subtract 4 from eax". And `cmp 4 eax; jl label` is simply "jump if 4 < eax" on Intel syntax, but in AT&T syntax the comparison is swapped to `cmp %eax $4`, but `jl` still means "jump if 4 < eax". It's very easy to get confused.
20 | 
21 | Beyond this, the assemblers are mostly different in whether they support macros and what kind. So the choice isn't too important.
22 | 


--------------------------------------------------------------------------------
/topics/babel.md:
--------------------------------------------------------------------------------
 1 | Babel is a transpiler (translator + compiler) and it converts modern code into old code, able to run in older browsers.
 2 | 
 3 | ```bash
 4 | npm install babel-cli babel-core babel-preset-env
 5 | ```
 6 | 
 7 | `babel-cli` - Command line interface. Takes a js file and returns a transpiled one.
 8 | `babel-core` - The transpiling logic.  
 9 | `babel-preset-env` - Each new javascript feature has a **separate** plugin. Intead of installing them one by one, we can install a preset containing all of them.
10 | 
11 | To run the transpiler we can use:
12 | ```bash
13 | # Use the env preset to transpile index.js and put the output in the build folder in index.js.
14 | babel --presets env index.js -o build/index.js
15 | ```
16 | This command is for one file. In order to transpile many files, a bundler like Webpack is needed. Here, every file is transpiler first, before being added to the bundle.
17 | 
18 | We can add this in `package.json` for convenience:
19 | ```json
20 | {
21 |     "scripts": {
22 |         "babel": "babel --presets env index.js -o build/index.js"
23 |     }
24 | }
25 | ```


--------------------------------------------------------------------------------
/topics/binary/bitwise.md:
--------------------------------------------------------------------------------
 1 | # OR
 2 | 
 3 | Sets each bit to 1 if one of two bits is 1.
 4 | 
 5 | ```javascript
 6 | // 1 = 00000001
 7 | // 2 = 00000010
 8 | 
 9 | console.log(1 | 2);
10 | // 3 = 00000011
11 | ```
12 | 
13 | # Bitwise AND
14 | 
15 | Sets each bit to 1 if both bits are 1.
16 | 
17 | ```javascript
18 | // 1 = 00000001
19 | // 2 = 00000010
20 | 
21 | console.log(1 & 2);
22 | // 0 = 00000000
23 | ```
24 | 
25 | # Bitwise XOR
26 | 
27 | Sets each bit to 1 if only one of two bits is 1.
28 | 
29 | ```javascript
30 | // 10 = 00001010
31 | 
32 | console.log(1 ^ 2);
33 | // 6 = 000000110
34 | ```
35 | 
36 | # Bitwise NOT
37 | 
38 | Inverts all the bits.
39 | 
40 | # Shift Left
41 | 
42 | Add n zeros to the right i.e. remove n bits from the left. (binary to number)
43 | 
44 | ```
45 | 00000 111 (7) << 1 = 0000 111 0 (14)
46 | 00000 101 (5) << 3 = 00 101 000 (40)
47 | ```
48 | 
49 | # Shift Right
50 | 
51 | Add n zeros to the left i.e. remove n bits from the right. (binary to number)
52 | 
53 | ```
54 | 00 101010 (42) >> 4 = 000000 10 (2)
55 | 00000 111  (7) >> 1 = 000000 11 (3)
56 | 00 110011 (51) >> 3 = 00000 110 (6)
57 | ```
58 | 


--------------------------------------------------------------------------------
/topics/caching.md:
--------------------------------------------------------------------------------
 1 | # Memcached
 2 | 
 3 | It stores key-value pairs in memory for quick access. It doesn't persist data to disk as a database.
 4 | 
 5 | Can be run on a separate machine, but usually it's on the app server.
 6 | 
 7 | When an HTTP request hits the server, it first checks if memcached has the response stored and returns that. If not, it retireves the data from the database, generates the reposnse, and saves it in the cache for future use.
 8 | 
 9 | ```bash
10 | sudo apt-get install memcached
11 | ```
12 | 
13 | ```bash
14 | # key (string) - value (string)
15 | set(key, value)
16 | get(key)
17 | delete(key)
18 | ```


--------------------------------------------------------------------------------
/topics/cryptojs.md:
--------------------------------------------------------------------------------
 1 | # Hashing
 2 | 
 3 | ```js
 4 | const SHA256 = require("crypto-js/sha256");
 5 | 
 6 | console.log(SHA256("pass").toString());
 7 | 
 8 | // d74ff0ee8da3b9806b18c877dbf29bbde50b5bd8e4dad7a3a725000feb82e8f1
 9 | 
10 | console.log(SHA256("pass"));
11 | 
12 | /*
13 |     {
14 |     words: [
15 |         -682626834,
16 |         -1918649984,
17 |         1796786295,
18 |         -604857411,
19 |         -452240424,
20 |         -455419997,
21 |         -1490747377,
22 |         -343742223
23 |     ],
24 |     sigBytes: 32
25 |     }
26 | */
27 | ```
28 | 
29 | # Encryption
30 | 
31 | **encrypt**
32 | 
33 | ```js
34 | const CryptoJS = require("crypto-js");
35 | const readline = require("readline");
36 | 
37 | const rl = readline.createInterface({
38 |     input: process.stdin,
39 |     output: process.stdout,
40 | });
41 | 
42 | rl.question("Enter string for encryption: ", (string) => {
43 |     rl.question("Enter secret: ", (secret) => {
44 |         let encrypted = CryptoJS.AES.encrypt(string, secret).toString();
45 |         console.log(`Encrypted string: ${encrypted}`);
46 |         rl.close();
47 |     });
48 | });
49 | ```
50 | 
51 | **decrypt**
52 | 
53 | ```js
54 | const CryptoJS = require("crypto-js");
55 | const readline = require("readline");
56 | 
57 | const rl = readline.createInterface({
58 |     input: process.stdin,
59 |     output: process.stdout,
60 | });
61 | 
62 | rl.question("Enter string for decryption: ", (string) => {
63 |     rl.question("Enter secret: ", (secret) => {
64 |         let bytes = CryptoJS.AES.decrypt(string, secret);
65 |         let decrypted = bytes.toString(CryptoJS.enc.Utf8);
66 |         console.log(`Decrypted string: ${decrypted}`);
67 |         rl.close();
68 |     });
69 | });
70 | ```
71 | 


--------------------------------------------------------------------------------
/topics/cybersecurity/csrf.md:
--------------------------------------------------------------------------------
1 | # Cross Site Request Forgery (CSRF)
2 | 
3 | **A CSRF vulnerability enables an attacker to perform actions on a website via an authenticated user.**
4 | 
5 | In a CSRF attack, the attacker makes a request to a third party page in the background, for instance by sending a POST request to your bank website. If you have a valid session with your bank, any website can make a request in the background that will be carried out unless your bank uses counter measures against CSRF.
6 | 


--------------------------------------------------------------------------------
/topics/cybersecurity/cybersecurity.md:
--------------------------------------------------------------------------------
1 | -   **SSL** - Let's encrypt.
2 | -   **Encryption** - Password hashing.
3 | -   **JWT** - Tokens vs cookies.
4 | -   **Reverse-proxy** - Localhost vs direct.
5 | -   **User groups** - Linux permissions.
6 | 


--------------------------------------------------------------------------------
/topics/cybersecurity/jwt.md:
--------------------------------------------------------------------------------
 1 | > You don't do any token validation on the client. The client shouldn't even be aware of the token. localStorage is bad.
 2 | 
 3 | > Server middleware validates tokens, and redirects to login page if invalid.
 4 | 
 5 | Storing JWTs in localStorage or sessionStorage in a browser can make them vulnerable to XSS attacks. Storing them in a secure, HttpOnly cookie is generally safer.
 6 | 
 7 | After generating the JWT, send it to the client in an HttpOnly cookie. This ensures that the token cannot be accessed via JavaScript (protecting against XSS attacks).
 8 | 
 9 | ```js
10 | const express = require("express");
11 | const jwt = require("jsonwebtoken");
12 | const app = express();
13 | 
14 | app.post("/login", (req, res) => {
15 |     // Authenticate user (you'd typically check the credentials here)
16 |     const userId = req.body.userId; // example user ID
17 | 
18 |     // Generate the JWT
19 |     const token = jwt.sign({ userId }, "your_secret_key", { expiresIn: "1h" });
20 | 
21 |     // Set the JWT in an HttpOnly cookie
22 |     res.cookie("token", token, {
23 |         httpOnly: true, // Prevents access to the cookie via JavaScript
24 |         secure: true, // Ensures the cookie is sent over HTTPS (set to true in production)
25 |         sameSite: "Strict", // Helps protect against CSRF attacks
26 |     });
27 | 
28 |     res.send("Logged in successfully");
29 | });
30 | ```
31 | 
32 | When the client makes requests to your server, the JWT will be automatically sent in the Cookie header. You can access and verify this token on the server to authenticate the request.
33 | 
34 | ```js
35 | app.get("/protected-route", (req, res) => {
36 |     const token = req.cookies.token;
37 | 
38 |     if (!token) {
39 |         return res.status(401).send("Access denied. No token provided.");
40 |     }
41 | 
42 |     try {
43 |         const decoded = jwt.verify(token, "your_secret_key");
44 |         req.user = decoded; // Now you have access to the user info in req.user
45 |         res.send("Protected data");
46 |     } catch (err) {
47 |         res.status(400).send("Invalid token");
48 |     }
49 | });
50 | ```
51 | 
52 | To log out a user, simply clear the cookie on the server.
53 | 
54 | ```js
55 | app.post("/logout", (req, res) => {
56 |     res.clearCookie("token");
57 |     res.send("Logged out successfully");
58 | });
59 | ```
60 | 
61 | If your front-end relies on the token to determine whether to display a login page or a content page, making an API request on app load to check the token is a common and effective approach.
62 | 
63 | API Request on App Load: On the initial load of your front-end application, make an API request to a backend endpoint (e.g., /me, /profile, or /auth/check) that checks the validity of the token and returns the user’s information if the token is valid.
64 | 
65 | ```js
66 | // Example using Fetch API
67 | function checkAuthStatus() {
68 |     return fetch("/auth/check", {
69 |         method: "GET",
70 |         credentials: "include", // Include cookies in the request
71 |     }).then((response) => {
72 |         if (!response.ok) {
73 |             throw new Error("Not authenticated");
74 |         }
75 |         return response.json();
76 |     });
77 | }
78 | 
79 | // Call this function on app load
80 | checkAuthStatus()
81 |     .then((user) => {
82 |         // Token is valid; show content page
83 |         console.log("User is authenticated:", user);
84 |         showContentPage(user);
85 |     })
86 |     .catch((error) => {
87 |         // Token is invalid or not present; show login page
88 |         console.log("User is not authenticated:", error);
89 |         showLoginPage();
90 |     });
91 | ```
92 | 
93 | credentials: 'include': This ensures that the cookie containing the JWT is sent with the request.
94 | 


--------------------------------------------------------------------------------
/topics/cybersecurity/sqlinjection.md:
--------------------------------------------------------------------------------
 1 | # SQL Injection
 2 | 
 3 | Password:
 4 | 
 5 | ```
 6 | password
 7 | ```
 8 | 
 9 | Result:
10 | 
11 | ```sql
12 | SELECT *
13 | FROM users
14 | WHERE
15 |     email = 'user@email.com'
16 |     AND pass  = 'password' LIMIT 1
17 | ```
18 | 
19 | ---
20 | 
21 | Use this to check for vulnerability.
22 | 
23 | Password:
24 | 
25 | ```
26 | '
27 | ```
28 | 
29 | Result:
30 | 
31 | ```sql
32 | SELECT *
33 | FROM users
34 | WHERE
35 |     email = 'user@email.com'
36 |     -- ERROR
37 |     AND pass  = ''' LIMIT 1
38 | ```
39 | 
40 | ---
41 | 
42 | This returns a session / JWT token
43 | 
44 | Password:
45 | 
46 | ```sql
47 | ' or 1=1 --
48 | ```
49 | 
50 | Result:
51 | 
52 | ```sql
53 | SELECT *
54 | FROM users
55 | WHERE
56 |     email = 'user@email.com'
57 |     AND pass  = '' or 1=1 --' LIMIT 1
58 | 
59 | ```
60 | 


--------------------------------------------------------------------------------
/topics/cybersecurity/xss.md:
--------------------------------------------------------------------------------
 1 | # Cross Site Scripting (XSS)
 2 | 
 3 | **An XSS vulnerability enables an attacker to inject JavaScript into a site.**
 4 | 
 5 | Handling special characters properly by preventing them from being parsed as code.
 6 | 
 7 | -   Input validation
 8 | 
 9 |     -   Limit allowed user inputs by blacklisting `>`, `<`, `"`, `<script>`...
10 | 
11 | -   Input transformation
12 | 
13 |     -   Encoding input into HTML character enitites:
14 |         -   `<` into `&lt;`
15 |         -   `>` into `&gt;`
16 | 
17 | -   Escaping
18 |     -   Having an input of `" alert("hacked")` as the quote ends the string in code, and executes the `alert`.
19 |         -   Use backlashes to escape the quotes `\" alert("hacked")`.
20 | 
21 | #### Example
22 | 
23 | Let's say there's a website with an `input` form that:
24 | 
25 | -   Generates a query string.
26 | -   Displays that string into the DOM.
27 | 
28 | ```js
29 | function ready() {
30 |     let query = new URL(window.location).searchParams.get("query");
31 |     document.getElementById("query-input").value = query;
32 |     document.getElementById("query-output").innerHTML = query;
33 | }
34 | ```
35 | 
36 | ```
37 | http://example.com/search?query=something
38 | ```
39 | 
40 | Now, putting this inside the input form...
41 | 
42 | ```html
43 | <img src onerror="alert(document.cookie)" />
44 | ```
45 | 
46 | Would inject the "string" via `innerHTML` as an image, which due to the missing `src`, would run the javascript code, which could be code sending the hacked the cookie via email.
47 | 
48 | The danger is when hackers send disquised links to other users to click.
49 | 
50 | To avoid this, use `innerText` instead!
51 | 


--------------------------------------------------------------------------------
/topics/database/conventions.md:
--------------------------------------------------------------------------------
1 | # Naming
2 | 
3 | -   **Singular form**. Both tables and columns.
4 | -   Be consistent! Doesn't matter if you use camelCase or snake_case. Use whatever the front-end uses.
5 | -   Avoid abbreviations or prefixes.
6 | -   Use unique names that cannot collude with SQL/RDBMS reserved words (avoid name, order, percent...) **or** use a trailing underscore.
7 | -   Do not use the table name followd by “id” (e.g. client_id) as your PK. id is more than enough and everyone will understand.
8 | -   Never use capital letters in your table or field names. Ever.
9 | 


--------------------------------------------------------------------------------
/topics/database/node-mssql.md:
--------------------------------------------------------------------------------
 1 | **server.js**
 2 | 
 3 | ```js
 4 | const express = require("express");
 5 | const http = require("http");
 6 | const sql = require("mssql");
 7 | 
 8 | const config = require("./config.js");
 9 | const middleware = require("./middleware.js");
10 | 
11 | let login = require("./api/auth/login");
12 | let users = require("./api/auth/users");
13 | 
14 | let catalogue = require("./api/endpoints/catalogue");
15 | let categories = require("./api/endpoints/categories");
16 | let groups = require("./api/endpoints/groups");
17 | let suppliers = require("./api/endpoints/suppliers");
18 | 
19 | const app = express();
20 | 
21 | app.use(express.json()); // Needed for POST and PATCH requests
22 | 
23 | app.all("/api/*", middleware.authenticationMiddleware);
24 | 
25 | // .use(middleware.requestsMiddleware)
26 | 
27 | app.use(login)
28 |     .use(users)
29 | 
30 |     .use(catalogue)
31 |     .use(categories)
32 |     .use(groups)
33 |     .use(suppliers)
34 | 
35 |     .use(middleware.errorMiddleware);
36 | 
37 | async function start() {
38 |     // Initialize pool only once
39 |     const connection = new sql.ConnectionPool(config.db);
40 |     const pool = await connection.connect();
41 | 
42 |     // pool available in routes via let request = req.app.locals.pool.request();
43 |     app.locals.pool = pool;
44 |     app.locals.sql = sql;
45 | 
46 |     const server = http.createServer(app);
47 | 
48 |     server.listen(config.port, () => {
49 |         console.log(`listening on port: ${config.port}`);
50 |     });
51 | }
52 | 
53 | start();
54 | ```
55 | 
56 | **users.js**
57 | 
58 | ```js
59 | const express = require("express");
60 | const router = express.Router();
61 | 
62 | router.get("/api/users/:userId", async (req, res, next) => {
63 |     try {
64 |         let userId = req.params.userId;
65 | 
66 |         let request = req.app.locals.pool.request();
67 |         let sql = req.app.locals.sql;
68 | 
69 |         request.input("userId", sql.Int, userId);
70 | 
71 |         let query = `
72 |             select *
73 |             from user u
74 |             where u.id = @userId    
75 |             ;
76 |         `;
77 | 
78 |         let result = await request.query(query);
79 | 
80 |         let final = result.recordset[0];
81 | 
82 |         res.send(final);
83 |     } catch (err) {
84 |         next(err);
85 |     }
86 | });
87 | 
88 | module.exports = router;
89 | ```
90 | 


--------------------------------------------------------------------------------
/topics/database/node-mysql.md:
--------------------------------------------------------------------------------
 1 | ```js
 2 | const express = require("express");
 3 | const util = require("util");
 4 | 
 5 | let databaseHandler = (pool) => {
 6 |     return (req, res, next) => {
 7 |         // let subodmain = req.subdomains[0];
 8 |         // req.subdomains is [] in deployment due to the reverse_proxy
 9 |         // req.decoded comes from authenticationHandler
10 |         let database = req.decoded.database;
11 | 
12 |         // Get a connection from the main pool in app.js
13 |         pool.getConnection((err, conn) => {
14 |             if (err) {
15 |                 console.log(err);
16 |                 return;
17 |             }
18 |             // Change the database for the connection
19 |             conn.changeUser({ database: database }, function (err) {
20 |                 if (err) {
21 |                     console.log(err);
22 |                     return;
23 |                 }
24 | 
25 |                 // Promisify for Node.js async/await.
26 |                 const asyncQuery = util.promisify(conn.query).bind(conn);
27 | 
28 |                 // Pass the modified query method down the chain as a property of req, avaiable via next()
29 |                 // req.query is used for queryStrings, so we use asyncQuery to avoid overwriting it
30 |                 // connection.release() is called in the routes
31 |                 req.asyncQuery = asyncQuery;
32 |                 req.connection = conn;
33 |                 req.tenant = database;
34 | 
35 |                 next();
36 |             });
37 |         });
38 |     };
39 | };
40 | 
41 | module.exports = { databaseHandler };
42 | ```
43 | 
44 | ```js
45 | router.get("/api/companies/:companyId", async (req, res, next) => {
46 |     try {
47 |         let companyId = req.params.companyId;
48 | 
49 |         let query = `
50 |             select *
51 |             from company c
52 |             where c.id = ?
53 |         `;
54 | 
55 |         let rows = await req.query(query, [companyId]);
56 |         let company = rows[0];
57 | 
58 |         res.status(200).send(company);
59 |     } catch (err) {
60 |         next(err);
61 |     } finally {
62 |         req.connection.release();
63 |     }
64 | });
65 | ```
66 | 


--------------------------------------------------------------------------------
/topics/database/normalization.md:
--------------------------------------------------------------------------------
 1 | # Table Relationships
 2 | 
 3 | **Look both ways (From each perspective) when trying to determine the relationship.**
 4 | 
 5 | ## One to Many - 90%
 6 | 
 7 | ![One to Many](../../pics/database/database_one_to_many_1.jpg)
 8 | 
 9 | ![One to Many](../../pics/database/database_one_to_many_2.jpg)
10 | 
11 | ## Many to Many - 10%
12 | 
13 | ![Many to One](../../pics/database/database_many_to_many_1.jpg)
14 | 
15 | ![Many to One](../../pics/database/database_many_to_many_2.jpg)
16 | 
17 | ## One to One - 0%
18 | 
19 | Not a thing.If one row points to only one row, you might as well join the tables.
20 | 
21 | ![One to One](../../pics/database/database_one_to_one_1.jpg)
22 | 
23 | Sometimes you think you have a one-to-one relationship, but you don’t. Look both ways (from each perspective) to avoid this.
24 | 
25 | ![One to One](../../pics/database/database_one_to_one_2.jpg)
26 | 
27 | # Normalization
28 | 
29 | Taking your database design through these 3 steps will vastly improve the quality of your data.
30 | 
31 | There are more than 3 Normal Forms, but usually 3 is the norm. There are more than 6.
32 | 
33 | ## First Normal Form (1NF)
34 | 
35 | Each of the columns and tables should contain one and only one value without it repeating.
36 | 
37 | Usually every 1NF problem is solved by creating a new table. One of the signs for the need is when columns start having the same name with a number differentiating them. Computer1, Computer2…
38 | 
39 | ![1NF](../../pics/database/database_1nf.jpg)
40 | 
41 | ## Second Normal Form (2NF)
42 | 
43 | Any non-key field should be dependent on the entire primary key i.e. “Can I figure out any of the values in the row from just part of the composite key?”. Only a problem when dealing with composite keys.
44 | 
45 | ![2NF](../../pics/database/database_2nf.jpg)
46 | 
47 | ## Third Normal Form (3NF)
48 | 
49 | No non-key field is dependent on any other non-key field i.e. “Can I figure out any of the values in this row from any of the other values?”.
50 | 
51 | ![3NF](../../pics/database/database_3nf.jpg)
52 | 
53 | ## Denormalization
54 | 
55 | Sometimes tables intentionally break normalization, and some only seem like they do.
56 | 
57 | Creating a new table for phones and emails would complicate things needlessly. The same goes for the area codes.
58 | 
59 | ![Denormalization](../../pics/database/database_denormalization.jpg)
60 | 


--------------------------------------------------------------------------------
/topics/database/optimizationQuerying.md:
--------------------------------------------------------------------------------
 1 | # Best practices
 2 | 
 3 | -   Always foreign key to IDs, rather than column values.
 4 | -   Try to stick to `where` clauses on indexed columns, instead of `like`.
 5 | -   Don't go crazy with `joins`.
 6 | -   Don't use varchar(255). Try to use the lowest number possible.
 7 | -   Avoid using functions on the Left Hand-Side of the Operator. It's ok to have a function in the right hand.
 8 | 
 9 | ```sql
10 | select * from users where upper(email) = 'foo@bar.com';
11 | -- vs
12 | select * from users where created < now();
13 | ```
14 | 
15 | -   Avoid Wildcard Characters at the Beginning of a LIKE Pattern. MySQL won't use an index for wildcard searches.
16 | 
17 | ```sql
18 | select * from users where email LIKE '%foo%';
19 | -- vs
20 | select * from users where email LIKE 'foo%';
21 | ```
22 | 
23 | -   Avoid OR conditions and use UNION as an alternative.
24 | -   Avoid sorting with a mixed order.
25 | -   In where clause, compare a column to a value which matches the column’s type.
26 | 
27 | ```sql
28 | select * from users where email = 101;
29 | -- vs
30 | select * from users where email = '101';
31 | ```
32 | 
33 | -   Columns on each side of ON clause of a join must be of the same type.
34 | -   If columns on each side of ON clause of a join is VARCHAR, make sure the collations of each of the columns are identical.
35 | -   You do not want to place too many indexes on tables that are frequently updated
36 | -   Keep your table statistics up to date. Done with `ANALYZE TABLE table_name`
37 | 
38 | # What if the query contains OR instead of AND?
39 | 
40 | > In this case, MySQL won't be able to use the index on queries having an OR condition, even if the query contains lookup column and maintains the order of WHERE clause same as the index.
41 | 
42 | Therefore, it's recommended to avoid such OR conditions and consider splitting the query to two parts, combined with a UNION DISTINCT (or even better, UNION ALL, in case you know there won't be any duplicate results)
43 | 
44 | ```sql
45 | select status, category_id from users where status = 1
46 | UNION ALL
47 | select status, category_id from users where category_id = 3
48 | ```
49 | 
50 | # What if the query contains GROUP BY and ORDER BY?
51 | 
52 | ```sql
53 | -- index(status, category_id, email)
54 | select * from users where status = 1 ORDER BY category_id
55 | ```
56 | 
57 | This will use the composite index for the WHERE clause.
58 | 
59 | If you think this will narrow down the records with the status having value as 1, sadly you now need to perform a sort on these resulting records to get them sorted by category_id.
60 | 
61 | This is because the index didn't sort the results by category_id in any meaningful way and ORDER BY clause lacks the lookup column.
62 | 
63 | This is known as a File Sort (some of you might have noticed this in an explain result). This happens because the index that we created failed to satisfy for the ORDER BY clause.
64 | 
65 | > File Sort: A sort that occurs after the query; it requires fetching the data into a temporary buffer and sorting it before finally returning. This wouldn't have been needed if the data was already sorted by the index in the way you wanted.
66 | 
67 | ```sql
68 | select * from users where status = 1 ORDER BY status, category_id
69 | ```
70 | 
71 | This query can leverage the usage of the mentioned index because it qualifies for both the WHERE clause and ORDER BY clause.
72 | 
73 | The same is also applicable to GROUP BY statements. if you run the following query with the composite index on (status, category_id, email):
74 | 
75 | ```sql
76 | select * from users where status = 1 GROUP BY category_id
77 | ```
78 | 
79 | The records are already sorted by status, category_id and email. This allows you to quickly filter down all the records with status = 1. After these results are returned they are also then sorted based on category_id since the index orders the rows differently than required in the query.
80 | 
81 | # What if the query contains JOINS?
82 | 
83 | > You should have indexes on all the columns used in the JOIN clauses. i.e, columns on each side of ON clause of a join must be indexed.
84 | 


--------------------------------------------------------------------------------
/topics/database/queriesAdmin.md:
--------------------------------------------------------------------------------
 1 | # Users
 2 | 
 3 | ```sql
 4 | -- Create user
 5 | CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
 6 | 
 7 | -- Give access to certain areas. In this case, it's for everything as *.* stands for dbName.tableName i.e. all of them.
 8 | GRANT ALL PRIVILEGES ON * . * TO 'user'@'localhost';
 9 | 
10 | -- Fix errors
11 | ALTER USER 'user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
12 | 
13 | -- Reload the privileges.
14 | FLUSH PRIVILEGES;
15 | 
16 | -- List all users.
17 | SELECT user FROM mysql.user;
18 | 
19 | -- Show current user.
20 | SELECT CURRENT_USER();
21 | 
22 | -- Delete user.
23 | DROP USER 'user'@'localhost';
24 | ```
25 | 
26 | ## Permissions
27 | 
28 | **Options:** ALL PRIVILEGES, CREATE, DROP, DELETE, INSERT, SELECT, UPDATE, GRANT OPTION (User can give permissions).
29 | 
30 | ```sql
31 | -- Give a specific permission, for a specific table.
32 | GRANT permission ON dbName.tableName TO '<user>'@'localhost';
33 | 
34 | -- Remove a permission.
35 | REVOKE permission ON dbName.tableName FROM '<user>'@'localhost';
36 | ```
37 | 
38 | ## Change password
39 | 
40 | ```sql
41 | ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass';
42 | FLUSH PRIVILEGES;
43 | 
44 | ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'MyNewPass';
45 | FLUSH PRIVILEGES;
46 | ```
47 | 


--------------------------------------------------------------------------------
/topics/database/queriesAggregate.md:
--------------------------------------------------------------------------------
 1 | # MAX, AVERAGE, SUM... Across columns
 2 | 
 3 | ```sql
 4 | select
 5 |     *,
 6 |     (
 7 |         select max(v)
 8 |         from (
 9 |             values
10 |                 (sales2017),
11 |                 (sales2018),
12 |                 (sales2019)
13 |         ) as value(v)
14 |     ) as maxSales
15 | from sales
16 | ```
17 | 
18 | # Multiple sums
19 | 
20 | ```sql
21 | select
22 |     mi.acIdent,
23 |     m.acissuer,
24 |     datediff(day, max(m.adDate), getdate()) lastSaleDays,
25 |     sum(CASE WHEN m.adDate >= getdate() - 30 THEN mi.anQty ELSE 0 END) soldPastDaysQty,
26 |     sum(CASE WHEN m.adDate between getdate() - (365 * 1) and getdate() - (365 * 1 - 30) THEN mi.anQty ELSE 0 END) soldNextDaysOneYearAgoQty,
27 |     sum(CASE WHEN m.adDate between getdate() - (365 * 2) and getdate() - (365 * 2 - 30) THEN mi.anQty ELSE 0 END) soldNextDaysTwoYearsAgoQty,
28 |     sum(CASE WHEN m.adDate between getdate() - (365 * 3) and getdate() - (365 * 3 - 30) THEN mi.anQty ELSE 0 END) soldNextDaysThreeYearsAgoQty,
29 |     sum(CASE WHEN m.adDate between getdate() - (365 * 4) and getdate() - (365 * 4 - 30) THEN mi.anQty ELSE 0 END) soldNextDaysFourYearsAgoQty
30 | from the_moveitem mi
31 |     left join the_move m on mi.acKey = m.acKey
32 | where
33 |     m.adDate > getdate() - 365 * 4
34 | group by
35 |     mi.acident,
36 |     m.acIssuer
37 | ```
38 | 
39 | # STRING_AGG / mysql group_concat
40 | 
41 | ```sql
42 | select
43 | 	sku,
44 | 	STRING_AGG(category, ', ')
45 | from categories
46 | group by
47 |     sku
48 | ```
49 | 
50 | # Rollup (Total Row)
51 | 
52 | `ROLLUP` is a subclause of the `GROUP BY` clause which provides a shorthand for defining multiple grouping sets. Unlike the `CUBE` subclause, `ROLLUP` does not create all possible grouping sets based on the dimension columns; the `CUBE` makes a subset of those.
53 | 
54 | When generating the grouping sets, `ROLLUP` assumes a hierarchy among the dimension columns and only generates grouping sets based on this hierarchy.
55 | 
56 | The `ROLLUP` is often used to generate subtotals and totals for reporting purposes.
57 | 
58 | ```sql
59 | SELECT
60 |     brand,
61 |     category,
62 |     SUM(sales) sales
63 | FROM
64 |     sales.sales_summary
65 | GROUP BY
66 |     ROLLUP(brand, category)
67 | ```
68 | 
69 | This will result in
70 | 
71 | | brand | category | sales |             |
72 | | ----- | -------- | ----- | ----------- |
73 | | Honda | cars     | 100   |
74 | | Honda | bikes    | 200   |
75 | | Honda | NULL     | 300   | Subtotal    |
76 | | BMW   | cars     | 400   |
77 | | BMW   | bikes    | 500   |
78 | | BMW   | NULL     | 900   | Subtotal    |
79 | | NULL  | NULL     | 1200  | Grand Total |
80 | 


--------------------------------------------------------------------------------
/topics/database/queriesLogic.md:
--------------------------------------------------------------------------------
 1 | # Coalesce
 2 | 
 3 | The SQL Server `COALESCE` function handles `NULL` values.
 4 | 
 5 | The expression accepts a number of arguments, evaluates them in sequence, and returns the first non-null argument.
 6 | 
 7 | ```sql
 8 | SELECT COALESCE (NULL,'A','B')                     -- A
 9 | SELECT COALESCE (NULL,100,20,30,40)                -- 100
10 | SELECT COALESCE (NULL,NULL,20,NULL,NULL)           -- 20
11 | SELECT COALESCE (NULL,NULL,NULL,NULL,NULL,'foo')   -- foo
12 | SELECT COALESCE (NULL,NULL,NULL,NULL,1,'foo')      -- 1
13 | SELECT COALESCE (NULL,NULL,NULL,NULL,NULL,'foo',1) -- coversion failed when converting the varchar value 'foo' to data type int
14 | ```
15 | 
16 | # Recursion
17 | 
18 | Dates generator from date to date (now).
19 | 
20 | ```sql
21 | with recursive dates as (
22 | 	select '2023-01-01' date -- start date
23 | 	union all
24 | 	select date_add(date, interval 1 day)
25 | 	from dates
26 | 	where date < curdate() -- end date
27 | )
28 | select * from dates
29 | 
30 | /*
31 | 2023-01-01
32 | 2023-01-02
33 | 2023-01-03
34 | ...
35 | */
36 | ```
37 | 


--------------------------------------------------------------------------------
/topics/database/queriesSchema.md:
--------------------------------------------------------------------------------
  1 | # Database
  2 | 
  3 | ```sql
  4 | SHOW DATABASES;              -- List databases.
  5 | SELECT database();           -- Show current database.
  6 | USE dbName;                 -- Select a database.
  7 | 
  8 | CREATE DATABASE dbName;     -- Create a database.
  9 | DROP DATABASE dbName;       -- Delete a database.
 10 | ```
 11 | 
 12 | # Tables
 13 | 
 14 | ### Create
 15 | 
 16 | ```sql
 17 | SHOW TABLES;                 -- List all tables.
 18 | DESCRIBE tableName;         -- Display columns and types.
 19 | 
 20 | -- Shows the query that creates the table.
 21 | SHOW CREATE TABLE tableName;
 22 | 
 23 | -- Create a table.
 24 | CREATE TABLE tableName (column1 DATATYPE, column2 DATATYPE);
 25 | 
 26 | -- Example
 27 | CREATE TABLE user (
 28 |     id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -- Important
 29 |     name VARCHAR(255),
 30 |     pass VARCHAR(255)
 31 | );
 32 | ```
 33 | 
 34 | ### Modify
 35 | 
 36 | ```sql
 37 | -- Rename a table.
 38 | RENAME TABLE tableName1 TO tableName2;
 39 | 
 40 | -- Change a column's datatype.
 41 | ALTER TABLE tablename MODIFY columnname DATATYPE;
 42 | 
 43 | -- Add a column at end.
 44 | ALTER TABLE tableName ADD columnName DATATYPE;
 45 | 
 46 | -- Add a column at certain location.
 47 | ALTER TABLE tableName ADD columnName DATATYPE AFTER columnName;
 48 | 
 49 | -- Delete a column.
 50 | ALTER TABLE tableName DROP columnName;
 51 | 
 52 | -- Change a column name. Has to be backticks.
 53 | ALTER TABLE tableName CHANGE `oldcolname` `newcolname` datatype(length);
 54 | 
 55 | -- Reset AUTO_INCREMENT id. For this to work, the table must be empty.
 56 | ALTER TABLE table AUTO_INCREMENT = 1;
 57 | ```
 58 | 
 59 | # Foreign Keys
 60 | 
 61 | They are used for **data integrity** i.e. they prevent entering values that don't exist in the linked table (gives an error).
 62 | 
 63 | A FOREIGN KEY is a field in one table that refers to the PRIMARY KEY in another table.
 64 | 
 65 | The table containing the foreign key is called the child table, and the table containing the candidate key is called the referenced or parent table.
 66 | 
 67 | ```sql
 68 | -- Foreign key definition during table creation.
 69 | CREATE TABLE user (
 70 |     id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
 71 |     name VARCHAR(255),
 72 |     pass VARCHAR(255),
 73 |     phoneId INT,
 74 |     FOREIGN KEY (phoneId) REFERENCES phone(id)
 75 | );
 76 | 
 77 | -- Add foreign key.
 78 | ALTER TABLE table1 ADD FOREIGN KEY (idColumn) REFERENCES table2(idColumn);
 79 | 
 80 | -- Remove foreign key.
 81 | ALTER TABLE tableName DROP FOREIGN KEY FK_columnName;
 82 | ```
 83 | 
 84 | ```sql
 85 | -- List foreign keys.
 86 | SELECT
 87 |     tableName,
 88 |     COLUMNNAME,
 89 |     CONSTRAINT_NAME,
 90 |     REFERENCED_tableName,
 91 |     REFERENCED_COLUMNNAME
 92 | FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
 93 | WHERE
 94 |     REFERENCED_tableName = 'my_table';
 95 | 
 96 | -- One-liner.
 97 | SELECT tableName, COLUMNNAME, CONSTRAINT_NAME, REFERENCED_tableName, REFERENCED_COLUMNNAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_tableName = 'my_table';
 98 | ```
 99 | 
100 | # Delete
101 | 
102 | Be **VERY** careful with this one. **ALWAYS** select first, delete second.
103 | 
104 | ```sql
105 | DROP TABLE tableName;
106 | ```
107 | 


--------------------------------------------------------------------------------
/topics/database/queriesVarious.md:
--------------------------------------------------------------------------------
  1 | # Declare Variables
  2 | 
  3 | ```sql
  4 | -- regular
  5 | DECLARE @date DATETIME = '07.01.2019'
  6 | 
  7 | -- from select
  8 | DECLARE @count INT;
  9 | SET @count = (SELECT COUNT(sku) FROM product)
 10 | SELECT @count;
 11 | ```
 12 | 
 13 | # YYYY-MM date format
 14 | 
 15 | ```sql
 16 | -- 2.5 million rows
 17 | 
 18 | -- 12 sec
 19 | select date
 20 | from sales
 21 | 
 22 | -- 13 sec
 23 | select concat(year(date), '-', RIGHT('00' + CONVERT(varchar(2), DATEPART(MONTH, date)), 2)) ym
 24 | from sales
 25 | 
 26 | -- 15 sec
 27 | select CAST(YEAR(date) AS VARCHAR(4)) + '-' + RIGHT('00' + CAST(MONTH(date) AS VARCHAR(2)), 2) as ym
 28 | from sales
 29 | 
 30 | -- 29 sec
 31 | select FORMAT(date, 'yyyy-MM') as ym
 32 | from sales
 33 | ```
 34 | 
 35 | # Only numbers
 36 | 
 37 | ```sql
 38 | select barcode
 39 | from barcodes
 40 | where barcode not like '%[^0-9]%'
 41 | ```
 42 | 
 43 | # Remove trailing zeros
 44 | 
 45 | ```sql
 46 | select cast(barcode as int)
 47 | ```
 48 | 
 49 | # Order a sub-query
 50 | 
 51 | Using `top 99.9999 percent` is a hack to achieve the ordering.
 52 | 
 53 | Note that `top 100 percent` won't work.
 54 | 
 55 | ```sql
 56 | select
 57 |     sku,
 58 |     STRING_AGG(attribute, ', ') attributes
 59 | from (
 60 |     select top 99.9999999999999 percent
 61 |         sku,
 62 |         attribute
 63 |     from attributes
 64 |     order by
 65 |         sku asc,
 66 |         attribute asc
 67 | ) t1
 68 | group by sku
 69 | ```
 70 | 
 71 | # Previous value
 72 | 
 73 | ```sql
 74 | select
 75 |     lag(value) over (order by created) -- returns the previous row's value
 76 | from sales
 77 | ```
 78 | 
 79 | # CTE - Common Table Expression
 80 | 
 81 | It defines a temporary result set which can be used in a SELECT statement.
 82 | 
 83 | ```sql
 84 | WITH
 85 |     salesrep AS (
 86 |         SELECT
 87 |             employeeNumber,
 88 |             CONCAT(firstName, ' ', lastName) AS salesrepName
 89 |         FROM
 90 |             employees
 91 |         WHERE
 92 |             jobTitle = 'Sales Rep'
 93 |     ),
 94 |     customer_salesrep AS (
 95 |         SELECT
 96 |             customerName, salesrepName
 97 |         FROM
 98 |             customers
 99 |                 INNER JOIN
100 |             salesrep ON employeeNumber = salesrepEmployeeNumber
101 |     )
102 | SELECT
103 |     *
104 | FROM
105 |     customer_salesrep
106 | ORDER BY customerName;
107 | ```
108 | 


--------------------------------------------------------------------------------
/topics/database/queriesWindow.md:
--------------------------------------------------------------------------------
  1 | # Partition By
  2 | 
  3 | We use this to make a "sub-query" i.e. select n-th item from a table for further use.
  4 | 
  5 | ### Data
  6 | 
  7 | ```sql
  8 | SELECT
  9 |     clientID,
 10 |     invoiceDate,
 11 |     revenue
 12 | FROM sales
 13 | ```
 14 | 
 15 | | clientID | invoiceDate | revenue  |
 16 | | -------- | ----------- | -------- |
 17 | | 1017     | 2019-01-31  | 6574.65  |
 18 | | 116      | 2018-02-05  | 5593.22  |
 19 | | 1211     | 2018-01-15  | 3637.80  |
 20 | | 116      | 2018-02-16  | 1848.00  |
 21 | | 1211     | 2018-01-09  | 15615.65 |
 22 | | 1017     | 2019-02-14  | 1386.00  |
 23 | | 1211     | 2018-02-09  | 16145.72 |
 24 | | 116      | 2018-02-13  | 2784.51  |
 25 | | 1211     | 2018-03-28  | 8844.64  |
 26 | 
 27 | ### Data with PARTITION BY
 28 | 
 29 | In this case, we want to have the latest sale for each client. We can achieve this by partitioning the data i.e. ordering the sales for each client in descending order based on the date. We can then select only the desired row with `rowNumber`.
 30 | 
 31 | ```sql
 32 | SELECT
 33 |     ROW_NUMBER() OVER (PARTITION BY clientID ORDER BY invoiceDate DESC) rowNumber,
 34 |     clientID,
 35 |     invoiceDate,
 36 |     revenue
 37 | FROM sales
 38 | ```
 39 | 
 40 | | rowNumber | clientID | invoiceDate | revenue  |
 41 | | --------- | -------- | ----------- | -------- |
 42 | | 1         | 1017     | 2019-02-14  | 1386.00  |
 43 | | 2         | 1017     | 2019-01-31  | 6574.65  |
 44 | | 1         | 116      | 2018-02-16  | 1848.00  |
 45 | | 2         | 116      | 2018-02-13  | 2784.51  |
 46 | | 3         | 116      | 2018-02-05  | 5593.22  |
 47 | | 1         | 1211     | 2018-03-28  | 8844.64  |
 48 | | 2         | 1211     | 2018-02-09  | 16145.72 |
 49 | | 3         | 1211     | 2018-01-15  | 3637.80  |
 50 | | 4         | 1211     | 2018-01-09  | 15615.65 |
 51 | 
 52 | ### Result
 53 | 
 54 | ```sql
 55 | SELECT
 56 |     lastSale.clientID,
 57 |     lastSale.invoiceDate,
 58 |     lastSale.revenue
 59 | FROM (
 60 |     SELECT
 61 |         ROW_NUMBER() OVER (PARTITION BY clientID ORDER BY invoiceDate DESC) rowNumber,
 62 |         clientID,
 63 |         invoiceDate,
 64 |         revenue
 65 |     FROM sales
 66 | ) lastSale
 67 | WHERE lastSale.rowNumber = 1
 68 | ```
 69 | 
 70 | We only get the first row for each client i.e. the last sale (sorted by descending invoice date).
 71 | 
 72 | | acReceiver | adDate     | sales   |
 73 | | ---------- | ---------- | ------- |
 74 | | 1017       | 2019-02-14 | 1386.00 |
 75 | | 116        | 2018-02-16 | 1848.00 |
 76 | | 1211       | 2018-03-28 | 8844.64 |
 77 | 
 78 | # Row Number
 79 | 
 80 | ```sql
 81 | SELECT
 82 |     ROW_NUMBER() OVER (ORDER BY profit DESC) rowNumber
 83 | FROM sales
 84 | ```
 85 | 
 86 | # Column sum / Running total
 87 | 
 88 | This one is better because it can be based on all data...
 89 | 
 90 | ```sql
 91 | select
 92 |     sum(value) over (partition by client order by date desc) runningTotal -- the `order by` turns this into a running sum.
 93 | from sales;
 94 | ```
 95 | 
 96 | ...instead of just filtered.
 97 | 
 98 | ```sql
 99 | SELECT
100 |     isnull(profit, 0) profit,
101 |     SUM(profit) OVER(ORDER BY profit desc ROWS UNBOUNDED PRECEDING) AS profitRunning, -- cummulative sum of profit
102 |     SUM(profit) OVER () AS profitTotal, -- sum of profit column
103 |     SUM(profit) OVER(ORDER BY profit desc ROWS UNBOUNDED PRECEDING) / SUM(profit) OVER () profitShare
104 | FROM sales
105 | ```
106 | 
107 | # Duplicates
108 | 
109 | ```sql
110 | SELECT
111 |     sku
112 | FROM (
113 |     SELECT
114 |         ROW_NUMBER() OVER (PARTITION BY sku ORDER BY sku asc) rowNumber,
115 |         sku
116 |     FROM product
117 | ) duplicates
118 | WHERE rowNumber > 1
119 | ```
120 | 


--------------------------------------------------------------------------------
/topics/database/sqlserver.md:
--------------------------------------------------------------------------------
1 | ```sql
2 | -- tables
3 | SELECT * FROM INFORMATION_SCHEMA.TABLES;
4 | 
5 | -- columns
6 | SELECT * FROM INFORMATION_SCHEMA.COLUMNS;
7 | ```
8 | 


--------------------------------------------------------------------------------
/topics/database/terminology.md:
--------------------------------------------------------------------------------
 1 | -   SQL Server Instance = The running process of SQL Server, which manages databases.
 2 | -   Database = A collection of data inside an instance.
 3 | -   Schema = A logical namespace inside a database to organize objects.
 4 | 
 5 | ---
 6 | 
 7 | -   SQL Server (the program) runs instances.
 8 | -   Each instance can manage multiple databases.
 9 | -   Each database can have multiple schemas.
10 | 
11 | ---
12 | 
13 | | **Concept**             | **Explanation**                                                                             |
14 | | ----------------------- | ------------------------------------------------------------------------------------------- |
15 | | **SQL Server (RDBMS)**  | The software you install that allows you to create, manage, and query relational databases. |
16 | | **SQL Server Instance** | A running process of SQL Server that can manage one or more databases.                      |
17 | | **Database**            | A collection of tables, views, and objects managed by an instance.                          |
18 | | **Schema**              | A logical namespace inside a database to organize tables and other objects.                 |
19 | 
20 | ```
21 | SQL Server (RDBMS)
22 | └── Instance: MSSQLSERVER
23 |     ├── Database: ERP_DB
24 |     │   ├── Schema: hr
25 |     │   │   ├── Table: hr.employees
26 |     │   ├── Schema: finance
27 |     │       ├── Table: finance.invoices
28 |     ├── Database: Retail_DB
29 |         ├── Schema: store
30 |             ├── Table: store.products
31 | ```
32 | 
33 | | **RDBMS**      | **Instance**        | **Schemas**         |
34 | | -------------- | ------------------- | ------------------- |
35 | | **SQL Server** | Yes (Named/Default) | Yes                 |
36 | | **PostgreSQL** | Yes (Cluster-based) | Yes                 |
37 | | **MySQL**      | No (Single process) | No (Databases only) |
38 | 


--------------------------------------------------------------------------------
/topics/dotenv.md:
--------------------------------------------------------------------------------
 1 | In order to use different parameters in our app depending on the enviroment such as...
 2 | 
 3 | -   Server ports
 4 | -   Database credentials
 5 | -   API keys
 6 | 
 7 | ...we can declare environment variables.
 8 | 
 9 | We do this by having a `.env` file to store the variables.
10 | 
11 | **NEVER COMMIT THIS FILE. PUT IT IN .gitignore!**
12 | 
13 | ```
14 | DBNAME=database
15 | DBUSER=root
16 | DBPASSWORD=root
17 | ```
18 | 
19 | Which we can read with the `dotenv` package like so.
20 | 
21 | ```js
22 | // config.js
23 | const dotenv = require("dotenv").config({
24 |     path: `${__dirname}/.env`,
25 | });
26 | 
27 | const database = process.env.DBNAME;
28 | const user = process.env.DBUSER;
29 | const password = process.env.DBPASSWORD;
30 | 
31 | module.exports = {
32 |     db: {
33 |         server: "localhost",
34 |         database: database,
35 |         user: user,
36 |         password: password,
37 |     },
38 | };
39 | ```
40 | 
41 | **NOTE:** `__dirname` is required because the variables are `undefined` when accessing the `.env` file outside the root folder.
42 | 
43 | We can then have one `.env` file for development in the local machine, and one for production on the live server. This way we can just set the variables and not touch the code.
44 | 
45 | **NEVER COMMIT THIS FILE. PUT IT IN .gitignore!**
46 | 
47 | We can also pass in the variables without a `.env` file and run the script.
48 | 
49 | ```
50 | DBNAME=database DBUSER=root DBPASSWORD=root node server.js
51 | ```
52 | 


--------------------------------------------------------------------------------
/topics/dotnet.md:
--------------------------------------------------------------------------------
 1 | # .NET Framework
 2 | 
 3 | It's a computing framework for building applications on Windows, and it serves as an environment in which computer programs can run.
 4 | 
 5 | It is composed of: 
 6 | - **Assemblies**, which are typically `.exe` or `.dll` files that contain compiled code which requires .NET to run.
 7 | - **The Common Language Runtime (CLR)**. This is a set of Windows libraries whose job is to run assemblies. It's essentially a Virtual Machine.
 8 | - **Class libraries**. A set of object-oriented APIs which can be used by assemblies.
 9 | 
10 | It's possible for anyone to create a compiler that compiles a language for .NET, but the most common languages that use .NET are C# and VB.NET.
11 | 
12 | If you write your code to the framework, you can be sure it will work on anything that the framework says it can run on. In the case of Windows .NET, that means 'any' version of Windows. In the case of .NET Core, that's starting to mean 'any' modern device.
13 | 
14 | ### CLR
15 | 
16 | It's an application sitting in memory, whose job is to translate IL Code (Intermediate Language) into Machine Code i.e. JIT (Just-in-time-compilation).
17 | 
18 | Java's "CLR" is called "JVM".
19 | 
20 | C/C++ > Machine Code  
21 | Java > ByteCode (JVM) > Machine Code  
22 | C# > IL Code (CLR) > Machine Code
23 | 
24 | ### .dll
25 | 
26 | Basically a module i.e. a collection of reusable code for other programs to call.
27 | 
28 | ### .bat
29 | 
30 | A script file, equivalent to a Linux shell/bash script.
31 | 
32 | ### Class Library
33 | 
34 | Applications consist of the building block classes.  
35 | 
36 | Related classes are organized in containers called Namespaces.  
37 | 
38 | Namespaces are organized in an Assembly, either an EXE (Executable) or DLL (Dynamically Linked Library)
39 | 
40 | When the application is compiled, one or more Assemblies are made.
41 | 
42 | # For Development
43 | 
44 | 1. .NET contains a large set of programs which you can call through your program. These are the programs which contain simple functions like join two arrays to complex functions like translate voice to text /or recognize red object in a image(image analyses) etc, Provide functionality to make a internet application, mobile application etc, alot of them are provided(you can call those functions from your program). The .NET libraries are soo vast that you can program Robots/Arduino etc to develop signal processing, image analysis, large set of web application frameworks, etc.
45 | 
46 | 2. It maintains a common language underneath and allows you to program in different higher level languages like C#, VB, IronPython etc. When you compile it convert to a common language. It provides different set of build tools to develop applications, integrate, add other frameworks, allow others to easily write frameworks, etc.
47 | 
48 | # For End User: 
49 | 
50 | When you develop a program in .NET (or you can say using .NET) to run this program on many other computers you need to have a corresponding .NET framework available on that computer. So you have to install the .NET framework before you run your program. The .NET framework which you install on different computers have all the functionality your program needs but it wont have the tools for compile/build/develop .NET applications (because those are not needed on the end user machines. They also ported this framework to Linux so you can run .NET applications on Linux platform.


--------------------------------------------------------------------------------
/topics/electronics/arduino.md:
--------------------------------------------------------------------------------
  1 | # Arduino
  2 | 
  3 | **Arduino** is a development board utilizing an **AVR ATMEGA328** MCU (microcontroller). An MCU can't do much unless it's in a circuit.
  4 | 
  5 | The more professional option is to use a separate development board/launchpad for the MCUs. The idea is to plug in the MCU into it, program it, and take it out to be soldered in a circuit, rather than use the whole board like the Arduino.
  6 | 
  7 | Other popular microcontrollers: 8051, PIC, AVR, ARM, MSP
  8 | 
  9 | Microcontrollers have application specific small processing power while microprocessors have general purpose large processing power.
 10 | 
 11 | Microcontrollers have built in RAM, ROM and other peripherals in a single chip. Microprocessors have only the CPU, and other peripherals, RAM, ROM should be connected externally.
 12 | 
 13 | # Programming
 14 | 
 15 | Unlike most previous programmable circuit boards, the Arduino does not need a separate piece of hardware (called a programmer) in order to load new code onto the board – you can simply use a USB cable.
 16 | 
 17 | The Arduino IDE uses a simplified version of C++.
 18 | 
 19 | Arduino basically works by setting something upfront once and then by trapping execution in an infinite loop.
 20 | 
 21 | The code **will not** compile without `setup()` and `loop()`.
 22 | 
 23 | ```c
 24 | void setup() {
 25 |   // Setup code, run once
 26 | }
 27 | 
 28 | void loop() {
 29 |   // Main code, run repeatedly
 30 | }
 31 | ```
 32 | 
 33 | # Setup
 34 | 
 35 | We can select the type of board we are working with at tools > board, or add ones with the boards manager.
 36 | 
 37 | We define the way we are connecting to the board via a port at tools > port. It changes each time the board is disconnected.
 38 | 
 39 | # Upload
 40 | 
 41 | The code is compiled and uploaded into the chip via the USB cable. The built-in small LED light will blink in the frequency of the loop to indicate that it's working.
 42 | 
 43 | # Serial Monitor
 44 | 
 45 | We can see what Arduino outputs via tools > serial monitor. If we are getting weird characters, we need to set the **baud** value to the correct one.
 46 | 
 47 | # Pull-up resistor
 48 | 
 49 | Instead of adding resistors manually, we can use the built-in functionality.
 50 | 
 51 | ```c
 52 | pinMode(button, INPUT_PULLUP)
 53 | ```
 54 | 
 55 | # digitalWrite vs analogWrite
 56 | 
 57 | `digitalWrite` will set the specified pin to one of two states - HIGH/LOW, which equate to 5v (3.3v on some boards) and ground respectively.
 58 | 
 59 | `analogWrite` can vary by the type of output used. It will set the pin to a periodic high/low signal, where the percentage of the signal spent high is proportional to the value written. Ex. `analogWrite(PIN, 255)`.
 60 | 
 61 | pinMode(buzzerPin, OUTPUT);
 62 | 
 63 | # Simple blinking LED example
 64 | 
 65 | ```c
 66 | int LED = 12;
 67 | 
 68 | void setup() {
 69 |   pinMode(LED, OUTPUT);
 70 | }
 71 | 
 72 | void loop() {
 73 |   digitalWrite(LED, HIGH);
 74 |   delay(100);
 75 |   digitalWrite(LED, LOW);
 76 |   delay(100);
 77 | }
 78 | ```
 79 | 
 80 | ![Arduino LED](../../pics/arduino_led.jpg)
 81 | 
 82 | # Cop Car
 83 | 
 84 | ```c
 85 | int LED_RED = 12;
 86 | int LED_BLUE = 13;
 87 | int BUZZER = 10;
 88 | 
 89 | void setup() {
 90 |   pinMode(LED_RED, OUTPUT);
 91 |   pinMode(LED_BLUE, OUTPUT);
 92 |   pinMode(BUZZER, OUTPUT);
 93 | }
 94 | 
 95 | void loop() {
 96 |   tone(BUZZER, 200, 250);
 97 |   digitalWrite(LED_RED, HIGH);
 98 |   delay(500);
 99 |   digitalWrite(LED_RED, LOW);
100 | 
101 |   tone(BUZZER, 400, 250);
102 |   digitalWrite(LED_BLUE, HIGH);
103 |   delay(500);
104 |   digitalWrite(LED_BLUE, LOW);
105 | }
106 | ```
107 | 


--------------------------------------------------------------------------------
/topics/electronics/raspberrypi.md:
--------------------------------------------------------------------------------
1 | # Raspberry Pi
2 | 
3 | It's a micro-computer.
4 | 


--------------------------------------------------------------------------------
/topics/electronics/rfid.md:
--------------------------------------------------------------------------------
 1 | # Standards
 2 | 
 3 | | Family              | AKA  | Frequency | Protocol       | Storage     | Writable | Reader         |
 4 | | ------------------- | ---- | --------- | -------------- | ----------- | -------- | -------------- |
 5 | | Low Frequency (LF)  | RFID | 125 kHz   | EM4100         | UID 4 bytes | No       | RDM6300, RC522 |
 6 | | High Frequency (HF) | NFC  | 13.56 MHz | Mifare Classic | UID 4 bytes | 1 KB     | PN532          |
 7 | 
 8 | The UIDs are hard-coded by the manufacturer and cannot be changed.
 9 | 
10 | All cards contain a chip and an antenna. They are passive i.e. get the energy from the reader.
11 | 
12 | # Wiegand
13 | 
14 | This is a transmission protocol which connects the RFID reader with a controller.
15 | 
16 | The Wiegand interface has two data lines, DATA0 and DATA1. These lines are normally held high at 5V.
17 | 
18 | -   When a 0 is sent, DATA0 drops to 0V for a few µs.
19 | -   When a 1 is sent, DATA1 drops to 0V for a few µs.
20 | 
21 | There are a few ms between the pulses.
22 | 
23 | It transmits the UID in 2 formats:
24 | 
25 | -   W26 - Transports only first 3 bytes of the UID.
26 | -   W34 - Transports the whole UID (4 bytes). Connect brown wire to ground to get this format.
27 | 
28 | If the correct UIDs are not transported via serial, the D0 and D1 may need to be swapped.
29 | 
30 | ![Wiegand](../../pics/rfid_wiegand_arduino.jpg)
31 | 
32 | # Read Wiegand
33 | 
34 | ```javascript
35 | function bitCount(int_type) {
36 |     let count = 0;
37 |     while (int_type) {
38 |         int_type &= int_type - 1;
39 |         count += 1;
40 |     }
41 |     return count;
42 | }
43 | 
44 | let raw = 0x21a6616; // 10000110100110011000010110
45 | 
46 | let FAC_PAR_MASK = 0x2000000; // 10000000000000000000000000
47 | let FACILITY_MASK = 0x1fe0000; // 01111111100000000000000000
48 | let CARD_MASK = 0x1fffe; // 00000000011111111111111110
49 | let CARD_PAR_MASK = 1; // 00000000000000000000000001
50 | 
51 | let facility = (raw & FACILITY_MASK) >> 17;
52 | let card = (raw & CARD_MASK) >> 1;
53 | 
54 | let fac_par = (raw & FAC_PAR_MASK) >> 25;
55 | // even parity
56 | let fac_par_ok = (bitCount(facility) + fac_par) % 2 == 0;
57 | 
58 | let card_par = raw & CARD_PAR_MASK;
59 | // odd parity
60 | let card_par_ok = (bitCount(card) + card_par) % 2 == 1;
61 | 
62 | if (fac_par_ok && card_par_ok) {
63 |     console.log("Both parity bits ok, successful read.");
64 |     console.log("Facility:", facility);
65 |     console.log("Card:", card);
66 | } else {
67 |     if (!fac_par_ok) console.log("Facility parity check failed!");
68 |     if (!card_par_ok) console.log("Card parity check failed!");
69 | }
70 | ```
71 | 


--------------------------------------------------------------------------------
/topics/excel.md:
--------------------------------------------------------------------------------
 1 | # Insert pictures from URL
 2 | 
 3 | This code gets images from URLs and inserts them in the column to the right of the URL.
 4 | 
 5 | 1. Have a column with the image URLs, usually in range `A:A`. Leave an empty column on the right i.e. `B:B`.
 6 | 2. Open the Developer/Visual Basic tab.
 7 | 3. Paste the below code in a new module. (Insert/Module)
 8 | 4. Edit the `Rng` value in the code i.e. the range with image URLs ex. `A1:A100`.
 9 | 5. Click run and wait for the images to be populated in the adjacent column i.e. column `B:B`.
10 | 
11 | It takes around 2 seconds per image.
12 | 
13 | ```vbnet 
14 | Sub URLPictureInsert()
15 |     Dim xCol As Long
16 |     Dim xRg As Range
17 |     Dim w As Integer
18 |     Dim h As Integer
19 |     On Error Resume Next
20 |     Set Rng = ActiveSheet.Range("A1:A100")
21 |     w = 100
22 |     h = 100
23 |     For Each cell In Rng
24 |         xCol = cell.Column + 1
25 |         Set xRg = Cells(cell.Row, xCol)
26 |         xRg.ColumnWidth = 20
27 |         xRg.RowHeight = 100
28 |         ActiveSheet.Shapes.AddPicture Filename:=cell, LinkToFile:=msoFalse, SaveWithDocument:=msoCTrue, Left:=xRg.Left + (xRg.Width - w) / 2, Top:=xRg.Top + (xRg.Height - h) / 2, Width:=w, Height:=h
29 |         Next
30 | End Sub
31 | ```
32 | 
33 | # Google Sheets Cell Update Timestamp
34 | 
35 | 1. Modify code with corresponding sheet, cells and update cells.
36 | 2. Go to Tools/Script Editor.
37 | 3. Paste the code and click save. 
38 | 
39 | ```javascript
40 | function onEdit(e) {
41 |   var sh = e.source.getActiveSheet();
42 |   var sheets = ['Sheet1']; // Which sheets to run the code.
43 | 
44 |   // Columns with the data to be tracked. 1 = A, 2 = B...
45 |   var ind = [1, 2, 3].indexOf(e.range.columnStart); 
46 | 
47 |   // Which columns to have the timestamp, related to the data cells.
48 |   // Data in 1 (A) will have the timestamp in 4 (D)
49 |   var stampCols = [4, 5, 6]
50 |   
51 |   if(sheets.indexOf(sh.getName()) == -1 || ind == -1) return;
52 | 
53 |   // Insert/Update the timestamp.
54 |   var timestampCell = sh.getRange(e.range.rowStart, stampCols[ind]);
55 |   timestampCell.setValue(typeof e.value == 'object' ? null : new Date());
56 | }
57 | ```


--------------------------------------------------------------------------------
/topics/express.md:
--------------------------------------------------------------------------------
  1 | # npm mssql
  2 | 
  3 | Connections are expensive. Use them for one time open/close operations. Otherwise, use a pool when executing a series of queries.
  4 | 
  5 | **Async/Await**
  6 | 
  7 | ```Javascript
  8 | router.get("/api", async (req, res) => {
  9 | 
 10 |         let id = req.query.id;
 11 | 
 12 |         try {
 13 |             const connection = await sql.connect(db);
 14 |             const request = await connection.request()
 15 | 
 16 |             request.input("id", sql.Int, id);
 17 | 
 18 |             let query = `
 19 |                 select *
 20 |                 from products
 21 |                 where id = @id
 22 |             `
 23 | 
 24 |             let result = await request.query(query)
 25 | 
 26 |             res.send(result)
 27 | 
 28 |         } catch (err) {
 29 |             console.log("Error: " + err);
 30 |         } finally {
 31 |             sql.close();
 32 |         };
 33 | })
 34 | ```
 35 | 
 36 | **Promise**
 37 | 
 38 | ```js
 39 | new sql.ConnectionPool(db)
 40 |     .connect()
 41 |     .then((pool) => {
 42 |         return pool.request().query("SELECT * FROM product");
 43 |     })
 44 |     .then((result) => {
 45 |         let rows = result.recordset;
 46 |         res.setHeader("Access-Control-Allow-Origin", "*");
 47 |         res.status(200).json(rows);
 48 |         sql.close();
 49 |     })
 50 |     .catch((err) => {
 51 |         res.status(500).send({ message: "${err}" });
 52 |         sql.close();
 53 |     });
 54 | ```
 55 | 
 56 | **Callback**
 57 | 
 58 | ```js
 59 | sql.connect(db, function (err) {
 60 |     if (err) console.log(err);
 61 |     var request = new sql.Request();
 62 |     request.query("SELECT * FROM product", function (err, recordset) {
 63 |         if (err) console.log(err);
 64 | 
 65 |         let rows = recordset.recordsets[0];
 66 |         res.send(rows);
 67 |         sql.close(); // Important
 68 |     });
 69 | });
 70 | ```
 71 | 
 72 | # JSON
 73 | 
 74 | JSON is used to transfer data via a string.
 75 | 
 76 | An object from one programming language can be transferred to another by encoding it in JSON and then decoding it, even though they cannot understand each others' objects.
 77 | 
 78 | ```Javascript
 79 | // Javascript object literal.
 80 | var personObject = {
 81 |     firstName:"John",
 82 |     lastName:"Doe",
 83 |     age:50,
 84 |     eyeColor:"blue"
 85 | };
 86 | 
 87 | // Convert object to JSON.
 88 | var personJSON = JSON.stringify(personObject);
 89 | 
 90 | // personJSON.
 91 | {
 92 |     "firstName":"John",
 93 |     "lastName":"Doe",
 94 |     "age":50,
 95 |     "eyeColor":"blue"
 96 | }
 97 | 
 98 | // Convert JSON to object.
 99 | JSON.stringify(personJSON);
100 | ```
101 | 


--------------------------------------------------------------------------------
/topics/ftp.md:
--------------------------------------------------------------------------------
 1 | # File Transfer Protocol (FTP)
 2 | 
 3 | Used to transfer computer files between a remote and a local machine.
 4 | 
 5 | > `FTP` is insecure. Use `SFTP` instead.
 6 | 
 7 | `SFTP` is part of the SSH (Secure Shell) service, which is usually already installed and running on Linux.
 8 | 
 9 | As long as the server has `sshd` running and the user has `SSH` access, you can connect via `SFTP`.
10 | 
11 | ### **Server**
12 | 
13 | 1. Create an FTP user (just a normal Linux user).
14 | 
15 | ```bash
16 | sudo adduser john
17 | ```
18 | 
19 | You can check the existing users with `less /etc/passwd`.
20 | 
21 | 2. Add password.
22 | 
23 | ```bash
24 | sudo passwd john
25 | ```
26 | 
27 | 3. Limit user access to a specific directory.
28 | 
29 | ```bash
30 | sudo usermod -d /home/user/folder john
31 | ```
32 | 
33 | 4. Give read/write permissions (Might not be needed).
34 | 
35 | ```bash
36 | sudo chown john:john /home/user/folder
37 | sudo chmod -R 755 /home/user/folder
38 | ```
39 | 
40 | ### **Client**
41 | 
42 | You can now access the directory remotely with an `FTP` client. A popular one is Filezilla.
43 | 
44 | Just add you server's IP address in the `host` filed, along with the username and password created above.
45 | 
46 | Make sure you are using `SFTP` and port `22` (default SSH port) for the connection. It should use it automatically.
47 | 


--------------------------------------------------------------------------------
/topics/googleapi.md:
--------------------------------------------------------------------------------
 1 | # Sheets API
 2 | 
 3 | 1. Go to `console.developers.google.com`
 4 | 2. Create a project.
 5 | 3. Go to `console.developers.google.com/apis/credentials` and create API key for the project.
 6 | 4. Set the sheet to public for the request to work.
 7 | 
 8 | The sheet can be public i.e. `Anyone who has the link can view`, and be only editable privately. This avoids the OAuth part.
 9 | 
10 | ```javascript
11 | let sheet = "c750833d5021f60a1b8ff8bf0a21bb9dc74cff12";
12 | let range = "Sheet 1!A:B";
13 | let apiKey = "6e0ece719a48d5334369bd881b4324aa957e4407";
14 | 
15 | let url = `https://sheets.googleapis.com/v4/spreadsheets/${sheet}/values/${range}?key=${apiKey}`;
16 | 
17 | // https://sheets.googleapis.com/v4/spreadsheets/c750833d5021f60a1b8ff8bf0a21bb9dc74cff12/values/Sheet 1!A:B?key=6e0ece719a48d5334369bd881b4324aa957e4407
18 | 
19 | fetch(url)
20 |     .then((res) => res.json())
21 |     .then((data) => {
22 |         console.log(data);
23 |     })
24 |     .catch((err) => err);
25 | ```
26 | 
27 | ### Private sheet
28 | 
29 | With private user data you would need to use OAuth.
30 | 
31 | 1. Go to `console.developers.google.com/apis/library` and pick Sheets.
32 | 2. Configure OAuth.
33 | 


--------------------------------------------------------------------------------
/topics/googling.md:
--------------------------------------------------------------------------------
 1 | # Googling
 2 | 
 3 | These are called advanced search operators.
 4 | 
 5 | ```bash
 6 | # Keywords
 7 | 
 8 | "keyword"                # Must include keyword
 9 | "foo bar baz"            # Must include phrase
10 | 
11 | -keyword                 # Must exclude keyword
12 | -foo -bar -baz           # Must exclude keywords
13 | 
14 | # Content
15 | 
16 | intitle: foo             # Single
17 | allintitle: foo bar      # Multiple
18 | 
19 | inurl: foo             # Single
20 | allinurl: foo bar      # Multiple
21 | 
22 | intext: foo             # Single
23 | allintext: foo bar      # Multiple
24 | 
25 | # Specific website
26 | 
27 | website.com: query
28 | site:website.com query
29 | link:example.com        # Sites linking to example.com
30 | 
31 | # Files
32 | 
33 | filetype: pdf
34 | ext: pdf
35 | 
36 | # Period
37 | 
38 | after: 2017
39 | before: 2018
40 | 
41 | 2017..2018               # Between dates
42 | 
43 | # Utilities
44 | 
45 | define: meaning
46 | weather: berlin
47 | map: place
48 | stocks: aapl
49 | ```
50 | 
51 | Google Dorking, also known as Google Hacking, is a technique that utilizes advanced search operators to uncover information on the internet that may not be readily available through standard search queries.
52 | 
53 | Examples:
54 | 
55 | ```bash
56 | intitle: webcampxp 5
57 | 
58 | filetype:env "DB_PASSWORD"
59 | ```
60 | 


--------------------------------------------------------------------------------
/topics/graphql.md:
--------------------------------------------------------------------------------
 1 | It's a query language for APIs.
 2 | 
 3 | GraphQL solves a people problem, not a technical one. If you don't have the problem of too many people working with the same data model, you don't need GraphQL
 4 | 
 5 | GraphQL sounds like the ORM of HTTP APIs.
 6 | 
 7 | ---
 8 | 
 9 | GraphQL is an alternative to REST API. It's a typed query language.
10 | 
11 | It allows flexible querying from the front-end i.e. client.
12 | 
13 | It solves the problem of needing **just** a piece of data, without getting all the data from an end-point.
14 | 
15 | REST API would handle this for a `GET /user` request with:
16 | 
17 | -   `GET /user-slim` - Lots of routes and updating.
18 | -   `GET /user?data=slim` - The API becomes complex
19 | 
20 | GraphQL would handle this with `POST /user` by sending this query expression in the body.
21 | 
22 | ```js
23 | {
24 |     query {           // operation type
25 |         user {        // operation end-point
26 |             name      // requested field
27 |             age
28 |         }
29 |     }
30 | }
31 | ```
32 | 
33 | GraphQL **always** uses `POST` because it sends the query expression.
34 | 
35 | | REST API                 | GraphQL                   |
36 | | ------------------------ | ------------------------- |
37 | | GET                      | `query` operation type    |
38 | | POST, PUT, PATCH, DELETE | `mutation` operation type |
39 | | Routes                   | Query definitions         |
40 | | Controllers              | Resolvers                 |
41 | 


--------------------------------------------------------------------------------
/topics/javascript/basics.md:
--------------------------------------------------------------------------------
  1 | # Hoisting
  2 | 
  3 | Both variable and function declarations are hoisted to the top on code execution, meaning that their order is irrelevant i.e functions can be called before they are declared.
  4 | 
  5 | # Variables
  6 | 
  7 | ```javascript
  8 | var a;     // Regular.
  9 | let c;     // Block scoped.
 10 | const b;   // Immutable.
 11 | ```
 12 | 
 13 | # Functions
 14 | 
 15 | Functions are first class objects - a function is a regular object of type `function`. The function object type has a constructor: `Function`.
 16 | 
 17 | There are several ways to declare a function.
 18 | 
 19 | The difference is how the function interacts with the external components (the outer scope, the enclosing context, object that owns the method, etc) and the invocation type (regular function invocation, method invocation, constructor call, etc).
 20 | 
 21 | ## Function declaration
 22 | 
 23 | **Hoisted**. Available immediately after parsing, before any code is executed.
 24 | 
 25 | The function declaration creates a variable in the current scope with the identifier equal to function name. This variable holds the function object.
 26 | 
 27 | ```javascript
 28 | function foo() {}
 29 | foo();
 30 | ```
 31 | 
 32 | Use them when a function expression is not appropriate or when it is important that that a function is hoisted.
 33 | 
 34 | ## Function expression
 35 | 
 36 | **Not hoisted.** Available only after the variable assignment is executed.
 37 | 
 38 | ```javascript
 39 | // Named
 40 | let bar = function foo() {};
 41 | bar();
 42 | foo(); // undefined
 43 | ```
 44 | 
 45 | Use them when you are doing recursion or want to see the function name in the debugger.
 46 | 
 47 | ```javascript
 48 | // Anonymous
 49 | let foo = function () {};
 50 | foo();
 51 | 
 52 | let bar = foo();
 53 | bar(); // Error: not a function.
 54 | ```
 55 | 
 56 | Use them when you want to pass a function as an argument to another function or you want to form a closure.
 57 | 
 58 | ## IIFE - immediately Invoked Function Expression
 59 | 
 60 | ```javascript
 61 | (function () {
 62 |     // ...
 63 | })();
 64 | ```
 65 | 
 66 | Use them for the module pattern.
 67 | 
 68 | ## ES6
 69 | 
 70 | Binds `this` automatically.
 71 | 
 72 | ```javascript
 73 | let foo = () => {};
 74 | ```
 75 | 
 76 | Use them when you want to lexically bind the `this` value.
 77 | 
 78 | ## Function constructor (Avoid this)
 79 | 
 80 | ```javascript
 81 | let foo = new Function();
 82 | ```
 83 | 
 84 | ## Other
 85 | 
 86 | -   Use function declaration generators `function* foo(){}` when you want to exit and then re-enter a function.
 87 | -   Use function expression generators `let foo = function* [name](){}` when you want to exit and then re-enter a nested function.
 88 | 
 89 | ## Function parameters vs arguments
 90 | 
 91 | An argument is the value supplied to the parameter.
 92 | 
 93 | ```javascript
 94 | function foo(bar) {
 95 |     // bar is a parameter
 96 |     console.log(bar);
 97 | }
 98 | 
 99 | foo("baz"); // baz is an argument.
100 | ```
101 | 
102 | # Useful
103 | 
104 | ## Truthy / Falsy
105 | 
106 | Strings with at least one letter and numbers larger than zero are `truthy`.
107 | 
108 | ```javascript
109 | console.log(true && "foo"); // foo
110 | console.log(true && "foo" && 1); // 1
111 | ```
112 | 


--------------------------------------------------------------------------------
/topics/javascript/debugging.md:
--------------------------------------------------------------------------------
 1 | # Log
 2 | 
 3 | ```js
 4 | // Write to console
 5 | console.log();
 6 | 
 7 | // Show DOM element
 8 | console.dir();
 9 | 
10 | // Display a table. Takes an array of objects.
11 | console.table(array);
12 | ```
13 | 
14 | # Execution
15 | 
16 | ```js
17 | // Display the call stack of a function
18 | console.trace();
19 | 
20 | // Track execution time
21 | console.time("point"); // undefined
22 | console.timeEnd("point"); // point: 1337.42 ms
23 | 
24 | // Count the number of executions
25 | console.count("foo"); // foo: 1
26 | console.count("foo"); // foo: 2
27 | console.countReset("foo"); // undefined
28 | console.count("foo"); // foo: 1
29 | ```
30 | 
31 | # Memory
32 | 
33 | ```js
34 | // Heap size
35 | console.memory;
36 | 
37 | // Show memory usage
38 | setInterval(() => {
39 |     const used = process.memoryUsage().heapUsed / 1024 / 1024;
40 |     console.log(`Script uses ${Math.round(used * 100) / 100} MB`);
41 | }, 1000);
42 | ```
43 | 
44 | # Test
45 | 
46 | ```js
47 | // Avoid if-else statements
48 | function greaterThan(a, b) {
49 |     console.assert(a > b, { message: "a is not greater than b", a: a, b: b });
50 | }
51 | 
52 | greaterThan(2, 1); // a is not greater than b, a: 2, b: 1
53 | ```
54 | 


--------------------------------------------------------------------------------
/topics/javascript/language.md:
--------------------------------------------------------------------------------
 1 | # Language
 2 | 
 3 | The complete JavaScript implementation is made up of three distinct parts:
 4 | 
 5 | -   The Core (based on ECMAScript spec)
 6 | -   The Document Object Model (DOM)
 7 | -   The Browser Object Model (BOM)
 8 | 
 9 | # ECMAScript
10 | 
11 | ECMA-262 describes it like this:
12 | 
13 | ```
14 | ECMAScript can provide core scripting capabilities for a variety of host environments, and therefore the core scripting language is specified... apart from any particular host environment.
15 | ```
16 | 
17 | A Web browser is considered a host environment for ECMAScript, but it is not the only host environment. A list of other host environments listed here.
18 | 
19 | Apart from DOM and BOM, each browser has its own implementation of the ECMAScript interface.
20 | 
21 | # Document Object Model (DOM)
22 | 
23 | The Document Object Model (DOM) is an application programming interface (API) for HTML as well as XML.
24 | 
25 | The DOM maps out an entire page as a document composed of a hierarchy of nodes like a tree structure and using the DOMAPI nodes can be removed, added, and replaced.
26 | 
27 | ### DOM level 1
28 | 
29 | Consisted of two modules: the DOM Core, which provided a way to map the structure of an XML-based document to allow for easy access to and manipulation of any part of a document, and the DOM HTML, which extended the DOM Core by adding HTML-specific objects and methods.
30 | 
31 | ### DOM Level 2
32 | 
33 | Introduced several new modules of the DOM to deal with new types of interfaces:
34 | 
35 | -   DOM Views — describes interfaces to keep track of the various views of a document (that is, the document before CSS styling and the document after CSS styling)
36 | -   DOM Events — describes interfaces for events
37 | -   DOM Style — describes interfaces to deal with CSS-based styles
38 | -   DOM Traversal and Range — describes interfaces to traverse and manipulate a document tree
39 | 
40 | ### DOM Level 3
41 | 
42 | Further extends the DOM with the introduction of methods to load and save documents in a uniform way (contained in a new module called DOM Load and Save) as well as methods to validate a document (DOM Validation). In Level 3, the DOM Core is extended to support all of XML 1.0, including XML Infoset, XPath, and XML Base.
43 | 
44 | Note that the DOM is not JavaScript-specific, and indeed has been implemented in numerous other languages. For Web browsers, however, the DOM has been implemented using ECMAScript and now makes up a large part of the JavaScript language.
45 | 
46 | Other DOMs
47 | 
48 | -   Scalable Vector Graphics (SVG)
49 | -   Mathematical Markup Language (MathML)
50 | -   Synchronized Multimedia Integration Language (SMIL)
51 | 
52 | # Browser Object Model (BOM)
53 | 
54 | Browsers feature a Browser Object Model (BOM) that allows access and manipulation of the browser window. Using the BOM, developers can move the window, change text in the status bar, and perform other actions that do not directly relate to the page content.
55 | 
56 | Because no standards exist for the BOM, each browser has its own implementation.
57 | 
58 | # Event Loop
59 | 
60 | The Javascript runtime only knows of the `heap` and `call stack`.
61 | 
62 | The rest of the functionality, like async stuff, is provided in the form of `WebAPIs` by the browser/Node.
63 | 
64 | For async operations, the `callback` is offloaded into a separate `queue`, which is emptied by the `event loop` one by one as soon as the `stack` becomes empty.
65 | 
66 | Without the `event loop` the stack would be blocked during the whole duration of the async operaiton, basically freezing the app.
67 | 
68 | ![TEA](../pics/js_event_loop.png)
69 | 
70 | Based on [Philip Roberts' talk](https://www.youtube.com/watch?v=8aGhZQkoFbQ).
71 | 


--------------------------------------------------------------------------------
/topics/libraries-frontend.md:
--------------------------------------------------------------------------------
 1 | # Calendar
 2 | 
 3 | https://github.com/fullcalendar/fullcalendar
 4 | 
 5 | https://ui.toast.com/tui-calendar
 6 | https://github.com/nhn/tui.calendar
 7 | 
 8 | # React
 9 | 
10 | https://marmelab.com/react-admin/
11 | https://github.com/marmelab/react-admin
12 | 
13 | https://ant.design/
14 | https://github.com/ant-design/ant-design/
15 | 


--------------------------------------------------------------------------------
/topics/linux/cron.md:
--------------------------------------------------------------------------------
  1 | # Troubleshooting
  2 | 
  3 | 1. **LEAVE AN EMPTY NEW LINE AT THE END OF THE FILE!**
  4 | 
  5 |     - Cron jobs may fail to execute correctly if there's no newline at the end of the crontab file because the cron daemon expects each line to end with a newline character. If the last line does not end with a newline, the cron daemon might not read it properly, which can result in that job not being executed.
  6 | 
  7 | 2. Not using absolute paths
  8 | 
  9 | ```bash
 10 | * * * * * /bin/echo "cron works" >> /tmp/file
 11 | ```
 12 | 
 13 | 3. Not using a PATH variable
 14 | 
 15 | ```bash
 16 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 17 | * * * * * echo "cron works" >> /tmp/file
 18 | ```
 19 | 
 20 | 4. Not escaping characters
 21 | 
 22 | ```bash
 23 | # mysqldump --databases db > /home/user/backup-$(date +%Y%m%d-%H%M%S)
 24 | mysqldump --databases db > /home/user/backup-$(date +\%Y\%m\%d-\%H\%M\%S)
 25 | ```
 26 | 
 27 | NOTE: `echo` won't work because `cron` runs in its own shell.
 28 | 
 29 | # Cron
 30 | 
 31 | Each user has his own crontab i.e. cron table i.e table of scheduled processes.
 32 | 
 33 | **List**
 34 | 
 35 | ```bash
 36 | # list of tasks for current user
 37 | crontab -l
 38 | 
 39 | # list of tasks for specific user
 40 | crontab –u username –l
 41 | ```
 42 | 
 43 | **Edit**
 44 | 
 45 | ```bash
 46 | # edit crontabs for current user
 47 | crontab -e
 48 | 
 49 | # edit tasks for specific user
 50 | crontab –u username –e
 51 | 
 52 | # edit tasks for root user
 53 | sudo crontab -e
 54 | ```
 55 | 
 56 | **Jobs**
 57 | 
 58 | ```bash
 59 | # list of crontabs
 60 | sudo less /var/spool/cron/crontabs
 61 | 
 62 | # root systemwide crontab
 63 | sudo less /etc/crontab
 64 | ```
 65 | 
 66 | # Format
 67 | 
 68 | **NOTE: Cron doesn't do seconds. Minimum is every minute.**
 69 | 
 70 | ```
 71 | .---------------- minute (0 - 59)
 72 | |  .------------- hour (0 - 23)
 73 | |  |  .---------- day of month (1 - 31)
 74 | |  |  |  .------- month (1 - 12) OR jan, feb, mar, apr...
 75 | |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun, mon, tue, wed, thu, fri, sat
 76 | |  |  |  |  |
 77 | *  *  *  *  * command to be executed
 78 | 
 79 | *     all
 80 | ,     list of values
 81 | x-y   range of values
 82 | /x    recurring i.e. every x times
 83 | ```
 84 | 
 85 | **NOTE: The timing doesn't overlap, meaning it happens in both cases, not a combination of the two.**
 86 | 
 87 | ```bash
 88 | # Every minute
 89 | * * * * *
 90 | 
 91 | # Every hour
 92 | 0 * * * *
 93 | 
 94 | # Every 2 hours
 95 | 0 */2 * * *
 96 | 
 97 | # Every day @ 23:59
 98 | 59 23 * * *
 99 | 
100 | # Sunday @ 23:59
101 | 59 23 * * 0
102 | 
103 | # At every minute past every hour from 7 through 18 on every day-of-week from Monday through Friday
104 | * 7-18 * * 1-5
105 | 
106 | # At every 20th minute past hour 22 on day-of-month 1 and 15
107 | */20 22 1,15 * *
108 | 
109 | # At 10:15 on every 2nd day-of-month from 1 through 10 and on Friday
110 | 15 10 1-10/2 * 5
111 | 
112 | # Every 2 hours between 06:00 and 18:00, on Monday - Friday.
113 | 0 6-18/2 * * 1-5
114 | ```
115 | 


--------------------------------------------------------------------------------
/topics/linux/filesystem.md:
--------------------------------------------------------------------------------
 1 | # Files
 2 | 
 3 | **On a UNIX system, everything is a file. If something is not a file, it is a process.**
 4 | 
 5 | File extensions are meaningless. They are there for the user's sake.
 6 | 
 7 | Ubuntu is simply a collection (repository) of pre-compiled packages, running over a **kernel** (Big pile of software that knows how to make hardware do stuff).
 8 | 
 9 | ```
10 | Package = Plain text file > Compilation > Binary (.exe)
11 | ```
12 | 
13 | ## File types
14 | 
15 | -   **File**. Images, text, config...
16 | -   **Directory**. File pointing to files.
17 | -   **Link**. Shortcut/Redirect.
18 | -   **Pipe**. Use a process output as input for another.
19 | -   **Character Device**. Input/Output files Ex. Teminal.
20 | -   **Block**. Used for block devices. Ex. Hard Disk.
21 | -   **Socket**. Used for Interprocess Communication.
22 |     -   **Unix Socket**. Local machine only (Superfast). Ex. Nginx communicates with a PHP interpreter.
23 |     -   **TCP Socket**. Exposed to network (Slower). Ex. Nginx communicates with a website visitor.
24 | 
25 | ## Interprocess Communication (IPC)
26 | 
27 | Special files like **sockets** that allow processes to communicate with each other without dangerously sharing memory.
28 | 
29 | **Sockets** are files where processes can write stuff, and other processes can listen in real time.
30 | 
31 | # Filesystem
32 | 
33 | ### OS
34 | 
35 | ```bash
36 | /boot      # Bootloaders - Everything the OS needs to boot.
37 | /run       # Runtime - Information stored in RAM i.e. not written to disk.
38 | /sys       # System - Kernel interaction. Similar to /run.
39 | /proc      # Processes - Pseudo files with information for system processes, created by the kernel. Every process has a directory named by the PID (process ID). Ex. cat /proc/cpuinfo gives CPU info.
40 | ```
41 | 
42 | ### Devices
43 | 
44 | ```bash
45 | /dev           # Devices ex. mouse - Other programs and drivers use this.
46 |     /dev/sda   # Hard disk (main). `sda1` would be a partition.
47 | /media         # Device mounting (Automatic) - External hard drives, USBs.
48 | /mnt           # Device mounting (Manual)
49 | /cdrom         # Mounting point for CDs.
50 | ```
51 | 
52 | ### Programs
53 | 
54 | ```bash
55 | # System
56 | 
57 | /bin        # Binaries - Programs like ls, cat, grep...
58 | /sbin       # System binaries - Admin only programs.
59 | /lib        # Libraries - Used by bin and sbin.
60 | 
61 | # User
62 | 
63 | /usr        # Applications installed and used by the user.
64 | /opt        # Optional - Manually installed software from other vendors.
65 | /tmp        # Temp - Temporary files ex. auto-saves.
66 | ```
67 | 
68 | ### Configuration
69 | 
70 | ```bash
71 | /etc        # Etcetera - System wide cofiguration files.
72 | /var        # Variable - Files expected to grow in size ex. logs, databases.
73 | ```
74 | 
75 | ### Users
76 | 
77 | ```bash
78 | /root        # - Home folder for root users.
79 | /home        #. Home folders for each user, storing personal files.
80 | ```
81 | 
82 | ### Other
83 | 
84 | ```bash
85 | /srv        # Service - Web server files accessible by external users.
86 | /snap       # Self-contained Ubuntu apps.
87 | ```
88 | 


--------------------------------------------------------------------------------
/topics/linux/fzf.md:
--------------------------------------------------------------------------------
 1 | # fzf (Fuzzy Finder)
 2 | 
 3 | Download
 4 | 
 5 | ```bash
 6 | git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
 7 | ```
 8 | 
 9 | Install
10 | 
11 | ```bash
12 | ~/.fzf/install
13 | ```
14 | 
15 | Add this line to `~/.bashrc`.
16 | 
17 | ```
18 | [ -f ~/.fzf.bash ] && source ~/.fzf.bash
19 | ```
20 | 
21 | # fzf-cd
22 | 
23 | Navigate folders with `CTRL + f`.
24 | 
25 | Add this to `.bashrc`.
26 | 
27 | ```bash
28 | fzf_cd() {
29 |     dir=$(find /mnt/c/user/dev/lab \( -name "node_modules" -o -name ".git" -o -name "android" \) -prune -o -type d -print | fzf --no-preview)
30 |     cd "$dir"
31 | }
32 | 
33 | bind -x '"\C-f": "fzf_cd"'
34 | ```
35 | 


--------------------------------------------------------------------------------
/topics/linux/grep.md:
--------------------------------------------------------------------------------
 1 | # grep
 2 | 
 3 | ```bash
 4 | grep STRING FILE_NAME           # Find string in specific file.
 5 | grep -r STRING .                # Find string in all directory files.
 6 | grep -i STRING                  # Search without case sensitivity.
 7 | command | grep "foo"            # Search output of a command.
 8 | ```
 9 | 
10 | # fzf
11 | 


--------------------------------------------------------------------------------
/topics/linux/gzip.md:
--------------------------------------------------------------------------------
 1 | # gzip
 2 | 
 3 | This package creates a `.gz` compressed file, much like `.rar` or `.zip`.  
 4 | 
 5 | ## Compression
 6 | `gzip <file>` - Compress a file. *Deletes original file*.  
 7 | `gzip -k <file>` - Compress without deletion.  
 8 | 
 9 | `gzip -9 <file>` - Compression quality 1-9. *Default is 5*.
10 | 
11 | 
12 | ## Extraction
13 | `gzip -d <file>` or `gunzip <file>`- Extract.  
14 | 


--------------------------------------------------------------------------------
/topics/linux/rsync.md:
--------------------------------------------------------------------------------
 1 | Transfer files over SSH.
 2 | 
 3 | Only transfer the files that have changes or are missing. Much faster and secure than FTP.
 4 | 
 5 | # Options
 6 | 
 7 | ```bash
 8 | -a   # Recursion and preserve everything.
 9 | -v   # Transfer log.
10 | -h   # Display the output numbers in a human-readable format.
11 | -e   # Specify remote shell.
12 | -W   # Copy whole file, without checking for changes.
13 | 
14 | --progress   # Show the sync progress during transfer
15 | ```
16 | 
17 | # Exclude files/folders
18 | 
19 | ```
20 | rsync -av ./file1 ./folder1 --exclude 'folder1/node_modules/*' user@123.456.789.255:folder/
21 | ```
22 | 
23 | # Local > Remote
24 | 
25 | ```bash
26 | # Transfer everything from the current directory to a new folder in the remote home directory.
27 | rsync -av . user@123.456.789.255:folder/
28 | 
29 | # Transfer folder1 and its content to remote home directory
30 | rsync -av ./folder1 user@123.456.789.255:
31 | 
32 | # Transfer everything from folder1 without the folder itself to remote folder2 in remote home directory.
33 | rsync -av ./folder1/ user@123.456.789.255:folder2/
34 | 
35 | # Transfer multiple files and folders.
36 | rsync -av ./file1 ./file2 ./folder1 user@123.456.789.255:folder2/
37 | 
38 | # Another way
39 | rsync -av -e 'ssh' ./folder1/ user@123.456.789.255:~/folder1/
40 | ```
41 | 
42 | # Remote > Local
43 | 
44 | Runs from local
45 | 
46 | ```bash
47 | rsync -av user@123.456.789.255:folder/ /path/to/local/storage
48 | ```
49 | 
50 | # Freezing
51 | 
52 | When the terminal freezes, fix it with this in a **new** terminal...
53 | 
54 | ```bash
55 | while sudo killall -CHLD ssh; do sleep 0.1; done;
56 | ```
57 | 
58 | # Virtual Machine
59 | 
60 | ```bash
61 | rsync -av -e "ssh -p PORT_NUMBER" <SOURCE> <DESTINATION>:<PATH>
62 | 
63 | rsync -av -e 'ssh -p 3022' . user@127.0.0.1:~/make-this_folder
64 | ```
65 | 
66 | # Backup
67 | 
68 | To copy multiple files, the command must be a string. This will copy the content from the locations to the single location the command is called from.
69 | 
70 | ```bash
71 | rsync -av -e 'ssh' 'root@123.456.789.255:/etc/nginx/nginx.conf /etc/letsencrypt/keys' .
72 | ```
73 | 
74 | This command will copy the `nginx.conf` file and the letsencrypt folder with the keys. The command must run as root for the keys.
75 | 


--------------------------------------------------------------------------------
/topics/linux/services.md:
--------------------------------------------------------------------------------
 1 | # service
 2 | 
 3 | `service` is an "high-level" command used for starting and stopping services in different unixes and linuxes.
 4 | 
 5 | ```bash
 6 | sudo service <service> <command>
 7 | 
 8 | # Commands
 9 | status        # Shows the status and last lines of log.
10 | start         # Starts a service.
11 | stop          # Stops a service.
12 | 
13 | reload        # Re-read the configuration files.
14 | restart       # Restart the service and re-read config files.
15 | 
16 | # List
17 | service --status-all
18 | ```
19 | 
20 | Depending on the "lower-level" service manager, service redirects to different binaries:
21 | 
22 | -   For CentOS 7 it redirects to `systemctl`.
23 | -   For CentOS 6 it directly calls the relative `/etc/init.d` script.
24 | -   In older Ubuntu releases it redirects to `upstart`.
25 | 
26 | `service` is adequate for basic service management, while directly calling `systemctl` give greater control options.
27 | 
28 | # systemctl
29 | 
30 | `systemctl` is a command-line tool that interacts with `systemd`. It is used to control the `systemd` system and service manager.
31 | 
32 | ```bash
33 | sudo systemctl <command> <service>
34 | 
35 | # Commands
36 | enable        # Enable start on BOOT.
37 | disable       # Disable start on BOOT.
38 | 
39 | # List
40 | systemctl list-units
41 | ```
42 | 
43 | # systemd
44 | 
45 | > `systemd` handles initializing everything that needs to launch behind the scenes when starting up Linux.
46 | 
47 | Anything that ends in a "d" is a daemon i.e. a process that works in the background.
48 | 
49 | Systemd is the daddy of processes. Process ID number 1. It starts all other processes/daemons at boot. It has integrated tools that manage, for example, wifi, bluetooth, suspend/shutdown, etc.
50 | 
51 | The original way of starting everything when a linux system boots was to just run each thing, one after another with scripts.
52 | 
53 | Systemd started as a more intelligent way of doing things, which could handle starting multiple things at the same time and thought about dependencies - you can't start things that need the network until you've started the network devices, for example. It mostly seemed like a good idea.
54 | 
55 | Systemd has since grown considerably, taking over other tasks. This has been controversial. Some people feel that systemd is forcing its way into things that an init system has no business touching.
56 | 
57 | So, at it's core Systemd is an init system, which is the first program that runs at boot, it launches all your daemons, and just performs general boot processes. People dislike it because it is getting pretty large, and some worry that it will become the next Xorg, in that it will become a chore to maintain, and it would be difficult to audit, along with Lenart Poeterring (creator of Systemd) being known for dismissing some potential problems.
58 | 
59 | This tool is used for managing services (units).
60 | 
61 | Service/Daemon is an on-going process that provides a service, usually designed to interact with something outside of it. Ex. web server, monitoring tool, database...
62 | 
63 | # journalctl
64 | 
65 | Manages logs.
66 | 
67 | ```bash
68 | journalctl -u SERVICE              # Log from a service.
69 | journalctl --since "10 min ago"    # Log from last 10 minutes.
70 | ```
71 | 


--------------------------------------------------------------------------------
/topics/linux/ssh.md:
--------------------------------------------------------------------------------
 1 | # Install
 2 | 
 3 | ```bash
 4 | sudo apt-get install openssh-server
 5 | ```
 6 | 
 7 | # Connect
 8 | 
 9 | ```bash
10 | ssh -p PORT USER@SERVER_IP
11 | 
12 | # Execute one command and exit.
13 | ssh -p PORT USER@SERVER_IP ls
14 | ```
15 | 
16 | SSH in Virtual Machine needs a port forwarding rule in network settings for the VM. Name `ssh`, host port `3022`, guest port `22`.
17 | 
18 | ```bash
19 | # SSH to local VM via port forwarding.
20 | ssh -p 3022 user@127.0.0.1
21 | ```
22 | 
23 | # sudo command
24 | 
25 | ```bash
26 | # It will ask for the root password in the remote machine
27 | ssh -t user@255.255.255.255 "sudo command"
28 | ```
29 | 
30 | # Alias
31 | 
32 | ```bash
33 | /etc/ssh/ssh_config   # system-wide
34 | ~/.ssh/config         # per user (better)
35 | 
36 | # Add this in the config.
37 | Host server_name
38 |   Port 22
39 |   User user
40 |   HostName 123.456.789.255
41 | 
42 | # Connect with this now.
43 | ssh server_name
44 | ```
45 | 
46 | # SSH with RSA key
47 | 
48 | Access servers with a **public/private** key instead of a password. This is a **much** more secure method.
49 | 
50 | Transfer the **public** key `id_rsa.pub` to the remote server, in the `~/.ssh/authorized_keys` file, with this command:
51 | 
52 | ```bash
53 | ssh-copy-id -i ~/.ssh/id_rsa.pub user@123.456.789.255
54 | ```
55 | 
56 | **If the keys don't exist** on local machine, generate them:
57 | 
58 | ```bash
59 | ssh-keygen
60 | 
61 | # keys are stored in /home/user/.ssh
62 | ls ~/.ssh
63 | ```
64 | 
65 | The **private** key `id_rsa` stays in the local machine.
66 | 


--------------------------------------------------------------------------------
/topics/linux/terminology.md:
--------------------------------------------------------------------------------
1 | # Terminology
2 | 
3 | -   **Relational Database Management System (RDBMS)** - MySQL, SQL Serverm Postgresql
4 | -   **schema** - database creation blueprint with column definitions.
5 | -   **database** - company_name
6 | -   **namespace** - client1.orders, client2.orders... sales.documents, legal.documents...
7 | -   **table** - orders, documents...
8 | -   **row**
9 | 


--------------------------------------------------------------------------------
/topics/linux/tmux.md:
--------------------------------------------------------------------------------
 1 | # Basic
 2 | 
 3 | ```bash
 4 | tmux                # Start tmux.
 5 | CTRL + B            # Command mode.
 6 | SHIFT + select      # Select/Paste text.
 7 | ```
 8 | 
 9 | # Windows (tabs)
10 | 
11 | ```bash
12 | c          # New window.
13 | numbers    # Change window.
14 | ,          # Name window.
15 | w          # List windows.
16 | .          # Move window. Asks for a number.
17 | &          # Close window.
18 | CTRL + D   # Close window.
19 | ```
20 | 
21 | # Panes (splits)
22 | 
23 | ```bash
24 | %        # Split horizontally (left/right).
25 | \"       # Split vertically (top/bottom).
26 | arrows   # Change pane. Resize if holding command.
27 | x        # Close pane.
28 | q        # Show pane numbers
29 | space    # Toggle between layouts
30 | ```
31 | 
32 | # Scrolling
33 | 
34 | ```bash
35 | [          # Scrolling mode with arrows or PageUp/PageDown.
36 | CTRL + C   # Exit scrolling mode.
37 | ```
38 | 
39 | # Mouse scrolling
40 | 
41 | In order to configurate tmux, a `.tmux.conf` file is needed, as it doesn't exist. We can create this with `sudo touch /etc/.tmux.conf`, or `sudo touch ~/.tmux.conf` for a user specific one.
42 | 
43 | **.tmux.conf**
44 | 
45 | ```bash
46 | # Activate mouse (Scrolling, selecting, re-sizing)
47 | set -g mouse on
48 | 
49 | bind-key -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel "xclip -selection clipboard"
50 | ```
51 | 
52 | **IMPORTANT:** You must reload the configuration.
53 | 
54 | ```bash
55 | tmux source-file ~/.tmux.conf
56 | 
57 | # Inside tmux (CTRL + B + :)
58 | source-file ~/.tmux.conf
59 | ```
60 | 
61 | # Setup script
62 | 
63 | Create a `tmux.sh` file to automate the setup.
64 | 
65 | ```bash
66 | # Start a new tmux session
67 | tmux new-session -d  \; \
68 | 
69 | # Split the window vertically: left and right
70 | tmux split-window -h  \; \
71 | 
72 | # Split the right pane vertically: left and right
73 | tmux split-window -h  \; \
74 | 
75 | # Adjust the panes to be of equal width
76 | tmux select-layout even-horizontal
77 | 
78 | # Run a script in the first pane (left)
79 | tmux send-keys -t 0 'cd ~/project/app && npm run dev' C-m  \; \
80 | 
81 | # Run a script in the second pane (middle)
82 | tmux send-keys -t 1 'cd ~/project/server/nodemon server.js' C-m \; \
83 | 
84 | # Move focus to the third pane (right)
85 | tmux select-pane -t 2 \; \
86 | 
87 | # Attach to the tmux session to see the panes
88 | tmux attach-session
89 | ```
90 | 


--------------------------------------------------------------------------------
/topics/logging.md:
--------------------------------------------------------------------------------
 1 | Winston, log4js, bunyan are logging libraries.
 2 | 
 3 | The act of persisting the log is called:
 4 | 
 5 | -   Winston: Transports
 6 | -   Bunyan: Streams
 7 | -   Log4js: Appenders
 8 | 
 9 | In Winston 3, a "transport" is a storage device for your logs, a writable stream i.e. carrying the data from the app to the console or file.
10 | 
11 | **Don't go crazy with logging. Use it to know what came in and out of the system. You can figure out almost everything with those two.**
12 | 
13 | # Winston
14 | 
15 | ```js
16 | ```
17 | 


--------------------------------------------------------------------------------
/topics/messageBrokers.md:
--------------------------------------------------------------------------------
 1 | Message brokers are also called queues, busses.
 2 | 
 3 | Kafka, RabbitMQ, MQtt
 4 | 
 5 | https://www.youtube.com/watch?v=aj9CDZm0Glc&ab_channel=IBMTechnology
 6 | https://www.youtube.com/watch?v=Ch5VhJzaoaI&ab_channel=JamesCutajar
 7 | https://www.youtube.com/watch?v=W4_aGb_MOls&ab_channel=HusseinNasser
 8 | https://www.youtube.com/watch?v=PzPXRmVHMxI&ab_channel=StephaneMaarek
 9 | https://www.youtube.com/watch?v=7rkeORD4jSw&ab_channel=IBMTechnology
10 | 


--------------------------------------------------------------------------------
/topics/microservices.md:
--------------------------------------------------------------------------------
 1 | # Caveat
 2 | 
 3 | > **DO NOT start building new application as microservices!**
 4 | 
 5 | > Micro-\* is largely about separating deployment for big teams.
 6 | 
 7 | Focus on building a modular, decoupled, easy to change application first.
 8 | 
 9 | When we have semi-stable decoupled modules - and there is a real business need - only then we should think about breaking it into microservices.
10 | 
11 | The process of breaking down the application into microservices is really nuanced, and to do it right requires a lot of knowledge and experience in managing software architecture.
12 | 
13 | > This is what happens when you read all those Kubernetes / orchestration / microservices / highscalability blog posts starting about 3 years ago, and come to the realization that you don't have Google-scale problems...
14 | 
15 | Microservices is more of an organizational structure than a software architecture. Basically you more or less HAVE to do Domain Driven Design to separate 'pieces' of the business between many teams.
16 | 
17 | As I hear stories about teams using a microservices architecture, I've noticed a common pattern.
18 | 
19 | -   Almost all the successful microservice stories have started with a monolith that got too big and was broken up
20 | -   Almost all the cases where I've heard of a system that was built as a microservice system from scratch, it has ended up in serious trouble.
21 | 
22 | This pattern has led many of my colleagues to argue that you shouldn't start a new project with microservices, even if you're sure your application will be big enough to make it worthwhile.
23 | 
24 | [Martin Fowler](https://martinfowler.com/bliki/MonolithFirst.html)
25 | 
26 | # Microservices
27 | 
28 | Developing a single application as a suite of small services, each running its own process and communicating with lightweight mechanisms, often an HTTP resource API.
29 | 
30 | Think of it like an organs system, where each organ has a purpose, the organs form a system, which form an organism.
31 | 
32 | ```
33 | Microservice > Container > Virtual Machine > Hypervisor > Server > Rack > Datacenter > Cloud
34 | ```
35 | 
36 | The other thing that I'd like to point out is that a microservices architecture is only great when the application becomes too large and complex. A microservices architecture requires more resources as it has some additional overhead. Start with a monolithic first.
37 | 
38 | A microservice can be a complete application including its own UI, business logic and data. **Usually it's just backend and data.**
39 | 
40 | Each microservice is a team.
41 | 
42 | # Misconceptions
43 | 
44 | -   _Micro services enable our teams to choose the best programming languages and frameworks for their tasks_. - Reality: It's super expensive to do this. Team size and investment are critical inputs.
45 | 
46 | -   _Code generation is evil_ - What's important is creating a defined schema that is 100% trusted.
47 | 
48 | -   _The event log must be the source of truth_. - Events are critical parts of an interface. But it's okay for services to be the system of record for their resources.
49 | 
50 | -   _Developers can maintain no more than 3 services each._ Wrong metric.
51 | 


--------------------------------------------------------------------------------
/topics/mobileCordova.md:
--------------------------------------------------------------------------------
 1 | # Apache Cordova
 2 | 
 3 | Mobile apps can be created with HTML, CSS and Javascript.
 4 | 
 5 | The mobile app is a website running in a webview, like Electron for desktop. A webview is a wrapper i.e. a shell browser, without the menus, tabs etc.
 6 | 
 7 | The native device features can be accessed through the wrapper, not directly. Also, The UI components automatically adjust to the platform.
 8 | 
 9 | ## History
10 | 
11 | -   PhoneGap was previously a product of Adobe.
12 | -   To keep it open-source always and follow standards, PhoneGap codebase was handed over to Apache.
13 | -   At Apache, it got a name change as Cordova.
14 | -   And now it’s better known as Apache Cordova.
15 | -   Ionic sits on top of Cordova as a UI library with Angular, to give the web app a native feel.
16 | 
17 | PhoneGap is paid.
18 | Cordova is open source.
19 | The codebase is the same.
20 | 
21 | If you use phonegap/Cordova you are using plain JavaScript (and can therefore choose to add any framework, including Angular, to that) whereas if you're using ionic then you're an AngularJs developer.
22 | 
23 | ## Install
24 | 
25 | To run Cordova, node is required. NPM is used for intalling Cordova, along with the plarforms and plugins.
26 | 
27 | ```bash
28 | sudo npm i cordova -g
29 | ```
30 | 
31 | When the app is compiled, the target platform SDK is required.
32 | 
33 | -   Adroid Stuido for Android SDK.
34 | -   Xcode for iPhone SDK.
35 | 
36 | ## Create app
37 | 
38 | ```bash
39 | #cordova folder_name package_name app_name
40 | cordova create myApp com.domain.app AppName
41 | ```
42 | 
43 | This will create the following:
44 | 
45 | -   `config.xml` - Old configuration (Don't use)
46 | -   `hooks` - Special build tools go here.
47 | -   `package.json` - Configuration
48 | -   `platforms` - SKDs are stored here.
49 | -   `plugins` - Like node_modules
50 | -   `res` - Additional resources, like icons.
51 | -   `www` - The web app lives here.
52 |     -   css
53 |     -   img
54 |     -   js
55 |     -   index.html
56 | 
57 | The phone doesn't call the apps by name. It uses a special internal name to reference them.
58 | 
59 | Reverse domain name notation is used as the naming convention for the packages. They are based on registered domain names, and are only reversed for sorting purposes.
60 | 
61 | For example, if a company making a product called `MyProduct` has the registered domain name `example.com`, they could use the reverse-DNS string `com.example.MyProduct` to describe it.
62 | 
63 | Reverse-DNS names are a simple way of reducing name-space collisions, since any domain name is registered by only one party at a time.
64 | 
65 | ## Add platform
66 | 
67 | ```bash
68 | cordova platform add android
69 | ```
70 | 
71 | ## Emulate app
72 | 
73 | This will load the app inside the emulator. You first need to create it with a system image for the target platform with AVD.
74 | 
75 | ```bash
76 | cordova emulate android
77 | ```
78 | 
79 | ## Build app
80 | 
81 | This will build the app i.e. `.apk` file, which can be installed on an android device.
82 | 
83 | ```bash
84 | cordova build android
85 | ```
86 | 


--------------------------------------------------------------------------------
/topics/mobilePWA.md:
--------------------------------------------------------------------------------
 1 | ![App Types](../pics/mobile/mobile_pwa.jpg)
 2 | 
 3 | Technology developed by Google in 2015 enables mobile devices to add a website or web application to a smartphone's home screen and be able to interact with it like a native app, which can work offline.
 4 | 
 5 | PWAs use the browser technology from the browser it was installed from.
 6 | 
 7 | Mobile app users spend 87% of time in native apps, compared to 13% in browser apps.
 8 | 
 9 | This happens because:
10 | 
11 | -   Push notifications help engagement.
12 | -   Icons for fast access.
13 | -   Access native devices like camera.
14 | -   Offline work.
15 | 
16 | PWA's live on the web, have native capabilities i.e installable and push notifications.
17 | 
18 | A progressive web application (PWA) is a type of application software delivered through the web, built using common web technologies including HTML, CSS and JavaScript. It is intended to work on any platform that uses a standards-compliant browser, including both desktop and mobile devices.
19 | 
20 | PWA's offer:
21 | 
22 | -   Offline work
23 | -   Push notifications
24 | -   Phone app
25 | 
26 | They have no access to the phone capabilities, such as camera.
27 | 
28 | Browser > Add to home screen
29 | 
30 | To become a PWA, the app needs:
31 | 
32 | -   Service worker - js program serving as a mediator between the app vs network and cache.
33 | -   Manifest - JSON file containing the settings for the phone app (icon, name...).
34 | 
35 | Direct deployment. Send the app directly to the user, rather than have them download it from a store.
36 | 


--------------------------------------------------------------------------------
/topics/mobileiOS.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/8483/notes/df1c7ab62a3f0e36a87063bea77eed15c3bd5886/topics/mobileiOS.md


--------------------------------------------------------------------------------
/topics/mvc.md:
--------------------------------------------------------------------------------
1 | ![mvc](../pics/mvc_full_stack.jpg)


--------------------------------------------------------------------------------
/topics/networkingDevices.md:
--------------------------------------------------------------------------------
 1 | # Overview
 2 | 
 3 | Hubs and switches create networks.  
 4 | Routers connect networks.
 5 | 
 6 | ```
 7 | PC 1 -----|                            |----- Router
 8 |           |                            |
 9 | PC 2 -----|----- Router --- Modem -----|----- Router
10 |           |                            |
11 | Phone ----|                            |----- Router
12 | 
13 | ----------------------------------     -------------
14 |         Local network                     Internet
15 | ```
16 | 
17 | # Connect Networks
18 | 
19 | ## **Modem**
20 | 
21 | Converts the internet's analog signals to digital ones for your computer, and vice-versa.
22 | 
23 | Establishes a connection to your ISP, and bings the internet into your home or business.
24 | 
25 | Comes before the router, usually bundled together.
26 | 
27 | You can connect directly to the modem, but a router is needed for multiple devices.
28 | 
29 | Short for modulator/demodulator.
30 | 
31 | ## **Router**
32 | 
33 | The **gateway** of a network.
34 | 
35 | Routes data from one network to another based on their IP address.
36 | 
37 | It determines if the data is for its own network and receives it, or forwards it to another one if it's not.
38 | 
39 | Comes after the modem, usually bundled together.
40 | 
41 | Passes your internet connection to all your devices via its built in switch for wired connections or access point for wireless ones.
42 | 
43 | # Create and expand networks
44 | 
45 | These devices do not read IP addresses, only MAC.
46 | 
47 | ## **Switch**
48 | 
49 | Detects and identifies **specific** devices connected to it.
50 | 
51 | Routes a signal to a specific device connected via ethernet, by storing its MAC address.
52 | 
53 | Routers have one built in.
54 | 
55 | It's a smart hub.
56 | 
57 | ## **Hub**
58 | 
59 | Only detects devices connected to it.
60 | 
61 | Routes a signal to **all** connected devices via ethernet.
62 | 
63 | # Drivers
64 | 
65 | Drivers act like a translator between the device they control, and the other programs in your system.
66 | 
67 | For instance, lets say you want to print "hello world" on a piece of paper. So you type that in to notepad, and click print.
68 | Windows passes the printer driver the document and says "Print this."
69 | The printer driver takes the information it gets, then turns to the printer and says "I want you to print out the following letters 'h' then 'e' then 'l' and so on.
70 | 
71 | Except it's all a lot more complicated than that because we don't send individual letters to a printer any more, we send a lot more detailed information about where to put ink or toner down, how to mix and layer ink or toner to get finely detailed pictures to come out clearly, and a lot of printers actually are smart enough to do these things on their own under certain conditions (like printing out pictures stored on a USB drive plugged directly to a printer)
72 | 


--------------------------------------------------------------------------------
/topics/networkingLayer2LinkMAC.md:
--------------------------------------------------------------------------------
 1 | # MAC
 2 | 
 3 | Physical address of a device.
 4 | 
 5 | IP address locates the device, MAC identifies it.
 6 | 
 7 | Devices need it to communicate on the local network.
 8 | 
 9 | They get it with ARP.
10 | 
11 | # ARP - Address Resolution Protocol
12 | 
13 | Used to resolve IP addresses to MAC addresses.
14 | 
15 | The broadcast does not go beyond the router.
16 | 
17 | ```
18 | Device A - Who is 10.0.0.4? I need the MAC address.
19 | 
20 | Device B - I am 10.0.0.4. I will send you the MAC address.
21 | ```
22 | 
23 | This is all cached to avoid sending the signal again.
24 | 
25 | ```
26 | arp -a
27 | ```
28 | 
29 | IP addresses can be matched to MAC manually.
30 | 
31 | ```
32 | arp -s 10.0.0.4 90-02-7b-c2-c0-67
33 | ```
34 | 


--------------------------------------------------------------------------------
/topics/networkingLayer4TransferTCP.md:
--------------------------------------------------------------------------------
 1 | # TCP - Transmission Control Protocol
 2 | 
 3 | TCP is implemented in the operating system.
 4 | 
 5 | All traffic is split up into messages called packets, sent between two computers in a stream, with the addresses of the sender and recipient in each one.
 6 | 
 7 | TCP just provides "envelopes" that can transfer bytes around the network.
 8 | 
 9 | An application protocol assigns structure and meaning to the contents of the envelopes.
10 | 
11 | **If you speak English and I send you a letter written in French, you'll still get the letter, but you won't understand it.**
12 | 
13 | # Ports
14 | 
15 | IP addresses locate devices. Ports locate programs on the devices.
16 | 
17 | ```bash
18 | netstat -n
19 | 
20 | Proto   Local addresses    Foreign addresses   State
21 | 
22 | TCP    92.168.0.12:52913   215.114.85.17:80    ESTABLISHED # HTTP Web server
23 | TCP    92.168.0.12:52920   215.114.85.17:21    ESTABLISHED # FTP server
24 | ```
25 | 
26 | Ports are like "IP addresses" for programs/services we want to use i.e. locating where they are running on a device, which has an actual IP address to locate it.
27 | 
28 | | Location |       Type        |      Range      |                           Example                           |
29 | | :------: | :---------------: | :-------------: | :---------------------------------------------------------: |
30 | |  Server  | System/Well-known |    0 - 1,023    |          80 (HTTP), 443 (SSL), 25 (SMTP), 21 (FTP)          |
31 | |  Server  |  User/Registered  | 1,024 - 49,151  |          1433 (MSSQL), 1527 (Oracle), 1102 (Adobe)          |
32 | |  Client  |  Dynamic/Private  | 49,152 - 65,535 | Termporarily assigned for client while using above services |
33 | 
34 | Listening on a port is like waiting for a phone call on a specific phone number.
35 | 
36 | Ports let servers distinguish one service from another on the same host and wait for someone to connect.
37 | 
38 | Ports are not physical, but logical.
39 | 
40 | Ports are always associated with an IP address, allowing programs to exchange data over the network.
41 | 
42 | Normally a server has well known ports for it's applications. The client initiates a connection, and it's associated with an arbitrary port on its end.
43 | 
44 | **Only one program can listen to a port in a given moment**. Once started, the program can start child processes to listen for multiple connections on the same port i.e. a web server.
45 | 
46 | The port range that a normal (non-root) user can listen on is `1024 - 65535`. Root access (including sudo) can listen on ports down to 1.
47 | 
48 | If the other side doesn't pick up, an RST (Reset packet) error message is sent back.
49 | 


--------------------------------------------------------------------------------
/topics/networkingModelOSI.md:
--------------------------------------------------------------------------------
 1 | # OSI Model
 2 | 
 3 | OSI/IP : Used to identify the devices corresponding to the protocols , and their relationships, that are involved during this communication
 4 | 
 5 | ## 1. Physical layer
 6 | 
 7 | This is mostly Ethnernet cables i.e. "The wire". It has no intelligence, as the datalink determines how it's used.
 8 | 
 9 | ## 2. Datalink layer
10 | 
11 | Transforms the layers above into signals transmitter over the wire, called `frames`. Most environments use Ethernet as the datalink layer.
12 | 
13 | IPv4:
14 | 
15 | -   Media Access Control (MAC)
16 | -   Address Resolution Protocol (ARP)
17 | 
18 | IPv6:
19 | 
20 | -   MAC
21 | -   Neighbor Discovery (ND)
22 | 
23 | ## 3. Network layer
24 | 
25 | Maps connectivity between hosts. i.e. "Can I and how do I get to this other host?"
26 | 
27 | Provides a consistent interface to network programs.
28 | 
29 | A single chunk of network data is called a `packet`.
30 | 
31 | The Internet uses the `Internet Protocol (IP)` which gives each host one or more unique IP addresses, so other hosts can find it.
32 | 
33 | Network Address Translation (NAT) screws around with the "unique address" rule, but ultimately, you have a globally unique IP address on your or provider's network.
34 | 
35 | ## 4. Transport layer
36 | 
37 | The data you care about, called `segments`, flows here.
38 | 
39 | ### ICMP - Internet Control Message Protocol
40 | 
41 | Low-level connectivity messages between hosts i.e. `ping`, re-routing traffic, Datalink layer errors...
42 | 
43 | ### TCP - Transmission Control Protocol
44 | 
45 | Rich (reliable) transmission of application data between hosts. Has error checking, congestion control, retransmission of lost data.
46 | 
47 | ### UDP - User Diagram Protocol
48 | 
49 | Simple (unreliable) transmission of application data between hosts. Reliability is handled in the application, rather than layer. Usually video games.
50 | 
51 | ## 5. Application layer
52 | 
53 | For simplicity and more realistic use, it bundles the OSI layers above it:
54 | 
55 | -   **Session layer** - open/close transport layer connections.
56 | -   **Presentation layer** - Lets programs exchange data.
57 | -   **Application layer** - Actual protocol spoken over these connections.
58 | 
59 | The `TCP/IP` model calls everything above the transport layer the application layer. It includes protocols like HTTP, SMTP, LDAP...
60 | 


--------------------------------------------------------------------------------
/topics/networkingOverview.md:
--------------------------------------------------------------------------------
 1 | # ELI5
 2 | 
 3 | Create a basic program that sends a string to the specified ip/port.
 4 | 
 5 | Create a second program that listens on that ip/port and prints out any received strings.
 6 | 
 7 | Congratulations you now know how every network works. The rest is security, data verification/validation, optimization.
 8 | 
 9 | # Analogy
10 | 
11 | ### **Highway**
12 | 
13 | Think of IP as a sort of high-way that allows other protocols to get on and find their way to other computers. TCP and UDP are the "trucks" on the highway, and the "load" they are carrying are protocols such as HTTP, File Transfer Protocol (FTP) and more.
14 | 
15 | IP is required to connect all networks;
16 | 
17 | TCP is a mechanism that allows us to transfer data safely and
18 | 
19 | HTTP which utilizes TCP to transfer its data, is a specific protocol used by Web servers and clients.
20 | 
21 | ### **Postal service**
22 | 
23 | One might regard TCP or UDP as the equivalent of the US Postal Service, while HTTP is the equivalent of one business letter template.
24 | 
25 | If you are writing to an unknown person, as business letter format is a good, generic way to transmit the "WHO, HOW, WHAT, WHEN, AND WHERE" of your message, but it is NOT the only format that is allowed by the USPS.
26 | 
27 | That is, if you are writing to a business associate or loved one, you might forgo the formalities and instead go with a more efficient format, like a billing invoice or love letter or greeting card, but the USPS, like TCP or UDP, will still be there for you, carrying the letters back and forth.
28 | 
29 | # Models
30 | 
31 | The OSI Model is a logical and conceptual model that defines network communication used by systems open to interconnection and communication with other systems. On the other hand, TCP/IP helps you to determine how a specific computer should be connected to the internet and how you can be transmitted between them.
32 | 
33 | OSI model helps you to standardize router, switch, motherboard, and other hardware, whereas TCP/IP helps you to establish a connection between different types of computers.
34 | 
35 | Each layer handles a very specific task and interacts only with layers directly above or below. When a layer breaks, it takes all the above with it. Always try to specify the problematic layer for better support.
36 | 
37 | # OSI
38 | 
39 | Textbook 7 layer model - Open Systems Interconnect (OSI)
40 | 
41 | 1. Physical
42 | 2. Data Link
43 | 3. Network
44 | 4. Transport
45 | 5. Session
46 | 6. Presentation
47 | 7. Application
48 | 
49 | # TCP/IP
50 | 
51 | Real-world 5 layer model
52 | 
53 | 1. Physical
54 | 2. Datalink
55 | 3. Network
56 | 4. Transport
57 | 5. Application
58 | 
59 | # Diagrams
60 | 
61 | ![TEA](../pics/networking/OSI-7-layers.jpg)
62 | ![TEA](../pics/networking/OSI-vs.-TCPIP-models.jpg)
63 | ![TEA](../pics/networking/OSI.png)
64 | ![TEA](../pics/networking/data_flow.jpg)
65 | 


--------------------------------------------------------------------------------
/topics/networkingRoles.md:
--------------------------------------------------------------------------------
 1 | Every sysadmin, database admin, web admin, developer, and IT professional should understand the basics of networking.
 2 | 
 3 | It's **much** easier to teach a system administrator the basics of networking, than to teach a network administrator the basics of system administration.
 4 | 
 5 | # System Administrators
 6 | 
 7 | Responsible for managing servers i.e. computers, running an OS, whose main task is providing services to other servers or users, rather than the network.
 8 | 
 9 | They should:
10 | 
11 | -   Learn the basics of networking
12 | 
13 | # Network Administrators
14 | 
15 | Responsible for managing network equipment, such as routers.
16 | 
17 | They should:
18 | 
19 | -   Learn basics of how servers operate.
20 | -   Understand the basics of:
21 |     -   user access control and privileges
22 |     -   processes
23 |     -   services and daemons
24 |     -   install/remove software
25 | 


--------------------------------------------------------------------------------
/topics/nodemailer.md:
--------------------------------------------------------------------------------
 1 | ```js
 2 | const nodemailer = require("nodemailer");
 3 | 
 4 | async function sendMail() {
 5 |     try {
 6 |         let mailOptions = {
 7 |             from: '"Vendor Name" <info@vendor.com>',
 8 |             to: ["info@clientOne.com", "contact@clientTwo.com"],
 9 |             subject: `Message from vendor`,
10 |             // text: // plain text body
11 |             html: `
12 |                 <h1>Some Title</h1>
13 |                 <br><br>
14 |                 <p>Some text</p>
15 |             `,
16 |         };
17 | 
18 |         // create reusable transporter object using the default SMTP transport
19 |         let transporter = nodemailer.createTransport({
20 |             name: "subdomain.vendor.com", // needed to send to gmail, yahoo
21 |             host: "mail.vendor.com", // email provider SMTP server
22 |             port: 465,
23 |             secure: true, // true for 465, false for other ports
24 |             auth: {
25 |                 user: "info@vendor.com", // has to be the same as mailOptions.from
26 |                 pass: "emailPassword",
27 |             },
28 |         });
29 | 
30 |         // send mail with defined transport object
31 |         // transporter.sendMail does not return a promise, it uses a callback function.
32 |         transporter.sendMail(mailOptions, async (error, info) => {
33 |             if (error) {
34 |                 res.send({
35 |                     success: false,
36 |                     message: "Sending failed.",
37 |                 });
38 |             } else {
39 |                 res.send({
40 |                     success: true,
41 |                     message: "Sent mail.",
42 |                 });
43 |             }
44 |         });
45 |     } catch (err) {
46 |         console.log("Error: " + err);
47 |     }
48 | }
49 | ```
50 | 
51 | # Promise response
52 | 
53 | ```js
54 | return new Promise((resolve, reject) => {
55 |     transporter.sendMail(mailOptions, (error, info) => {
56 |         if (error) {
57 |             reject({
58 |                 success: false,
59 |                 type: "error",
60 |                 message: "Sending failed.",
61 |             });
62 |         } else {
63 |             resolve({
64 |                 success: true,
65 |                 type: "success",
66 |                 message: "Sent mail.",
67 |             });
68 |         }
69 |     });
70 | });
71 | ```
72 | 


--------------------------------------------------------------------------------
/topics/notifications.md:
--------------------------------------------------------------------------------
 1 | Push API is the W3C standard for web push notification protocol.
 2 | 
 3 | Push API is a web-push, unlike a native-push.
 4 | 
 5 | `Push` and `notification` use different, but complementary, APIs:
 6 | 
 7 | -   `push` is invoked when a server supplies information to a service worker.
 8 | -   `notification` is the action of a service worker or web page script showing information to a user.
 9 | 
10 | Service workers (core for PWAs) are needed for the browsers to handle push notifications.
11 | 
12 | 1. Backend endpoint is needed
13 | 2. Clients sends subscription object to server endpoint
14 | 3. Client shows notification
15 | 
16 | Running the front end Javascript to subscribe to your notifications, and getting the device token returned.
17 | Granting a client access to your notifications is very simple using Javascript. If a valid push package is returned, access will be granted and a device token is given in a JSON response. A device token is a unique identifier for each Mac that subscribes to the notification service. When sending a notification, the device token determines which Mac the notification will be sent to.
18 | 


--------------------------------------------------------------------------------
/topics/optimization/algorithms.md:
--------------------------------------------------------------------------------
 1 | # Useful Algorithms
 2 | 
 3 | ## Dummy data
 4 | 
 5 | ```javascript
 6 | let data = [
 7 |     { id: 1, name: "a" },
 8 |     { id: 2, name: "b" },
 9 |     { id: 3, name: "c" },
10 |     { id: 4, name: "d" },
11 |     { id: 5, name: "e" },
12 | ];
13 | ```
14 | 
15 | ## Shuffle array
16 | 
17 | ```javascript
18 | function shuffleArray(array) {
19 |     for (var i = array.length - 1; i > 0; i--) {
20 |         var j = Math.floor(Math.random() * (i + 1));
21 |         var temp = array[i];
22 |         array[i] = array[j];
23 |         array[j] = temp;
24 |     }
25 |     return array;
26 | }
27 | 
28 | let shuffled = shuffleArray(data);
29 | console.log(shuffled);
30 | ```
31 | 
32 | ## Sort array
33 | 
34 | ```javascript
35 | // true desc, false asc
36 | let dynamicSort = function (field, reverse, primer) {
37 |     let key = primer
38 |         ? function (x) {
39 |               return primer(x[field]);
40 |           }
41 |         : function (x) {
42 |               return x[field];
43 |           };
44 | 
45 |     reverse = !reverse ? 1 : -1;
46 | 
47 |     return function (a, b) {
48 |         return (a = key(a)), (b = key(b)), reverse * ((a > b) - (b > a));
49 |     };
50 | };
51 | 
52 | let sorted = data.sort(dynamicSort("id", false));
53 | console.log(sorted);
54 | ```
55 | 


--------------------------------------------------------------------------------
/topics/optimization/codeGolf.md:
--------------------------------------------------------------------------------
 1 | # Swap numbers
 2 | 
 3 | ```js
 4 | [a, b] = [b, a];
 5 | ```
 6 | 
 7 | # Unique array values
 8 | 
 9 | ```js
10 | let unique = [...new Set(array)];
11 | ```
12 | 
13 | # Sum
14 | 
15 | ```js
16 | array.reduce((accumulator, item) => accumulator + item.value, 0);
17 | ```
18 | 
19 | # Max value of object property in array
20 | 
21 | ```js
22 | Math.max(...array.map((object) => object[property]));
23 | ```
24 | 
25 | # Longest string in an array
26 | 
27 | ```js
28 | array.reduce((a, b) => (a.length > b.length ? a : b), "");
29 | ```
30 | 


--------------------------------------------------------------------------------
/topics/optimization/comments.md:
--------------------------------------------------------------------------------
 1 | # Don't write comments
 2 | 
 3 | ```
 4 | code > comments
 5 | ```
 6 | 
 7 | Comments get bugs like code. When code is updated, usually the comment is not.
 8 | 
 9 | Use comments only when there is some non-obvious code optimization, explaining why the code is weird, or if it references some specific math or algorithm.
10 | 
11 | # Write documentation
12 | 
13 | Comments = How code works  
14 | Documentation = How code is used
15 | 
16 | # Use constants
17 | 
18 | ```js
19 | // A status of 5 signals message sent
20 | if (status == 5) {
21 |     message.markSent();
22 | }
23 | ```
24 | 
25 | ```js
26 | CONST MESSAGE_SENT = 5
27 | if (status == MESSAGE_SENT) {
28 |     message.markSent();
29 | }
30 | ```
31 | 
32 | # Refactor with constants
33 | 
34 | ```js
35 | /*
36 | You can update a message IF the current user is the author of the message and the message was delivered less 5 minutes ago OR if the current user is an administrator. You can also edit the message if the message wasn't delivered yer.
37 | */
38 | 
39 | if ((message.user.id == currentUser.id && (!message.deliveredTime() || datetime.now() - message.deliveredTime() < 300)) || currentUser.type == "administrator") {
40 |     message.updateText(text);
41 | }
42 | ```
43 | 
44 | ```js
45 | const FIVE_MINUTES = 5 * 60;
46 | 
47 | let userIsAuthor = message.user.id == currentUser.id;
48 | let isRecent = !message.deliveredTime() || datetime.now() - message.deliveredTime() < FIVE_MINUTES;
49 | let userIsAdmin = currentUser.type == "administrator";
50 | 
51 | if ((userIsAuthor && isRecent) || userIsAdmin) {
52 |     message.updateText(text);
53 | }
54 | ```
55 | 
56 | ```js
57 | function canEditMessage(currentUser, message) {
58 |     const FIVE_MINUTES = 5 * 60;
59 | 
60 |     let userIsAuthor = message.user.id == currentUser.id;
61 |     let isRecent = !message.deliveredTime() || datetime.now() - message.deliveredTime() < FIVE_MINUTES;
62 |     let userIsAdmin = currentUser.type == "administrator";
63 | 
64 |     return (userIsAuthor && isRecent) || userIsAdmin;
65 | }
66 | 
67 | if (canEditMessage(currentUser, message)) {
68 |     message.updateText(text);
69 | }
70 | ```
71 | 


--------------------------------------------------------------------------------
/topics/optimization/dependencyInjection.md:
--------------------------------------------------------------------------------
 1 | https://www.youtube.com/watch?v=J1f5b4vcxCQ
 2 | 
 3 | > A piece of code using another piece of code that is passed in, instead of used directly.
 4 | 
 5 | The act of passing things to be used is called `injection` i.e. We inject the dependent code into the code that uses it.
 6 | 
 7 | **Before**
 8 | 
 9 | ```js
10 | export class Storage(){
11 |     private database: Database
12 | 
13 |     constructor(){
14 |         this.database = New Database("db.sqlite");
15 | 
16 |         this.database.run(`
17 |             CREATE TABLE IF NOT EXISTS user (
18 |                 id INTEGER PRIMARY KEY,
19 |                 username TEXT,
20 |                 group_id INTEGER,
21 |                 creation_time TIMESTAMP
22 |             )
23 |         `);
24 |     }
25 | }
26 | ```
27 | 
28 | **After**
29 | 
30 | ```js
31 | export class Storage(){
32 |     private database: Database
33 | 
34 |     constructor(database: Database){
35 |         this.database = database;
36 | 
37 |         this.database.run(`
38 |             CREATE TABLE IF NOT EXISTS user (
39 |                 id INTEGER PRIMARY KEY,
40 |                 username TEXT,
41 |                 group_id INTEGER,
42 |                 creation_time TIMESTAMP
43 |             )
44 |         `);
45 |     }
46 | }
47 | ```
48 | 


--------------------------------------------------------------------------------
/topics/optimization/naming.md:
--------------------------------------------------------------------------------
 1 | # 1. Don't abbreviate names
 2 | 
 3 | ```js
 4 | function relScore(m1, m2) {}
 5 | 
 6 | function movieRelationScore(movie1, movie2) {}
 7 | ```
 8 | 
 9 | # 2. Use Endiannes / Smurfing / Molds
10 | 
11 | ```bash
12 | # big-endian = Most significant word FIRST
13 | profitMonthlyMax
14 | 
15 | # little-endian = Most significant word LAST
16 | maxMonthlyProfit
17 | ```
18 | 
19 | # 3. Don't use single letters
20 | 
21 | ```js
22 | let x = 1;
23 | 
24 | let someValue = 1;
25 | ```
26 | 
27 | # 4. Don't put types in the name (Hungarian notation)
28 | 
29 | ```c
30 | bool bIsValid;
31 | int32_t iSpeed;
32 | uint32_t uNumUsers;
33 | char szUserName;
34 | ```
35 | 
36 | # 5. Add units to variables.
37 | 
38 | ```js
39 | function execute(delay) {}
40 | 
41 | function execute(delaySeconds) {}
42 | ```
43 | 
44 | # 6. Refactor if you find yourself using `utils`.
45 | 
46 | ```js
47 | // utils.js
48 | function assignDefaults() {}
49 | function relationScore() {}
50 | function moviesOnPage() {}
51 | function topMoviesByRating() {}
52 | function moviesByDirector() {}
53 | function parseCookie() {}
54 | function assignCookie() {}
55 | ```
56 | 
57 | ```js
58 | // movies.js
59 | function assignDefaults() {}
60 | function relationScore() {}
61 | 
62 | // pager.js
63 | function moviesOnPage() {}
64 | 
65 | // movieCollection.js
66 | function topMoviesByRating() {}
67 | function moviesByDirector() {}
68 | 
69 | // cookie.js
70 | function parseCookie() {}
71 | function assignCookie() {}
72 | ```
73 | 


--------------------------------------------------------------------------------
/topics/optimization/nesting.md:
--------------------------------------------------------------------------------
 1 | # Never nest beyond 3 levels
 2 | 
 3 | ```js
 4 | function calculate(bottom, top) {
 5 |     //  One
 6 |     if (top > bottom) {
 7 |         //  Two
 8 |         let sum = 0;
 9 | 
10 |         for (let number = bottom; number <= top; number++) {
11 |             //  Three
12 |             if (number % 2 == 0) {
13 |                 //  Four
14 |                 sum += number;
15 |             }
16 |         }
17 | 
18 |         return sum;
19 |     } else {
20 |         return 0;
21 |     }
22 | }
23 | ```
24 | 
25 | # **Methods of denesting**
26 | 
27 | -   **Extraction** - Move code into a separate function
28 | -   **Inversion** - Early termination of conditions
29 | 
30 | ```js
31 | // Extraction i.e. Separate function
32 | function filterNumber(number) {
33 |     // One
34 |     if (number % 2 == 0) {
35 |         // Two
36 |         return number;
37 |     }
38 |     return 0;
39 | }
40 | 
41 | function calculate(bottom, top) {
42 |     // One
43 | 
44 |     // Inversion i.e. Early termination
45 |     if (top < bottom) return 0;
46 | 
47 |     let sum = 0;
48 | 
49 |     for (let number = bottom; number <= top; number++) {
50 |         // Two
51 |         sum += filterNumber(number);
52 |     }
53 | 
54 |     return sum;
55 | }
56 | ```
57 | 


--------------------------------------------------------------------------------
/topics/optimization/premature.md:
--------------------------------------------------------------------------------
 1 | # Premature Optimization
 2 | 
 3 | > _"Premature optimization is the root of all evil"_ - Donald Knuth
 4 | 
 5 | You're writing code to solve a real world problem. Getting to a solution faster is more important than a fast solution.
 6 | 
 7 | -   Macro performance (Design level) - system wide decisions ex. sql vs nosql
 8 | -   Micro performance (Fine tuning) - modules, functions...
 9 | 
10 | 1. Have a **real** performance problem.
11 | 2. Make 80% moves (what change leads to an 80% reduction? usually data structures).
12 | 3. Use a profiler to fix hot spots.
13 | 4. Get under the hood (meomry).
14 | 
15 | # Quotes
16 | 
17 | > A sentence I stole online and sometimes tell my classmates is "If your code doesn't work, we don't care how fast it doesn't work". I think it's a great piece of advice.
18 | 
19 | > My data structures and algorithms lecturer said something similar, an anecdote about him replacing a broken algorithm. The exchange was along the lines of 'But your algorithm takes 3 times as long as my algorithm!' 'Yes, but my algorithm gets the right answer'
20 | 
21 | > Correctness comes before efficiency. Sometimes people also say “I can make it run a bit faster if it doesn’t have to handle all these edge cases”. Or, in other words, if it doesn’t have to be correct.
22 | 
23 | > That's a clever adaptation of the shorter one they use often when training devs: "It's easier to make working code go faster than it is to make fast code work"
24 | 
25 | > One lesson that always stuck with me since college was that software engineering doesn’t just have one time-cost. It has three: runtime cost, development time cost, and repair/maintenance cost. Which happen to be a perfect allegory to the performance, velocity, adaptability triangle
26 | 


--------------------------------------------------------------------------------
/topics/puppeteer.md:
--------------------------------------------------------------------------------
 1 | # Install
 2 | 
 3 | ```bash
 4 | npm i puppeteer --save
 5 | 
 6 | # This is needed for the dependencies
 7 | sudo apt install chromium-browser
 8 | ```
 9 | 
10 | # Scraping
11 | 
12 | 
13 | # PDF
14 | 
15 | ```javascript
16 | const express = require("express");
17 | const puppeteer = require('puppeteer')
18 | 
19 | var app = express();
20 | 
21 | // Allow requests from all domains and localhost
22 | app.all("/*", function (req, res, next) {
23 |     res.header("Access-Control-Allow-Origin", "*");
24 |     res.header(
25 |         "Access-Control-Allow-Headers",
26 |         "X-Requested-With, Content-Type, Accept"
27 |     );
28 |     res.header("Access-Control-Allow-Methods", "POST, GET");
29 |     next();
30 | });
31 | 
32 | app.get('/pdf/:id', function (req, res) {
33 | 
34 |     let id = req.params.id;
35 | 
36 |     async function printPDF() {
37 |         const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] });
38 |         const page = await browser.newPage();
39 |         await page.goto(`http://localhost:4000/${id}`, { waitUntil: 'networkidle0' });
40 |         const pdf = await page.pdf({ format: 'A4' });
41 | 
42 |         await browser.close();
43 |         return pdf
44 |     }
45 | 
46 |     printPDF().then(pdf => {
47 |         res.set({ 'Content-Type': 'application/pdf', 'Content-Length': pdf.length })
48 |         res.send(pdf)
49 |     })
50 | 
51 | });
52 | 
53 | app.get('/offer', function (req, res) {
54 | 
55 |     html = `<h1>Hello World!</h1>`
56 |     res.send(html)
57 | 
58 | });
59 | 
60 | var server = app.listen(4000, function () {
61 |     var host = server.address().address;
62 |     var port = server.address().port;
63 |     console.log("app listening at http://%s:%s", host, port);
64 | });
65 | ```
66 | 
67 | 


--------------------------------------------------------------------------------
/topics/reddit.md:
--------------------------------------------------------------------------------
  1 | # 1. Create app
  2 | 
  3 | https://old.reddit.com/prefs/apps
  4 | 
  5 | # 2. Install dependencies
  6 | 
  7 | ```
  8 | npm i snoowrap express --save
  9 | ```
 10 | 
 11 | # 3. Scraper
 12 | 
 13 | ```js
 14 | var snoowrap = require("snoowrap");
 15 | const express = require("express");
 16 | const app = express();
 17 | const port = 6000;
 18 | 
 19 | // (async () => {
 20 | app.get("/", async (req, res) => {
 21 |     // https://old.reddit.com/prefs/apps/
 22 |     const r = new snoowrap({
 23 |         userAgent: "A random string.",
 24 |         clientId: "APP_ID",
 25 |         clientSecret: "APP_SECRET",
 26 |         username: "REDDIT_USER",
 27 |         password: "REDDIT_PASSWORD",
 28 |     });
 29 | 
 30 |     const subreddit = await r.getSubreddit("cscareerquestions");
 31 |     const topPosts = await subreddit.search({ query: "Salary Sharing thread for EXPERIENCED DEVS", time: "all", sort: "new" });
 32 | 
 33 |     console.log("topPosts");
 34 | 
 35 |     let posts = topPosts.filter((post) => post.title.includes("EXPERIENCED DEVS"));
 36 | 
 37 |     console.log("posts");
 38 | 
 39 |     let data = [];
 40 | 
 41 |     /*
 42 |     submisson
 43 |         comments
 44 |             comment
 45 |                 replies
 46 |                     replies
 47 |             comment
 48 |                 replies
 49 |                     replies
 50 |     */
 51 | 
 52 |     for (let i = 0; i < posts.length; i++) {
 53 |         let post = posts[i];
 54 |         let id = post.id;
 55 | 
 56 |         let submission = await r.getSubmission(id).expandReplies({ limit: 1, depth: 1 });
 57 | 
 58 |         console.log("submission");
 59 | 
 60 |         let comments = submission.comments;
 61 | 
 62 |         comments.forEach((comment) => {
 63 |             let region = comment.body.split("**")[1];
 64 | 
 65 |             if (!region) return;
 66 | 
 67 |             comment.replies.forEach((reply) => {
 68 |                 let foo = { region, permalink: `https://old.reddit.com/${reply.permalink}` };
 69 | 
 70 |                 let lines = reply.body.split("\n");
 71 | 
 72 |                 lines.forEach((line) => {
 73 |                     let parts = line.split(": ");
 74 |                     let key = "";
 75 |                     let value = parts[1];
 76 | 
 77 |                     if (parts[0].includes("Experience")) key = "experience";
 78 |                     if (parts[0].includes("Tenure")) key = "tenure";
 79 |                     if (parts[0].includes("Industry")) key = "industry";
 80 |                     if (parts[0].includes("Title")) key = "title";
 81 |                     if (parts[0].includes("Location")) key = "location";
 82 |                     if (parts[0].includes("Salary")) key = "salary";
 83 |                     if (parts[0].includes("Total")) key = "total";
 84 | 
 85 |                     if (key && value) foo[key] = value;
 86 |                 });
 87 | 
 88 |                 data.push(foo);
 89 |             });
 90 |         });
 91 |     }
 92 | 
 93 |     console.log(data);
 94 | 
 95 |     console.log("done");
 96 | 
 97 |     res.send(data);
 98 | });
 99 | 
100 | app.listen(port, () => {
101 |     console.log(`Example app listening at http://localhost:${port}`);
102 | });
103 | // })();
104 | ```
105 | 


--------------------------------------------------------------------------------
/topics/serverless.md:
--------------------------------------------------------------------------------
 1 | Where microservices break up monolithic apps... Serveless breaks up microservices into independent functions.
 2 | 
 3 | # AWS Lambda/Serverless
 4 | 
 5 | ```bash
 6 | # Install
 7 | npm install -g serverless
 8 | 
 9 | # Initialize (Setup AWS credentials)
10 | serverless
11 | 
12 | # Deploy code
13 | serverless deploy
14 | 
15 | # Call API
16 | curl https://pv2vfelg5j.execute-api.us-east-1.amazonaws.com/dev/api
17 | ```
18 | 
19 | # Code
20 | 
21 | ```bash
22 | npm install express aws-serverless-express
23 | ```
24 | 
25 | **api.js**
26 | 
27 | ```js
28 | const express = require("express");
29 | 
30 | router.get("/", (req, res) => {
31 |     res.status(200).json({ foo: "bar" });
32 | });
33 | 
34 | module.exports = router;
35 | ```
36 | 
37 | **app.js**
38 | 
39 | ```js
40 | const express = require("express");
41 | const cors = require("cors");
42 | 
43 | let api = require("./api");
44 | 
45 | const app = express();
46 | 
47 | app
48 |     .use(cors());
49 |     .use(express.json())
50 |     .use(api);
51 | 
52 | module.exports = app;
53 | ```
54 | 
55 | **handler.js**
56 | 
57 | ```js
58 | const awsServerlessExpress = require("aws-serverless-express");
59 | const app = require("./app");
60 | 
61 | const server = awsServerlessExpress.createServer(app);
62 | 
63 | exports.handler = (event, context) => {
64 |     return awsServerlessExpress.proxy(server, event, context);
65 | };
66 | ```
67 | 
68 | **serverless.yml**
69 | 
70 | ```yml
71 | service: api
72 | 
73 | provider:
74 |     name: aws
75 |     runtime: nodejs12.x
76 | 
77 | functions:
78 |     app-api:
79 |         handler: handler.handler
80 |         events:
81 |             - http:
82 |                   path: /
83 |                   method: get
84 |                   cors: true
85 | ```
86 | 


--------------------------------------------------------------------------------
/topics/sheetjs.md:
--------------------------------------------------------------------------------
 1 | ```html
 2 | <!DOCTYPE html>
 3 | <html>
 4 |     <head>
 5 |         <title>SheetJS Demo</title>
 6 |         <meta charset="UTF-8" />
 7 |         <script src="https://oss.sheetjs.com/sheetjs/xlsx.full.min.js"></script>
 8 |     </head>
 9 | 
10 |     <body>
11 |         <div id="app"></div>
12 |         <script type="module" src="/app.min.js"></script>
13 |     </body>
14 | </html>
15 | ```
16 | 
17 | ```js
18 | let excelButton = document.getElementById("button-excel");
19 | excelButton.addEventListener("click", () => {
20 |     let now = new Date();
21 |     let timestamp = `${now.toISOString().split("T")[0]} ${now.toLocaleTimeString("en-GB")}`; // 2020-04-18 14_03_05
22 |     activitiesTable.download("xlsx", `Exel report - ${timestamp}.xlsx`);
23 | });
24 | ```
25 | 


--------------------------------------------------------------------------------
/topics/startup/marketingFacebookPixel.md:
--------------------------------------------------------------------------------
1 | Pixels don't work without adding permissions to them.
2 | 


--------------------------------------------------------------------------------
/topics/startup/marketingGoogleTagManager.md:
--------------------------------------------------------------------------------
 1 | [Source](https://youtu.be/DiAgCihHW58)
 2 | 
 3 | Without coding:
 4 | 
 5 | 1. Embed/inject javascript code.
 6 | 2. Track events across many websites.
 7 | 
 8 | Super useful, even if you are a developer.
 9 | 
10 | # Account
11 | 
12 | ![](../../pics/startup/marketing/tag-manager_account.jpg)
13 | 
14 | Container = Property in Google Analytics
15 | 
16 | Create a separate container for each website.
17 | 
18 | # Components
19 | 
20 | ![](../../pics/startup/marketing/tag-manager_tags.jpg)
21 | 
22 | -   **Event** - An actual generic event like button click.
23 | -   **Tag** - Micro code injections/embeds.
24 |     -   Any javascript code, without actually coding it.
25 |         -   Google Analytics.
26 |         -   Facebook Pixel.
27 |         -   Chatbot...
28 |     -   Can send event meta-data to 3rd parties. Paired with Google Analytics properties.
29 |         -   Google Analytics GA4 Event - Dedicated for Google Analytics.
30 |         -   ~~Google Tag - General purpose, works for other Google services.~~
31 | 
32 | ```
33 | tags > new > tag configuration > Google Analytics > Google Analytics GA4 Event > Insert Tag ID (found in Google Analytics data stream)
34 | 
35 | triggering > Initialization - All Pages
36 | ```
37 | 
38 | -   **Trigger** - Tags are code just sitting there, waiting for directions what to do i.e. listen for the desired events to activate the tag script, while matching the conditions. Ex. specific button (.class_name). Triggers are not enabled by default, they need to be created, and then linked to tags.
39 | 
40 | ```
41 | triggers > new > trigger configuration > trigger type
42 | ```
43 | 
44 | -   **Variables** - Static content (URL pattern) or dynamically set values (order total).
45 | -   **Templates** - Custom tags with specific fields for them.
46 | 
47 | Triggers and tags work together. Triggers listen for the specific signal, and the tag then performs the specific function.
48 | 
49 | # Settings
50 | 
51 | Enable all link clicks (not available by default). You can add other data (variables) to tags as well.
52 | 
53 | ```
54 | Variables > configure > clicks (tick checkboxes)
55 | ```
56 | 
57 | Put the measurement ID (data stream) into a variable.
58 | 
59 | # Workflow
60 | 
61 | 1. Configure tags, triggers, variables.
62 | 2. Click preview (tag assistant) to verify events fire.
63 | 3. Check Google Analytics DebugView to verify events fired.
64 | 4. Submit and name the container configuration version.
65 | 
66 | # Manual event sending
67 | 
68 | 1. Ask developer to push a custom event to the Google Analytics data layer.
69 | 
70 | ```js
71 | gtag("event", "sign_up");
72 | ```
73 | 
74 | 2. Check if the event is avaliable in the Tag Manager preview.
75 | 3. Create a custom trigger to use the custom event as a triggering condition.
76 | 4. Create a tag to send the event to Google Analytics, link it to the custom trigger.
77 | 5. Verify the event is sent via Google Analytics DebugView
78 | 


--------------------------------------------------------------------------------
/topics/startup/marketingLandingPage.md:
--------------------------------------------------------------------------------
 1 | [SOURCE](https://youtu.be/g3cmNDlwGEg)
 2 | 
 3 | # 1. Navigation
 4 | 
 5 | ![](../../pics/startup/marketing/langing-page-navigation.jpg)
 6 | 
 7 | Keep it simple, people are used to this layout. Make it sticky as you scroll. Logo, few links and CTA button.
 8 | 
 9 | # 2. Hero
10 | 
11 | 1. **Headline** - What do you do? The big result your clients get.
12 | 2. **Sub-headline** - How do you make their lives better?
13 |     - What the service is
14 |     - Who is it for
15 |     - How it's delivered
16 | 3. **Call to action (CTA)** - What do they need to do to get it? Be really clear what happens when it's clicked.
17 | 4. **Image** - Ideally show your client in their happy state. "This could be you if you use our service"
18 | 
19 | Clear and direct, don't be cute or clever.
20 | 
21 | ![](../../pics/startup/marketing/langing-page-hero-example.jpg)
22 | 
23 | # 3. Problem
24 | 
25 | What does your sevice fix?
26 | 
27 | ![](../../pics/startup/marketing/langing-page-problem.jpg)
28 | 
29 | It isn't about being negative, but showing that you unserstand them.
30 | 
31 | ![](../../pics/startup/marketing/langing-page-problem-example.jpg)
32 | 
33 | # 4. Solution
34 | 
35 | Focus on how you can help, not just who you are.
36 | 
37 | -   Briefly highlight your qualifications and experience.
38 | -   Share a personal story how you understand their problem.
39 | -   Really short explanations how your service solves their problem.
40 | -   Showing your face here really helps.
41 | 
42 | ![](../../pics/startup/marketing/langing-page-solution.jpg)
43 | 
44 | ![](../../pics/startup/marketing/langing-page-solution-example.jpg)
45 | 
46 | # 5. Benefits
47 | 
48 | Show exactly what your users get. Focus on results, not just features.
49 | 
50 | Each benefit should paint a picture how your client's life is going to improve.
51 | 
52 | Benefit structure:
53 | 
54 | -   Title
55 | -   Short description
56 | -   Image
57 | 
58 | ![](../../pics/startup/marketing/langing-page-benefits.jpg)
59 | 
60 | ![](../../pics/startup/marketing/langing-page-benefits-example.jpg)
61 | 
62 | # 5. Action plan
63 | 
64 | Don't skip this!
65 | 
66 | ![](../../pics/startup/marketing/langing-page-action-plan.jpg)
67 | 
68 | ![](../../pics/startup/marketing/langing-page-action-plan-example.jpg)
69 | 
70 | # 6. Testimonials
71 | 
72 | Prove your worth.
73 | 
74 | Testimonial structure:
75 | 
76 | -   Short headline
77 | -   Description.
78 |     -   Before I was struggling with X.
79 |     -   Now after using the service, I've achieved Y, and I feel Z.
80 | -   Picture of client
81 | -   5-star graphic
82 | 
83 | Show 3rd party review website scores.
84 | 
85 | ![](../../pics/startup/marketing/langing-page-testimonials.jpg)
86 | 
87 | # 7. FAQ
88 | 
89 | Handle objections, by turning them into questions, and answering them.
90 | 
91 | ![](../../pics/startup/marketing/langing-page-faq.jpg)
92 | 
93 | # 8. Call to action (CTA)
94 | 
95 | Repeat the same CTA from the hero.
96 | 
97 | ![](../../pics/startup/marketing/langing-page-cta.jpg)
98 | 


--------------------------------------------------------------------------------
/topics/startup/startupProblemSolving.md:
--------------------------------------------------------------------------------
 1 | # XY Problem
 2 | 
 3 | The XY problem is a communication problem encountered in help desk, technical support, software engineering, or customer service situations where the question is about an end user's attempted solution (X) rather than the root problem itself (Y or Why?).
 4 | 
 5 | The XY problem obscures the real issues and may even introduce secondary problems that lead to miscommunication, resource mismanagement, and sub-par solutions. The solution for the support personnel is to ask probing questions as to why the information is needed in order to identify the root problem Y and redirect the end user away from an unproductive path of inquiry.
 6 | 
 7 | # Elon Musk's 5 step process
 8 | 
 9 | [Elon Musk on problem-solving](https://youtu.be/CDZ9REOh2xA)
10 | 
11 | First priniples critical thinking
12 | 
13 | > Whatever the people at the front-lines are doing, try to do it yourself a couple of times.
14 | 
15 | ## 1. Ask the right question
16 | 
17 | Question the requirements. Make them simpler.
18 | 
19 | No matter how good the requirements are, they are still dumb to some degree.
20 | 
21 | You start here because you can get the perfect answer to the wrong question.
22 | 
23 | Try to make the question the least wrong possible.
24 | 
25 | ## 2. Try to delete the process
26 | 
27 | If you're not forced to put back 10% in, you are not deleting enough.
28 | 
29 | People think they've succeeded by not being forced to put things back, but in fact they are overly conservative and kept things in that should have been deleted.
30 | 
31 | People are afraid to do this because they remember the last time they had to put things back, but what happened was they over-corrected by leaving too much stuff in and over-complicating things.
32 | 
33 | Deliberately delete more than you should.
34 | 
35 | ## 3. Optimize/simplify it
36 | 
37 | Go back to step 1 and try to improve the process.
38 | 
39 | The most common engineering mistake is to optimize something that shouldn't exist.
40 | 
41 | ## 4. You can always speed things up
42 | 
43 | No matter how good the process it, it can always be done faster.
44 | 
45 | Even if you don't change the process, you can use better machines, people...
46 | 
47 | ## 5. Automate it
48 | 
49 | Find a way to automate the process.
50 | 


--------------------------------------------------------------------------------
/topics/statistics.md:
--------------------------------------------------------------------------------
 1 | # Probability
 2 | 
 3 | Probability of happening
 4 | ```
 5 | 1 / possible outcomes
 6 | 1 / 4 = 25%
 7 | ```
 8 | 
 9 | Happening in a row (3 times)
10 | ```
11 | Probability ^ instances
12 | 0.25 ^ 3 = 0.0156 ~ 1.5%
13 | ```
14 | 
15 | **NOT** happening
16 | ```
17 | 1 - probability
18 | 1 - 0.25 = 0.75
19 | ```
20 | 
21 | **NOT** happening in a row (15 times)
22 | ```
23 | Probability NOT ^ instances
24 | (1 - 0.25) ^ 15
25 | 0.75 ^ 15 = 0.133 ~ 13%
26 | ```
27 | 
28 | Happening after **NOT** happening (15 times)
29 | ```
30 | 1 - (1 - 0.25) ^ 15
31 | 1 - 0.75 ^ 15
32 | 1 - 0.133 = 0.867 ~ 87%
33 | ```
34 | 
35 | 


--------------------------------------------------------------------------------
/topics/tagify.md:
--------------------------------------------------------------------------------
  1 | ```html
  2 | <!DOCTYPE html>
  3 | <html>
  4 |     <head>
  5 |         <title>Tagify Demo</title>
  6 |         <meta charset="UTF-8" />
  7 | 
  8 |         <script src="https://cdnjs.cloudflare.com/ajax/libs/tagify/3.21.0/tagify.min.js" integrity="sha512-YKRkB65j3s2S05MOobXwnLQvUw0asCy+5Dt8aIVK6rPqI4RxJmGLLExUObcGjn0K8/kQDNXXwSeLFkqXwXYtfA==" crossorigin="anonymous"></script>
  9 |         <script src="https://cdnjs.cloudflare.com/ajax/libs/tagify/3.21.0/tagify.polyfills.min.js" integrity="sha512-SvqV96Tz5KzauECowu+oMXacoJXm29uMw9GBl3sNW8nQZXxnLUzFP27dGn9SOSFuugSmXL6PedEbWdijxPkDVg==" crossorigin="anonymous"></script>
 10 |         <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tagify/3.21.0/tagify.min.css" integrity="sha512-91wa7heHLbuVdMrSXbWceVZva6iWDFlkFHnM+9Sc+oXFpTgw1FCqdnuaGBJfDVuNSNl0DwDmeGeJSORB0HyLZQ==" crossorigin="anonymous" />
 11 |     </head>
 12 | 
 13 |     <body>
 14 |         <script src="src/index.js"></script>
 15 |     </body>
 16 | </html>
 17 | ```
 18 | 
 19 | ```js
 20 | let tagsInput = document.createElement("input");
 21 | tagsInput.className = "activity-entity-tags";
 22 | document.body.append(tagsInput);
 23 | 
 24 | let tags = [
 25 |     {
 26 |         id: 1,
 27 |         value: "foo 1",
 28 |         searchBy: "foo 1",
 29 |     },
 30 |     {
 31 |         id: 2,
 32 |         value: "bar 2",
 33 |         searchBy: "bar 2",
 34 |     },
 35 |     {
 36 |         id: 3,
 37 |         value: "baz 3",
 38 |         searchBy: "baz 3",
 39 |     },
 40 | ];
 41 | 
 42 | let tags = new Tagify(tagsInput, {
 43 |     templates: {
 44 |         tag: function (tagData) {
 45 |             try {
 46 |                 return `
 47 |                     <tag 
 48 |                         title='${tagData.value}' 
 49 |                         contenteditable='false' 
 50 |                         spellcheck="false" 
 51 |                         class='tagify__tag ${tagData.class ? tagData.class : ""}' 
 52 |                         ${this.getAttributes(tagData)}
 53 |                     >
 54 |                         <x title='remove tag' class='tagify__tag__removeBtn'></x>
 55 |                         <div>
 56 |                             <span class='tagify__tag-text'>${tagData.value}</span>
 57 |                         </div>
 58 |                     </tag>
 59 |                 `;
 60 |             } catch (err) {
 61 |                 console.log(err);
 62 |             }
 63 |         },
 64 | 
 65 |         dropdownItem: function (tagData) {
 66 |             try {
 67 |                 return `
 68 |                     <div 
 69 |                         class='tagify__dropdown__item ${tagData.class ? tagData.class : ""}' 
 70 |                         style="font-size: 8pt;"
 71 |                     >
 72 |                       <span class="tags-dropdown-value">${tagData.searchBy}</span>
 73 |                     </div>
 74 |                 `;
 75 |             } catch (err) {
 76 |                 console.log(err);
 77 |             }
 78 |         },
 79 |     },
 80 |     enforceWhitelist: true,
 81 |     whitelist: tags,
 82 |     backspace: false,
 83 |     editTags: false,
 84 |     delimiters: ";",
 85 |     dropdown: {
 86 |         // fuzzySearch: true,
 87 |         maxItems: 500,
 88 |         // searchKeys: ["searchBy"],
 89 |         enabled: 0, // suggest tags after a single character input, zero i show on focus
 90 |         classname: "extra-properties", // custom class for the suggestions dropdown
 91 |     }, // map tags' values to this property name, so this property will be the actual value and not the printed value on the screen
 92 | });
 93 | 
 94 | tags.addTags([tags[0]]);
 95 | 
 96 | tags.on("dropdown:show", (e) => {
 97 |     console.log("showing");
 98 | });
 99 | 
100 | tags.on("dropdown:select", (e) => {
101 |     console.log("selecting");
102 |     console.log(e.detail);
103 | });
104 | ```
105 | 


--------------------------------------------------------------------------------
/topics/testing/testing.md:
--------------------------------------------------------------------------------
 1 | # Overview
 2 | 
 3 | The idea is to automate the manual testing of code, with code.
 4 | 
 5 | This requires an initial time investment, which is quickly paid back in the time saved by making sure the application is stable.
 6 | 
 7 | # Test types
 8 | 
 9 | -   **Unit tests**  
10 |     Testing single functions with no dependencies (thousands).
11 | 
12 | -   **Integration test**  
13 |     Testing single functions with dependencies i.e. functions that call other functions (couple). Does the combination of single functions work?
14 | 
15 | -   **End-to-end (E2E) / UI test**  
16 |     Testing by simulating a literal manual UI interaction (few).
17 | 
18 | # Setup
19 | 
20 | The following is needed to test code.
21 | 
22 | 1. **Test runner** - Executes tests and summarizes results. Ex. `Jest`, `Mocha`.
23 | 2. **Assertion library** - Define testing logic and conditions. Ex. `Jest`, `Chai`.
24 | 3. **Headless browser** - E2E testing - Simulate browser interactions. Ex. `Puppeteer`, `Cypress`.
25 | 
26 | `Jest` is both a test runner and an assertion library.
27 | 


--------------------------------------------------------------------------------
/topics/uiux.md:
--------------------------------------------------------------------------------
1 | ![Fonts](../pics/uiux/uiux_fonts.jpg)
2 | 


--------------------------------------------------------------------------------
/topics/vagrant.md:
--------------------------------------------------------------------------------
 1 | # Vagrant
 2 | 
 3 | Vagrant is used to avoid the tedious provisioning of Virtual Machines. Instead of manually installing the OS for every machine, VMs can be spun up instantly by downloading an image (box) from the hub, and running it.  
 4 | 
 5 | Vagrant **is not** like Docker. Vagrant is used to start VMs fast, while Docker is used to containerize packages within the VMs. Vagrant avoids installing an OS, Docker avoids installing packages i.e. they just run them. This significantly speeds things up by allowing to quickly create and destroy whole environments.  
 6 | 
 7 | In other words, use Vagrant for just the OS and Docker install, and run everything else as a Docker container.  
 8 | 
 9 | **Host** = Main Machine. **Guest** = Virtual Machine.  
10 | 
11 | ## Install
12 | `wget "URL"` - Download Vagrant.   
13 | `sudo dpkg -i FILENAME` - Install Vagrant.  
14 | `sudo apt-get install virtualbox` - Download VirtualBox.
15 | 
16 | ## Virtual Machine
17 | `vagrant box add BOX_NAME` - Download a box.  
18 | `vagrant init BOX_NAME` - Create Vagrantfile i.e. VMs live here.   
19 | `vagrant up` - Start a box (VM).
20 | 


--------------------------------------------------------------------------------
/topics/vm.md:
--------------------------------------------------------------------------------
 1 | # Virtualbox
 2 | 
 3 | 1. Create VM.
 4 | 2. Mount and install Guest Additions.
 5 | 3. **Reboot.**
 6 | 4. Add clipboard settings.
 7 | 5. Add host shared folder. It is under `/media/user/sf_folder_name`.
 8 | 6. `sudo adduser username vboxsf` to access shared folder.
 9 | 7. **Reboot.**
10 | 


--------------------------------------------------------------------------------
/topics/vue.md:
--------------------------------------------------------------------------------
 1 | # Hello World
 2 | 
 3 | ```html
 4 | <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 5 | 
 6 | <div id="app">
 7 |     <p>{{ title }}</p>
 8 | </div>
 9 | ```
10 | ```javascript
11 | new Vue({
12 |     el: "#app",
13 |     data: {
14 |         title: "Hello World!"
15 |     }
16 | });
17 | ```
18 | `Vue` instances are at the core of every Vue app, as they control their own HTML template rendered to the screen.
19 | 
20 | # Component Anatomy
21 | 
22 | All the code is encapsulated in the component.
23 | 
24 | **Output - HTML**
25 | ```html
26 | <template>
27 |     <div class="user">
28 |         <h1>{{ user.name }}</h1>
29 |     </div>
30 | </template>
31 | ```
32 | 
33 | **Functionality - Javascript**
34 | 
35 | A default object is exported i.e. component with a name of "User". The `data()` method returns the state of the component.
36 | ```html
37 | <script>
38 |     export default {
39 |         name: "User",
40 |         data() {
41 |             return {
42 |                 user: { name: "Foo" }
43 |             }
44 |         }
45 |     }
46 | </script>
47 | ```
48 | 
49 | **Style - CSS**
50 | ```html
51 | <style scoped>
52 |     h1 {
53 |         font-size: 2 rem;
54 |     }
55 | </style>
56 | ```
57 | 
58 | The main page served is `index.html` located in the `public` folder.  
59 | 
60 | The entry point for a vue app is `main.js`, located in `src`. There we import the `Vue` app object (where we mount the instance to the `index.html`), and the `App` component.
61 | 
62 | # Install
63 | 
64 | ```bash
65 | sudo npm i -g vue
66 | 
67 | vue --version
68 | ```
69 | 
70 | The framework can also be referenced with a CDN.
71 | 
72 | # Vue-CLI
73 | 
74 | Qucik SPA scaffolding. It provides build setups for a modern frontend workflow, with hot-reload, lint-on-save, and production-ready builds.
75 | 
76 | ```bash
77 | vue create app-name
78 | 
79 | cd app-name
80 | nom run serve
81 | ```
82 | 
83 | Chrome extension for debugging: Vue.js Devtools  
84 | VS Code Syntax highlighting: Vetur
85 | 
86 | # vue-router
87 | 
88 | **Installing it overwrites the `App.vue` file**s
89 | 
90 | # vuex
91 | 
92 | State management library similar to Redux.


--------------------------------------------------------------------------------
/topics/wasm.md:
--------------------------------------------------------------------------------
 1 | Native apps, distributed in the browser.
 2 | 
 3 | Run "almost machine" code in the browser.
 4 | 
 5 | Lets browsers compete with app stores and installers. 
 6 | 
 7 | Write C++, Rust... Compile it to WebAssembly... Run the code as a "web app".
 8 | 
 9 | You can play video games directly in the browser.
10 | 
11 | Ex. Open Photoshop in the browser, and send a link of the current project to someone to continue working. No sharing of files and installations.


--------------------------------------------------------------------------------
/topics/webpack.md:
--------------------------------------------------------------------------------
 1 | Webpack is a bundler, which combines many javascript files into a single bundle file.
 2 | 
 3 | It also uglifies (shortens identifier names) and minifies (gets rid of whitespace) the code.
 4 | 
 5 | ```bash
 6 | sudo npm install webpack webpack-cli --save-dev
 7 | ```
 8 | 
 9 | ## Simple Default Example
10 | 
11 | **Webpack needs an `src` directory with the entry `index.js` file.**  
12 | 
13 | Without this, we get `ERROR in Entry module not found: Error: Can’t resolve ‘./src’ in 'folder'`. The entry point can be changed in a `webpack.config.js` file.
14 | 
15 | We need to add a webpack scripts in `package.json`, which gets all the dependencies from `./src/index.js`, and bundles all the code into a `./dist/main.js` file.
16 | 
17 | ```json
18 | {
19 |     "scripts": {
20 |         "build": "webpack"
21 |     },
22 |     "devDependencies": {
23 |         "webpack": "4.x.x"
24 |     }
25 | }
26 | ```
27 | We then simply run
28 | ```bash
29 | npm run build
30 | ```
31 | 
32 | These can also be used in `package.json`, where production minifies, and development doesn't.
33 | ```json
34 | "scripts": {
35 |     "dev": "webpack --mode development",
36 |     "build": "webpack --mode production"
37 | }
38 | ```
39 | 
40 | ## Configuration
41 | 
42 | Instead of a `package.json` script, we can use a detailed `webpack.config.js` configuration file, which can be generated with the command below and by answering questions.  
43 | 
44 | ```bash
45 | webpack init
46 | ```
47 | Example :
48 | 1. Will your application have multiple bundles? **No**
49 | 2. Which module will be the first to enter the application? [example: './src/index.js'] **./src/index.js**
50 | 3. Which folder will your generated bundles be in? [default: dist] **Enter**
51 | 4. Are you going to use this in production? **No**
52 | 5. Will you be using ES2015 (ES6)? **Yes**
53 | 6. Will you use one of the below CSS solutions? **No**
54 | 7. Name your `webpack.[name].js`? [default: 'config'] **Enter**
55 | 
56 | This will install:
57 | - webpack-cli
58 | - uglifyjs-webpack-plugin
59 | - babel-core
60 | - babel-loder
61 | - babel-preset-env
62 | - webpack
63 | 
64 | It will also generate the `webpack.config.js` file:
65 | ```javascript
66 | const webpack = require("webpack");
67 | const path = require("path");
68 | 
69 | const UglifyjsJSPlugin = require("uglifyjs-webpack-plugin");
70 | 
71 | module.exports = {
72 |     entry: './src/index.js',
73 |     output: {
74 |         filename: '[name].bundle.js',
75 |         path: path.resolve(__dirname, dist)
76 |     },
77 |     module: {
78 |         rules: [
79 |             {
80 |                 test: /\.js$/,
81 |                 exclude: /node_modules/,
82 |                 loader: 'babel-loader',
83 |                 options: {
84 |                     presets: ['env'] 
85 |                 }
86 |             }
87 |         ]
88 |     },
89 |     plugins: [new UglifyJSPlugin()]
90 | };
91 | ```
92 | We can add this in `package.json` watch for changes and rebuild:
93 | ```json
94 | {
95 |     "scripts": {
96 |         "build": "webpack -w"
97 |     }
98 | }
99 | ```


--------------------------------------------------------------------------------
/topics/workflow/deployment.md:
--------------------------------------------------------------------------------
  1 | # Server
  2 | 
  3 | -   Buy server.
  4 | -   Find out IP address.
  5 | -   [Setup SSH public and private key for remote connections.](../ssh.md)
  6 | -   [Create users and setup the environment.](./environment.md)
  7 | 
  8 | # Interoperability
  9 | 
 10 | If you server connects to a database on another server, instead of using a VPN, ask the admins to add your server's IP address to their firewall.
 11 | 
 12 | # Deploy code
 13 | 
 14 | Use `rsync` to upload new files, and replace existing ones.
 15 | 
 16 | Deploy the front-end static files, as well as the server ones.
 17 | 
 18 | ```
 19 | npm run build --prefix app/ \
 20 | && rsync -av -e 'ssh' ./server ./app/dist --exclude 'server/node_modules' user@123.456.789.255:~/project/ \
 21 | && ssh user@123.456.789.255 pm2 reload /home/user/project/server/server.js --name "project"
 22 | ```
 23 | 
 24 | # Domain
 25 | 
 26 | If someone else owns the domain...
 27 | 
 28 | -   Tell them to create an A record for the domain/subdomain, which points to your server.
 29 | 
 30 | If you own it...
 31 | 
 32 | -   Find the nameservers of your server's host.
 33 | -   Configure the domain's nameservers i.e. which DNS to use for further configuration. This is done in your registrar's admin panel, or you can tell the admin to manually set them up. They look like this:
 34 | 
 35 | ```
 36 | ns1.host.com
 37 | ns2.host.com
 38 | ns3.host.com
 39 | ```
 40 | 
 41 | # DNS
 42 | 
 43 | -   Add the domain.
 44 | -   Create A record for the domain/subdomain, which points to your server.
 45 | -   Create CNAME record for `www > domain.com` to handle `www.domain.com`.
 46 | 
 47 | # SSL
 48 | 
 49 | -   Add a letencrypt SSL certificate with certbot.
 50 | 
 51 | # Web server -nginx
 52 | 
 53 | -   Add the new configuration, which has SSL and a reverse proxy.
 54 | 
 55 | ```nginx
 56 | events {}
 57 | 
 58 | http {
 59 |     include mime.types;
 60 | 
 61 |     server {
 62 |         listen 80;
 63 |          # IMPORTANT: Add CNAME record for www > domain.com
 64 |         # www.domain.com won't work without this
 65 |         server_name domain.com www.domain.com;
 66 |         return 301 https://domain.com$request_uri;
 67 |     }
 68 | 
 69 |     server {
 70 |         listen 443 ssl;
 71 |         server_name domain.com;
 72 |         ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
 73 |         ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
 74 | 
 75 |         root /home/ivan/wms/dist;
 76 |         index index.html;
 77 | 
 78 |         location / {
 79 |             try_files $uri /index.html; # Fixes refreshing resulting in 404 error for single page apps
 80 |         }
 81 | 
 82 |         location /auth {
 83 |             proxy_pass 'http://127.0.0.1:9999';
 84 |         }
 85 | 
 86 |         location /api {
 87 |             proxy_pass 'http://127.0.0.1:9999';
 88 |         }
 89 | 
 90 |         location /socket.io/ {
 91 |             proxy_pass 'http://127.0.0.1:9999';
 92 |         }
 93 |     }
 94 | }
 95 | ```
 96 | 
 97 | # Start server script
 98 | 
 99 | Use daemons such as `pm2` to run the script continuously. You can also use `nodemon` for running it temporarily.
100 | 
101 | ```
102 | pm2 start server.js --name "project"
103 | ```
104 | 
105 | # Test
106 | 
107 | Visit the domain from multiple devices and be aware of caching, which might show something else than the real things.
108 | 
109 | # Email
110 | 
111 | Use a service like `migadu` or `mxroute` for low volume, and `mailgun` for high volume.
112 | 


--------------------------------------------------------------------------------
/topics/workflow/development.md:
--------------------------------------------------------------------------------
 1 | # tmux
 2 | 
 3 | Use to start development quickly:
 4 | 
 5 | -   Start front-end dev server.
 6 | -   Start MySQL server.
 7 | -   Start back-end API server.
 8 | 
 9 | ```
10 | tmux new-session \; \
11 |     send-keys 'cd /home/user/dev/project/app && npm run dev' C-m \; \
12 |     split-window -h -p 50 \; \
13 |     send-keys 'echo password | sudo -S service mysql start && cd /home/user/dev/project/server && nodemon server.js' C-m \; \
14 | ```
15 | 
16 | # localhost Proxy
17 | 
18 | During development, the front-end and back-end run on different ports. In order to avoid messy "manual/env" `localhost` URLs, use a proxy configuration in the front-end dev server.
19 | 
20 | ```js
21 | // Vite example
22 | server: {
23 |     proxy: {
24 |         "/api": "http://localhost:9010",
25 |         "/auth": "http://localhost:9010",
26 |         "/socket.io": {
27 |             target: "ws://localhost:9010",
28 |             ws: true,
29 |         },
30 |     },
31 |     esbuild: {
32 |         drop: ["console", "debugger"],
33 |     },
34 | }
35 | ```
36 | 
37 | # VPN
38 | 
39 | When working with databases that aren't yours, you can connect to them by establishing a VPN connection and using the local IP address of the machine hosting the database, example `192.168.10.4,1434` where `1434` is the port.
40 | 
41 | You can ping the IP address to see if the connection works.
42 | 
43 | # Build
44 | 
45 | The front-end is bundled in static files, meaning they no longer run on a port. This means we can simply upload them to the live server to be used like any regular file.
46 | 


--------------------------------------------------------------------------------
/topics/workflow/environment.md:
--------------------------------------------------------------------------------
  1 | # User
  2 | 
  3 | ```bash
  4 | # Login as root with password
  5 | ssh root@123.456.789.255
  6 | 
  7 | # Add user
  8 | adduser <user>
  9 | 
 10 | # Add sudo access
 11 | usermod -aG sudo <user>
 12 | 
 13 | # Switch to user
 14 | su - <user>
 15 | ```
 16 | 
 17 | # SSH
 18 | 
 19 | ```bash
 20 | # Transfer the public key id_rsa.pub to the remote server
 21 | ssh-copy-id -i user@123.456.789.255
 22 | 
 23 | # If they private/public keys don't exist
 24 | ssh-keygen
 25 | 
 26 | # Connect to server
 27 | ssh user@123.456.789.255
 28 | ```
 29 | 
 30 | # System
 31 | 
 32 | ```bash
 33 | # Update OS
 34 | sudo apt update && sudo apt upgrade;
 35 | 
 36 | # Check version
 37 | lsb_release -a
 38 | 
 39 | # Check timezone
 40 | timedatectl
 41 | 
 42 | # Change timezone
 43 | sudo timedatectl set-timezone CET;
 44 | ```
 45 | 
 46 | # Tools
 47 | 
 48 | ```bash
 49 | # curl, vim, tmux, git (Usually installed already)
 50 | sudo apt install curl vim tmux git -y;
 51 | ```
 52 | 
 53 | # Node.js
 54 | 
 55 | **DO NOT install `nodejs` directly. Use `nvm`!**
 56 | 
 57 | > **MUST RESTART TERMINAL AFTER INSTALL FOR `nvm` TO WORK!**
 58 | 
 59 | ```bash
 60 | # Download and install nvm
 61 | curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash;
 62 | # MUST RESTART TERMINAL AFTER INSTALL FOR nvm TO WORK!!
 63 | 
 64 | # Install latest nodejs
 65 | nvm install node;
 66 | 
 67 | # Forward all the commands received as node to nodejs
 68 | sudo ln -sf "$(which node)" /usr/bin/node;
 69 | ```
 70 | 
 71 | # Daemons
 72 | 
 73 | ```bash
 74 | # Global nodemon
 75 | npm i -g nodemon;
 76 | 
 77 | # Global process manager
 78 | npm i -g pm2;
 79 | 
 80 | # Forward all the commands received as pm2 to whatever the fuck
 81 | sudo ln -sf "$(which pm2)" /usr/bin/pm2;
 82 | ```
 83 | 
 84 | # Web Server - nginx
 85 | 
 86 | ```bash
 87 | sudo apt install nginx -y;
 88 | ```
 89 | 
 90 | # Database - MySQL
 91 | 
 92 | ```bash
 93 | sudo apt install mysql-server;
 94 | 
 95 | sudo service mysql start
 96 | # sudo /etc/init.d/mysql start;
 97 | ```
 98 | 
 99 | Add a password to the `root` user.
100 | 
101 | ```bash
102 | # Login
103 | sudo mysql;
104 | 
105 | # Change root password
106 | ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
107 | 
108 | # Reload the privileges after password change.
109 | FLUSH PRIVILEGES;
110 | 
111 | # Login with password
112 | sudo mysql -u root -p;
113 | ```
114 | 
115 | Change time zone.
116 | 
117 | ```
118 | sudo vim /etc/mysql/my.cnf
119 | ```
120 | 
121 | Add this:
122 | 
123 | ```
124 | [mysqld]
125 | default-time-zone = "+01:00"
126 | ```
127 | 
128 | Restart the MySQL server:
129 | 
130 | ```
131 | sudo systemctl restart mysql
132 | ```
133 | 


--------------------------------------------------------------------------------