<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mahmoud Ehab</title>
    <description>The latest articles on DEV Community by Mahmoud Ehab (@_moehab).</description>
    <link>https://dev.to/_moehab</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F780815%2Fca78a550-aeee-42f6-9395-e5ad065c001c.jpeg</url>
      <title>DEV Community: Mahmoud Ehab</title>
      <link>https://dev.to/_moehab</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_moehab"/>
    <language>en</language>
    <item>
      <title>A Comprehensive Guide to Integrate FawryPay API into your own RESTful API Server</title>
      <dc:creator>Mahmoud Ehab</dc:creator>
      <pubDate>Thu, 20 Nov 2025 23:40:24 +0000</pubDate>
      <link>https://dev.to/_moehab/a-comprehensive-guide-to-integrate-fawrypay-api-into-your-own-restful-api-server-478d</link>
      <guid>https://dev.to/_moehab/a-comprehensive-guide-to-integrate-fawrypay-api-into-your-own-restful-api-server-478d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This text was originally written on March 12, 2025. As part of my work at LiteSpace, I was responsible for managing the integration of the Fawry API into our application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These papers provide a brief, but sufficient, exposition of how &lt;a href="https://fawrypay.com" rel="noopener noreferrer"&gt;FawryPay&lt;/a&gt; works, how to integrate its payment methods in your back-end software application, how refund works, and how to keep up with transactions status. Moreover, a general architecture that ensures a seamless integration of FawryPay API, with a flexible design that can adapt any other API, is proposed at the end of these papers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Payment Process Workflow&lt;/strong&gt;
1.1 Choosing Payment Method
1.2 Collecting Client’s Payment Details
1.3 Submitting Payment Request
1.4 Showing Payment Status&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Refund API&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bank Installments&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;General Architecture Specification&lt;/strong&gt;
4.1 Entity Relationship Diagram
4.2 System Overview Diagram
4.3 Request Factory
4.4 Details Collector
4.5 Payment Strategy
&lt;strong&gt;Further Readings&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Payment Process Workflow
&lt;/h2&gt;

&lt;p&gt;In a nutshell, the payment process involves four steps: choosing payment method, collecting client’s payment details, submitting payment request to the API (e.g. FawryPay), and showing the payment status summary to the client. Each of these steps will be elaborated in this section.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 Choosing Payment Method
&lt;/h3&gt;

&lt;p&gt;This step affects the upcoming procedures of the next steps; for example if &lt;a href="https://developer.fawrystaging.com/docs/server-side-api/pay-at-fawry" rel="noopener noreferrer"&gt;payment using FawryPay reference number&lt;/a&gt; is selected, then there is no client payment details to be collected, the payment HTTP request to be submitted shall have &lt;code&gt;"paymentMethod":"PAYATFAWRY"&lt;/code&gt; in its payload, and the status summary to be shown will be the reference number that shall be used to send money.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 Collecting Client’s Payment Details
&lt;/h3&gt;

&lt;p&gt;According to the selected method in the previous step, the required payment info will vary. As mentioned before, it can be none, in case the selected method is “PAYATFAWRY”. And it could be the user’s payment card info (card number, expiry year, expiry month, and cvv), in case the selected method is “CARD”.&lt;/p&gt;

&lt;h4&gt;
  
  
  Collecting Payment Card Details
&lt;/h4&gt;

&lt;p&gt;In order to make further payments seamless and easy (for users), we have to collect and store users payment info. However, this is considered an illegal action, if we are not fully &lt;a href="https://www.pcisecuritystandards.org/" rel="noopener noreferrer"&gt;PCI&lt;/a&gt; compliant. So, a hassle-free approach to achieve this would be using &lt;a href="https://developer.fawrystaging.com/docs/card-tokenization/card-tokenization-overview" rel="noopener noreferrer"&gt;Fawry Card Token API&lt;/a&gt;. And this splits this step into two steps: generating a card token (optional), and using/selecting an existing card token (users can have more than one card token).&lt;/p&gt;

&lt;p&gt;If the selected method is CARD, and the user chose an existing card token, this will affect the next step by adding the following attribute in the request payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"cardToken"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ac0a1…"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; alternatively, “saveCardInfo” field can be used, in the request body, instead of storing tokens, as will be shown in the next section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1.3 Submitting Payment Request
&lt;/h3&gt;

&lt;p&gt;The body of Fawry payment request is quite verbose, all its required and optional fields are listed and nicely described in the docs. The body slightly differs from one method to the other; meanly, specifying the “paymentMethod” attribute imposes an associated (to the selected method) body structure. e.g. if the “paymentMethod” is “PAYATFAWRY” you don’t have to pass the payment card info into the request body. On the other hand, if it’s “CARD” then the payment card info are required in the body.&lt;/p&gt;

&lt;p&gt;In this section you will know the general structure of the request body. And some useful features that you can obtain from its optional fields.&lt;/p&gt;

&lt;h4&gt;
  
  
  The General Body Structure
&lt;/h4&gt;

&lt;p&gt;Here is a brief list of the body structure, it states only the required fields in all body variants. Most of the fields values type, one can figure out from the name. However, others need some elaboration, for those you will find below a table of their description taken directly from the docs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"merchantCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1tSa6uxz2nTwlaAmt38enA=="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"merchantRefNum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2312465464"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"customerMobile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"01234567891"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"customerEmail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;580.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"currencyCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EGP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"language"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"en-gb"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"chargeItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"itemId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"897fa8e81be26df25db592e81c31c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Item Descriptoin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;580.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2ca4c078ab0d…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"paymentMethod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PAYATFAWRY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example Description"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;merchantCode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The merchant code provided by FawryPay team during the account setup.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;merchantRefNum&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The unique reference number for the charge request in merchant system.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;amount&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Must be in the form 0.00 (with two decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;signature&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The SHA-256 digested for the following concatenated string: &lt;code&gt;"merchantCode + merchantRefNum + customerProfileId (if exists, otherwise "") + paymentMethod + amount (in two decimal format 10.00) + secureKey"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Similar to the required fields, the optional varies according to the used “paymentMethod”. For example, “saveCardInfo” which is a boolean value, can be used only when the “paymentMethod” is “CARD”. And it functions along with the “customerProfileId” optional field which will be elaborated in the following table (the general optional fields table).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;customerProfileId&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The unique customer profile ID in merchant system. This can be the user ID.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;customerName&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The customer name in merchant system.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;orderWebHookUrl&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WebHook Url used to notify your application back end when an event happens in this order like order paid, expired or refund&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; merchant system means your own system; the values in your own database.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pay attention that the aforementioned fields are general to all body structure variants, this doesn’t mean, in any way, that your request will certainly be valid (not a bad request, 400) when you dispatch it with only these fields. e.g. when you use the “CARD” method, the “returnUrl” field, which is not listed above, is required.&lt;/p&gt;

&lt;p&gt;The docs provide code examples for each method; you can navigate to your preferred method from &lt;a href="https://developer.fawrystaging.com/docs/server-side-api/server-side-api-overview" rel="noopener noreferrer"&gt;Server to Server APIs&lt;/a&gt; section, copy the sample code in your preferred language, modify and use it in your project.&lt;/p&gt;

&lt;h4&gt;
  
  
  3D Secure Authentication Card Payments
&lt;/h4&gt;

&lt;p&gt;Before moving to the final step, it’s worth mentioning the “enable3DS” field of the body structure variant associated to the “CARD” method.&lt;/p&gt;

&lt;p&gt;Normally, when using the “CARD” method and dispatching a request to FawryAPI, it responses with json object like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ChargeResponse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"referenceNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"963455678"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"merchantRefNum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9990d0642040"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"orderAmount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;20.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"paymentAmount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;20.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"fawryFees"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"paymentMethod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CARD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"orderStatus"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PAID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"paymentTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1607879720568&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"customerMobile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"01234567891"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"customerMail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"authNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12336534"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"customerProfileId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1212"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b0ef178e2..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"statusCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"statusDescription"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Operation done successfully"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, when the “enable3DS” field is set “true”, another body variant is imposed; you have to supply the body with one more required field: “returnUrl”.&lt;/p&gt;

&lt;p&gt;The 3 domains secure (3DS) authentication protocol uses three domains to fulfill the transaction: your server domain, the provider domain (Fawry), and the band domain. First of all, you dispatch the request (with “enable3DS” true) to FawryAPI. Then it responses with a “redirectUrl” that you shall use to redirect the client to. The redirect destination (the bank) then do the authentication process and redirect the client back to Fawry. And eventually, Fawry redirects the client to the “returnUrl” you specified in the first place. &lt;a href="https://developer.fawrystaging.com/docs/server-side-api/3d-secure" rel="noopener noreferrer"&gt;Read More&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.4 Showing Payment Status
&lt;/h3&gt;

&lt;p&gt;The final step is showing the payment status, whether it is NEW, PAID, EXPIRED, CANCELED, REFUNDED, or FAILED. And more importantly, informing the user of further procedure he/she shall take to complete the payment process. e.g. when the user make payment with the “PAYATFAWRY” method, a page should be rendered (or a mail should be sent to the client e-mail) with the “referenceNumber” (that shall be used by any FawryPay POS retail store to fulfill the process) and instructions telling the user that he/she should pay an amount of money in any FawryPay POS retail store.&lt;/p&gt;

&lt;p&gt;A response body of FawryAPI to a request with the “PAYATFAWRY” method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ChargeResponse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"referenceNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"963455678"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"merchantRefNum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9990d0642040"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"orderAmount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;20.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"paymentAmount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;20.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"fawryFees"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"paymentMethod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PayAtFawry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"orderStatus"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PAID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"paymentTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1607879720568&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"customerMobile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"01234567891"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"customerMail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"customerProfileId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1212"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b0ef178e2f06..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"statusCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"statusDescription"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Operation done successfully"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand, to present the payment result in case the method is “CARD”, we may either use FawryAPI charge response and assign it to the “returnUrl” field. See &lt;a href="https://developer.fawrystaging.com/docs/server-side-api/callback-v2" rel="noopener noreferrer"&gt;charge response endpoint example&lt;/a&gt;, or more convenient, we may use the Get Payment Status API.&lt;/p&gt;

&lt;p&gt;The Get Payment Status is just a Fawry endpoint to which we can dispatch an HTTP GET request with the following three query parameters: merchantCode, merchantRefNumber, and signature. Whereas, the signature is the SHA-256 digest value for merchantCode + merchnatRefNumber + secureKey.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://atfawry.fawrystaging.com/ECommerceWeb/Fawry/payments/status/v2?
merchantCode=is0N+YQzlE4=&amp;amp;merchantRefNumber=23124654641
&amp;amp;signature=a5701a2e1e865bf863f0c781829f709ea4d36bdaf7d70e9bafb9458b1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Fawry Server Notification
&lt;/h4&gt;

&lt;p&gt;Fawry supplies its users (merchants) with an out of the box feature to push notification for every change in any transaction status. And this is done by preconfiguring an endpoint, whilst the registration process, that FawryAPI will dispatch an HTTP post request to automatically on every status update. &lt;a href="https://developer.fawrystaging.com/docs/server-side-api/server-to-server-notification-v2" rel="noopener noreferrer"&gt;Read More&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Refund API
&lt;/h2&gt;

&lt;p&gt;Nothing more can be said rather than the description in the docs: “FawryPay allows you to refund amounts that have previously been paid by customers, returning a unique reference for this request. Refunding can be done on the full captured amount or a partial amount. Payments which have been authorised, but not captured, cannot be refunded.”&lt;/p&gt;

&lt;p&gt;Notice that we can refund just a partial amount of the money. Authorized money means pending funds, and it’s called captured once it’s moved from pending to complete.&lt;/p&gt;

&lt;p&gt;Refund can be applied by dispatching an HTTP post request to &lt;a href="https://developer.fawrystaging.com/docs/server-side-api/refund" rel="noopener noreferrer"&gt;Fawry refund endpoint&lt;/a&gt; with a body structure like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"merchantCode"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1tSa6uxz2nTwlaAmt38enA=="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"referenceNumber"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"23124654641"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"refundAmount"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"362.50"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Item not as described"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3f527d0209f..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Refund Voucher
&lt;/h3&gt;

&lt;p&gt;What if users have paid with the “PAYATFAWRY” method, how then refund works?&lt;/p&gt;

&lt;p&gt;In this case, Fawry merchants shall generate a refund voucher that clients can use to get their money back from any FawryPay POS retail store. However this functionality/feature has not been mentioned in the online docs at the time of writing these papers. You have to contact Fawry support to inquiry about the applicability of refund vouchers.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Bank Installments
&lt;/h2&gt;

&lt;p&gt;Likewise, just another variant of the body structure. When an “installmentPlanId” is specified in the aforementioned body structure of the “CARD” method. Then the request will be handled by FawryAPI as a payment with Bank Installment.&lt;/p&gt;

&lt;p&gt;However, you must provide Fawry with your installment plans, using your account dashboard. And then you can retrieve them in your application by dispatching a GET request to the endpoint:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://www.atfawry.com/ECommerceWeb/api/merchant/installment-plans&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.fawrystaging.com/docs/server-side-api/installments" rel="noopener noreferrer"&gt;Read More&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. General Architecture Specification
&lt;/h2&gt;

&lt;p&gt;This section proposes an abstract software design solution for the aforementioned system. Workflow, PaymentStrategy, DetailsCollector, and RequestFactory; these are the models that shall be defined in order to express the high-level implementation of the above-mentioned workflow.&lt;/p&gt;

&lt;p&gt;Before going through the discussion of each of the mentioned models, we should first delineate our database with and entity relationship diagram.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 Entity Relationship Diagram
&lt;/h3&gt;

&lt;p&gt;The database shall contain at least four entities: users, merchants, invoices, and items. The relations between these entities and their minimal fields (as shown in the diagram below) have been specified to be compliant with the aforementioned implementation in an abstract way; meanly, the DataControllers that will treat this data model as a FawryAPI model, may retrieve the merchant.id as FawryAPI “merchantRefNumber” and the merchant.name as “merchantCode”, invoice.id as “referenceNumber”,… etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rh1scvvy8ysa02e4fhs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rh1scvvy8ysa02e4fhs.png" alt=" " width="800" height="787"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 System Overview Diagram
&lt;/h3&gt;

&lt;p&gt;The Workflow is defined by its constituents: PaymentStrategy, DetailsCollector, and RequestFactory. So you can write a FawryWorkflow component that extends the abstract one in the sense that it has FawryPaymentMethod, FawryDetailsCollector, and FawryRequestFactory, that in turn extend the abstract defined ones. In more technical sense, the Workflow is a facade design pattern that gives the main script (the server) access to a compatible tools to be used to fulfill a payment process. And moreover, it connects these tools together.&lt;/p&gt;

&lt;p&gt;Just as the dependency flow in the real world model, it does in this simulation model; it goes from RequestFactory to DetailsCollector and ends in PaymentStrategy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqr12rsy8ycoet8diw84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqr12rsy8ycoet8diw84.png" alt=" " width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3 Payment Strategy
&lt;/h3&gt;

&lt;p&gt;This component is responsible of specifying the required data along with its payment method name. If you are working with .Net, for example, you may implement it with static classes and/or type definitions. If you are going to implement it using TypeScript, you will probably just export a bunch of &lt;a href="https://zod.dev/" rel="noopener noreferrer"&gt;Zod&lt;/a&gt; objects.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.4 Details Collector
&lt;/h3&gt;

&lt;p&gt;This component is responsible of collecting the required data as specified by the PaymentStrategy, in the same Workflow. It can be an html form, a React form component, a function that fetches data from a local storage, or an express server handler to which users dispatch requests to initiate/fulfill payment processes (in this case this component and the RequestFactory will be merged together).&lt;/p&gt;

&lt;h3&gt;
  
  
  4.5 Request Factory
&lt;/h3&gt;

&lt;p&gt;This component is responsible of forging the final API request that will be dispatched to the payment service provider. At the end of the day, this is what the user (of the system), our RESTful API server, makes use of. The Workflow must be initializing and passing the RequestFactory with the compatible DetailsCollector, therefore the end user can use its functions directly to forge requests. e.g. &lt;code&gt;FawryRequestFactory.payWithCard()&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.6 One Feasible Implementation
&lt;/h3&gt;

&lt;p&gt;One feasible implementation, in TypeScript, for the abstract discussion above is as follows: the &lt;em&gt;PaymentStrategy&lt;/em&gt; is just a script or bunch of scripts that export &lt;a href="https://zod.dev/" rel="noopener noreferrer"&gt;Zod&lt;/a&gt; objects. Whereas, the &lt;em&gt;DetailsCollector&lt;/em&gt; is a script or bunch of scripts that export URL endpoints for different application forms pages (assuming it’s a web application). Lastly, the &lt;em&gt;RequestFactory&lt;/em&gt; is a bunch of express handlers/middlewares that can be used within express handlers to either 1) redirect the user to the required form which in turn will (re)redirect the user to the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer" rel="noopener noreferrer"&gt;referer&lt;/a&gt; with payment info in the payload, or 2) use the payment info in the found payload, if exists, forge the request body, and finally invoke the (express) next function.&lt;/p&gt;




&lt;h2&gt;
  
  
  Further Readings
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://developer.fawrystaging.com/docs/testing/testing" rel="noopener noreferrer"&gt;End-to-End Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.fawrystaging.com/docs/error-codes/error-codes" rel="noopener noreferrer"&gt;Error Codes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.fawrystaging.com/docs/server-side-api/server-to-server-notification-v2" rel="noopener noreferrer"&gt;Server To Server Notification V2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>fawry</category>
      <category>payments</category>
      <category>fawryapi</category>
    </item>
    <item>
      <title>StateFile: A Minimalist Design for Permanent State Management</title>
      <dc:creator>Mahmoud Ehab</dc:creator>
      <pubDate>Sun, 07 Jul 2024 05:49:00 +0000</pubDate>
      <link>https://dev.to/_moehab/statefile-a-minimalist-design-for-permanent-state-management-43d7</link>
      <guid>https://dev.to/_moehab/statefile-a-minimalist-design-for-permanent-state-management-43d7</guid>
      <description>&lt;h2&gt;
  
  
  StateFile in Abstract
&lt;/h2&gt;

&lt;p&gt;A StateFile can be abstractly defined as an object that permanently holds a substate of the application.&lt;/p&gt;

&lt;p&gt;A StateFile contains and defines the structure of units of data to be hold, it supplies users, as well, with facilities to retrieve, update, or remove data (all, specific or filtered), and it takes control of saving and loading data to and from permanent storage disks. Furthermore, it can crack data into several saved files, and it does it in several means: either by specifying, by the user, a limit on the size of each saved file, by cracking in half the last saved file, or by sealing the current file and add a new one above it.&lt;/p&gt;

&lt;p&gt;Lastly, saved files shall have a conventional naming syntax that would facilitate automatically reaching it, and it shall contain a header or a metadata part in it, that contains the name of the substate it belongs to, and the order in which it's been created among other cracks (saved files).&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I've already implemented it in typescript: &lt;a href="https://github.com/Mahmoud-Ehab/cracksdb" rel="noopener noreferrer"&gt;cracksdb&lt;/a&gt; is an npm package that you can install and try in your project with the command &lt;code&gt;npm i cracksdb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs78mnjzqmchbmqec2qh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs78mnjzqmchbmqec2qh.gif" alt="GIF Overview" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One feasible implementation of the concepts and features mentioned above is concretely discussed in the following sections and illustrated in the diagram below.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Naming Syntax &amp;amp; File Structure&lt;/li&gt;
&lt;li&gt;Storing, Loading and Cracking Data&lt;/li&gt;
&lt;li&gt;Access and Manipulate Data&lt;/li&gt;
&lt;li&gt;Typer&lt;/li&gt;
&lt;li&gt;StateManager&lt;/li&gt;
&lt;li&gt;FileManager&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8z70knkmfr3ku6n82gtn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8z70knkmfr3ku6n82gtn.png" alt="StateFile Class Diagram" width="800" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Naming Syntax &amp;amp; File Structure
&lt;/h2&gt;

&lt;p&gt;In this implementation, the physical state file name and the information it contains, or some of, are strictly coupled. First of all, a state file is a JSON file that basically has three attributes: &lt;em&gt;meta&lt;/em&gt;, &lt;em&gt;data&lt;/em&gt;, and &lt;em&gt;unittype&lt;/em&gt;. &lt;em&gt;data&lt;/em&gt; is a list of units of data, where each data unit structure shall be in accordance with &lt;em&gt;unittype&lt;/em&gt;; meanly it must has, at least, the same fields as &lt;em&gt;unittype&lt;/em&gt;. &lt;em&gt;meta&lt;/em&gt; is where the coupling established between the name and the contents; it has, at least, two fields (the name of the substate and the crack order), as mentioned before, that are essentailly manifested in the file name. And accordingly, the file name syntax is &lt;code&gt;sf.[order].[substate_name].json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The prefix &lt;code&gt;sf&lt;/code&gt; makes it way easier for a StateFile to look for state files and automatically load the application state. Once a state file is found, it gets validated by checking the order and the substate name in both the file name and its content. Once a state file is validated, it gets loaded by a StateFile object. Last thing to mention, is that the order is involved in the name in order to make it possible for the StateFile to load just the lastest crack of data of the corresponding substate.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Storing, Loading and Cracking Data
&lt;/h2&gt;

&lt;p&gt;As much as the implementation discussed above, it's obvious that StateFiles store data in JSON files. This section, furthermore, discusses how exactly a StateFile object shall store, load and crack those JSONs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storing &amp;amp; Loading Data
&lt;/h3&gt;

&lt;p&gt;The constructor of a StateFile object has two parameters: one of them is the directory path in which cracks are saved, and the other is the name of the substate. The constructor first checks if any &lt;code&gt;sf.*.[substate_name].json&lt;/code&gt; file exists, if some are found then it pushes each one path in a private array &lt;code&gt;cracks_paths&lt;/code&gt;, with respect to the order in the file name, and loads the last one by a private &lt;code&gt;loadCrack&lt;/code&gt; method. On the other hand, if no sf file is found, the constructor initializes and creates an empty sf file with order equals to zero and unittype to an empty object (that indicates 'any' type).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;loadCrack&lt;/code&gt; method, in turn, validates the sf file and then pushes, if the validation yields true, the data attribute list to the private local variable &lt;code&gt;cracks_data&lt;/code&gt; of the StateFile (&lt;code&gt;cracks_data&lt;/code&gt; is an array of arrays of objects). In case the validation output is false, the method log a warning and doesn't load any data.&lt;/p&gt;

&lt;p&gt;Recall that, when StateFile already finds sf files, in the construction phase, it assigns the unittype of the first sf file to the private local variable &lt;code&gt;unittype&lt;/code&gt;. In case no file exists, it assigns an empty object instead. Furthermore, we may define a public method for users to extend the unittype. &lt;code&gt;extend&lt;/code&gt; method takes parameter of &lt;a href="//#4.%20Typer"&gt;Typer&lt;/a&gt;.Type object and extends the local unittype attributes with it. And accordingly, every crack file unittype and data unit in the data list shall be modified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cracking Data
&lt;/h3&gt;

&lt;p&gt;Data is cracked or divided by sealing crack files and initializing new ones. A sealed crack file, that has a &lt;em&gt;sealed&lt;/em&gt; attribute equals to true in the meta part, deprives storing more data units.&lt;/p&gt;

&lt;p&gt;By default, a crack file gets sealed when it reaches a limit of 100 data unit within it. That limit can be changed by users via the method &lt;code&gt;setLimit&lt;/code&gt;. Or customly, crack files may be sealed directly by invoking the method &lt;code&gt;seal&lt;/code&gt;, or the method &lt;code&gt;split&lt;/code&gt; that will seal the last crack file right after moving half of its data unit to a new one.&lt;/p&gt;

&lt;p&gt;One final noteworthy propery to mention here is that it's quite reasonable, more reliable, and less error-prone that a StateFile object contains at most one unsealed crack file. And that unsealed crack file shall be the last in the list that leaves behind the old sealed ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Access and Manipulate Data
&lt;/h2&gt;

&lt;p&gt;Users can retrieve a specifc data unit either by specifying an index or a search condition. In the same manner, users can retrieve a set of units of data, however the first way shall involve a range of two indexes. And for this purpose, four methods may be defined: &lt;code&gt;get(index)&lt;/code&gt;, &lt;code&gt;getWhere(condition)&lt;/code&gt;, &lt;code&gt;getList(index, index)&lt;/code&gt;, and &lt;code&gt;getListWhere(condition)&lt;/code&gt;. A typical definition or implementation, so to speak, of the search condition parameter might be a lambda function that takes a data unit and returns a boolean value. Furthermore, &lt;code&gt;getIndexOf(condition)&lt;/code&gt; returns the index of the first data unit that applies the condition, or -1 in case nothing is found.&lt;/p&gt;

&lt;p&gt;Adding data units, updating existing ones values, or removing them... each of these operations corresponds respectively with the methods: &lt;code&gt;add(object)&lt;/code&gt;, &lt;code&gt;update(index | condition, object)&lt;/code&gt;, and &lt;code&gt;remove(index | condition)&lt;/code&gt;; in case an index is provided the method should update/remove only one unit, in case of a condition, on the other hand, it shall update/remove the set of units that meets the condition.&lt;/p&gt;

&lt;p&gt;Just one rather subtle feature is left. When data is manipulated, should StateFile writes data automatically on the disk? or should it leave it for the user to manually invoke instead?... &lt;em&gt;simul&lt;/em&gt; is another StateFile private local variable of type boolean with true as its default value. When simul is true the StateFile will save data automatically, however, it shall rewrite only the crack file that holds the added/updated/removed data unit. On the other hand, when simul is false, the only way to save data permanently is by invoking the &lt;code&gt;save&lt;/code&gt; method which will rewrite all crack files.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Typer
&lt;/h2&gt;

&lt;p&gt;In order to store data unit types in json, parse, extend, and compare them, we ought to define a specific class that hardcodes basic types and constructs composite types objects.&lt;/p&gt;

&lt;p&gt;Typer is used by StateFile to generate a unittype object, to extend a unittype object, or to check if a specific object applies to a specific type. One straight forward property Typer shall have, in order to implement these three mechanisms, is a hardcoded enumeration of types.&lt;/p&gt;

&lt;p&gt;Typer.Type has a recursive definition whereas it's a map from a string to one of the following values: "number", "string", "boolean", and Typer.Type.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. StateManager
&lt;/h2&gt;

&lt;p&gt;Users can create StateFiles and access them only by using StateManager. A StateManager creates StateFiles with &lt;code&gt;add(substate_name)&lt;/code&gt; method and stores it in a local variable. Users can access and remove StateFiles with methods: &lt;code&gt;get(substate_name)&lt;/code&gt; and &lt;code&gt;remove(substate_name)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At the construction of StateManager, users shall provide the root directory path for sf files. Given that path, the StateManager explores it and considers every sub-directory, it founds, to be a StateFile directory, which is a directory that's been named after the substate of a StateFile. And accordingly, StateManager constructor invokes the add method with the explored directories names.&lt;/p&gt;

&lt;p&gt;Removed StateFiles are only removed from the local variable of the StateManager, however, to remove them entirely from persistence, users may invoke &lt;code&gt;delete(substate_name, passkey)&lt;/code&gt; method. The &lt;em&gt;passkey&lt;/em&gt; parameter bestows some security for users, so that sf files don't get easly or accedentally deleted. It's compared to the passkey attached in each sf file meta part, if there isn't a passkey in there then the sf file considered undeletable by the StateManager.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. FileManager
&lt;/h2&gt;

&lt;p&gt;A File object is considered as a virtual file that stores the path of the physical file and its content in local variable. And it contains methods to retrieve, set, and update the content. However, manipulating the content using File methods only happens virtually, it's not persistent.&lt;/p&gt;

&lt;p&gt;From here, a FileManager can be simply stated as a collection of File objects with a specified unique name for each of which. Users can create, read, update or remove Files only with the methods provied by FileManager. Furthermore, users can configure files to be written automatically on disk whenever its value change by invoking the method &lt;code&gt;simulFile(file)&lt;/code&gt;. And can turn it off with &lt;code&gt;unsimulFile(file)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There shall exist only one instance of FileManager that gets passed through StateManager, StateFileFactory, and StateFileContainer. As it's shown in the diagram above.  &lt;/p&gt;

</description>
      <category>programming</category>
      <category>architecture</category>
      <category>statemanagement</category>
    </item>
    <item>
      <title>A Plea for Mature Industry!</title>
      <dc:creator>Mahmoud Ehab</dc:creator>
      <pubDate>Fri, 23 Jun 2023 05:19:34 +0000</pubDate>
      <link>https://dev.to/_moehab/a-plea-for-mature-industry-476g</link>
      <guid>https://dev.to/_moehab/a-plea-for-mature-industry-476g</guid>
      <description>&lt;p&gt;Storage-Facilities Architecture is an attempt to delineate a general solution for typical problems appertain to web software development. If you browsed the source code of any open-source web application, fully developed using JavaScript in particular, you would probably find that its architecture is brutally shaped by a framework or, even worse, by a library (there are tools proclaimed as libraries, but they are usually used as frameworks in the sense that they specify at least one part of the architecture). Developing a large software project bounded to a specific framework is a pernicious decision which is significantly what led to the wide range of irrelevant, to the art of software development, titles: React Developer, VueJS Developer, ExpressJS Developer, ...etc (“Software Developer” or even “JavaScript Developer” should be sufficient). This article prescribes a general architecture, perceived as a receptacle box in which various frameworks can be plugged, that web developers can implement regardless of what technology will be used in the future. &lt;br&gt;
This article is a plea for mature industry!&lt;/p&gt;

&lt;p&gt;Read the full article on Substack:&lt;br&gt;
&lt;a href="https://open.substack.com/pub/moehab/p/storage-facilities-architecture" rel="noopener noreferrer"&gt;https://open.substack.com/pub/moehab/p/storage-facilities-architecture&lt;/a&gt;&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>architecture</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Introduction to Agile</title>
      <dc:creator>Mahmoud Ehab</dc:creator>
      <pubDate>Thu, 24 Mar 2022 07:17:52 +0000</pubDate>
      <link>https://dev.to/_moehab/introduction-to-agile-25bc</link>
      <guid>https://dev.to/_moehab/introduction-to-agile-25bc</guid>
      <description>&lt;p&gt;Agile is a technique, method, or strategy which is used in software development as an alternative to the traditional methodology. As the name indicates, it seeks to make software development easier and manageable; by applying agile, the team can observe the overall progress of the project development and make better decisions, &lt;em&gt;“User Story, Burndown Chart”&lt;/em&gt;, make more maintainable and flexible software &lt;em&gt;“Testing, Refactoring, and Pair Programming”&lt;/em&gt;, and produce consistently a free-of-bugs deployable product &lt;em&gt;"Sprints, and Iterative Development"&lt;/em&gt; — by using specific practices and artifacts (the italicized text) that we will elaborate later on.&lt;/p&gt;

&lt;p&gt;Agile has several methodologies — the prominent ones nowadays are Scrum, Extreme Programming, Lean Software, and Crystal — that follow the same principles mentioned in &lt;a href="https://agilemanifesto.org/" rel="noopener noreferrer"&gt;Agile Manifesto&lt;/a&gt; 2001. Accordingly, instead of a single development method (the traditional software engineering), agile provides us with a heap of methods and practices that are established and recommended by professional software engineers with a supreme experience in the field. Moreover, engineers can — and they should — combine between these methods to wind up with the best suitable plan for their project, rather than embracing a single method entirely, as if it’s a tenet!&lt;/p&gt;

&lt;p&gt;The following two sections shall give you a satisfying overview of agile, that is neither too brief nor too verbose; since it covers the overall concepts of agile. However, you’ll find more exposition and practice guidance in &lt;em&gt;“Agile!: the Good, the Hype, and the Ugly” book, by Bertrand Meyer&lt;/em&gt;, which is the only reference for this article.&lt;/p&gt;




&lt;h2&gt;
  
  
  Some Agile Terminologies
&lt;/h2&gt;

&lt;p&gt;This section and the following one, could be combined into one concrete section demonstrating agile principles. Actually, the content in this section is a constituent of the following one, however, it has been segregated for demonstrative reasons. You can consider it as an introductory.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Velocity:&lt;/strong&gt; indicates the project progress pace velocity; how many tasks are accomplished in a sprint (days). It’s used as a virtual artifact to observe the project state, and how the team is going on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Big Upfront:&lt;/strong&gt; it’s a derogatorily term used to refer to big steps, that usually ends up paralyzing the project’s velocity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sprint:&lt;/strong&gt; it’s a definite period of time (a development iteration), after which the project should be ready for new version deployment, even with partial functionalities. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ROI:&lt;/strong&gt; Return Of Investment. A virtual assessment of functions, to decide which functions should be implemented first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scenarios:&lt;/strong&gt; it is a description of a particular interaction of a user with the system. Moreover, it’s considered as a replacement for requirements, while user interaction is definitely more suitable, than collecting requirements (Big Upfront process), in defining tasks. Scenario is a more general term that carries two artifacts: use case, and user story.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Case:&lt;/strong&gt; it is a full run through the system. Observing the scenario from the beginning of starting the application, by the user, to the completion of a certain task(s).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Story:&lt;/strong&gt; it is a declaration of small unit of functionality expected by the users. Such as: “As a customer, I want to be able to delete my account”, “As a customer, I want to make some information in my account private”... etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Burndown chart:&lt;/strong&gt; a record of a project’s velocity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Planning Game:&lt;/strong&gt; a group estimation techniques which ask the participants to come with initial estimates independently, then examine each other’s estimates and iterate until a consensus is reached.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Agile Principles
&lt;/h2&gt;

&lt;p&gt;The principles are followed from the values, which mentioned in the &lt;a href="https://agilemanifesto.org/" rel="noopener noreferrer"&gt;manifesto&lt;/a&gt;, and from these principles each methodology devises its own practices and artifacts, that fulfill the principles and therefore preserve the values.&lt;/p&gt;

&lt;p&gt;There are twelve principles mentioned in the manifesto (&lt;a href="https://agilemanifesto.org/principles.html" rel="noopener noreferrer"&gt;https://agilemanifesto.org/principles.html&lt;/a&gt;). In this section, we are going to discuss, separately, each principle and mention its followed practices and artifacts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foidmyfukal2w3ykk0bjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foidmyfukal2w3ykk0bjl.png" alt="Agile Manifesto Image" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Continues Delivery
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Earlier, in traditional software engineering, it wasn't uncommon to split the project into sub-developments and then, at the end of the development or after few months, integrate those constituents all together to institute the whole project. This practice was effective in simplifying the development of the project, however, it was impediment for deployment. It takes much time to fix the bugs and incompatibility between different parts (sub-developments) of the system.&lt;/p&gt;

&lt;p&gt;Therefore, agile methodologies advocate CI / CD (Continuous Integration &amp;amp; Continuous Delivery). The sub-developments should be integrated frequently, in order to provide two values: &lt;em&gt;working software&lt;/em&gt; and &lt;em&gt;customer collaboration&lt;/em&gt;. The first is accomplished, in the sense of fixing bugs and incompatibility as soon as possible, by integrating the parts after few weeks, rather than months (there are methodologies recommend doing it several times a day). Moreover, the later is accomplished by producing working software after each integration to the customer for feedback.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Accept Changes and Customer Role
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Welcome changing requirements, even late in development. Agile processes harness change for the customer's competitive advantage.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In agile, the customer has a central role in the project development. Rather than documenting the requirements at the planning phase of the project — which considered as a big upfront — we let it evolves as the project develops, by giving the customer a central role that usually concerns in trying intermediate releases of the project. This approach, replacing the requirements or vanishing big upfronts, is almost applied by all agile principles.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Working Software
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.&lt;/p&gt;

&lt;p&gt;Working software is the primary measure of progress.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These two principles may seem redundant of the first one listed in this section. However, the both demonstrates a guideline that our practices shall follow. These two principles telling us that we should always be able and ready to produce and deploy a working software (new version of the application) after each sprint, even if with partial functionality. Neither The deadline can be postponed for deployment, nor the application can be deployed with bugs, because of adding new feature to the application.&lt;/p&gt;

&lt;p&gt;So, the primary measure of progress is not how many functionalities have been added. Working software has more priority in agile development, and the software is assured working through the use of test suites.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Team Meetings
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Business people and developers must work together daily throughout the project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This principle is, obviously, a practice than it’s a principle. Agile methods advocate frequent face-to-face contact between team members. It helps teams remain cohesive, know what everyone is doing, and spot problems early.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Open Rooms and Pair Programming
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.&lt;/p&gt;

&lt;p&gt;The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agile methodologies reject and revolt on cubicles and closed offices. It’s preferable to set up the office as an open room to favor constant interaction between team members. Moreover, a common practice of agile, is pair programming. In which the code is written by one developer, while being supervised or criticized by another developer. This helps catching mistakes or even bad code early.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Sustainable Development
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again, another principle seems redundant; all the previous principles certainly invoke sustainability. However, it may have other meanings or values. This principle refuses putting the team in an exceptional pressure, rather, the developers should work in reasonable hours, preserving evenings and weekends. It could be considered as a revolt on managers, as we may see in later principle.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Refactoring and TDD
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Continuous attention to technical excellence and good design enhances agility.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To make our software agile, we should create a test for every single code. Concisely, we should not write any new code before creating its unit tests. Therefore, the test comes first then we think about the simplest code that makes that test passes, and we iterate these two steps over and over again, until there is no more test to be passed. In other words, this part of the software we are working on is done. This approach is known as &lt;em&gt;Test-Driven Development&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Eventually, applying TDD winds up with a fragile, messy, and miserable design of the code. And here comes another significant practice in agile, &lt;em&gt;Refactoring&lt;/em&gt;. Which is the process of critically examining a design or implementation and applying any transformations that may be needed to improve its consistency. (It may not seem obvious, if one doesn’t know what software design &amp;amp; architecture is)&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Minimalistic Funcationality
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Simplicity--the art of maximizing the amount of work not done--is essential.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The development phase in agile methods should be as simple as possible, as the team must be able to deploy a new version in two weeks! Therefor, the functionalities that need to be done in the next iteration (sprint), must be essential and requested by the customer. So, if the team meeting before the beginning of any sprint &lt;em&gt;“planning game”&lt;/em&gt;, winded up with ten functionalities whilst two of them are only essential for the user, the other eight functionalities are excluded for next iterations. It’s a matter of concern to be aware of that the ROI is definitely used in the exclusion process.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Self-Organizing Team
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The best architectures, requirements, and designs emerge from self-organizing teams.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agile methods redefine and limit the manager’s job by transferring many of the duties to the team as a whole, including one of the most important responsibilities: selecting tasks to be performed and assigning them to developers. Agile teams are self-organizing, deciding on their own tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Retrospective
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another agile practice is the retrospective, in which a team having finished a development iteration takes time off further development to reflect on the experience and the lessons learned, with the goal of improving its development process.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>management</category>
      <category>productivity</category>
    </item>
    <item>
      <title>From Coding to Programming: Introduction</title>
      <dc:creator>Mahmoud Ehab</dc:creator>
      <pubDate>Tue, 01 Mar 2022 23:14:31 +0000</pubDate>
      <link>https://dev.to/_moehab/from-coding-to-programming-introduction-345b</link>
      <guid>https://dev.to/_moehab/from-coding-to-programming-introduction-345b</guid>
      <description>&lt;p&gt;The era of programmers; this is the best description that I'd give to the current era we live in. In these days, everyone wants to be a programmer, each one of us is somehow attracted to programming since the first time he/she heard of it. Thanks to YouTube and the dozens of free online courses on the internet, the number of programmers in the whole world is increasing exponentially. Each one of us, as a newbie, got interested in this creative magic thing, watched dozens of videos on YouTube that telling us how to write classes and methods (how to code), wrote several applications with various languages in different disciplines — starting with "Hello World" simple app, and ending up to a barely complex desktop/web/mobile app. Hover, &lt;strong&gt;knows nothing about programming&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As I mentioned, we watched many tutorials, but &lt;strong&gt;none of them taught us how to program&lt;/strong&gt;. All they taught us is how to write code, how to define variables and use them with flow-control statements, how to turn the thoughts and solutions in our mind into code of sequences, selections, and iterations. Which is a good thing to learn, but it's not sufficient to make us real programmers.&lt;/p&gt;

&lt;p&gt;It may seem absurd in the first glance; you may think that: "But we actually do make programs, so we can do programming... WE ARE PROGRAMMERS!". No, &lt;strong&gt;you cannot be a programmer just because you're able to produce a program&lt;/strong&gt;. You are just using some programmers' artifacts to make/produce your messy, miserable, fragile program. You can't take a sketching pencil and start scribbling and then call yourself an artist!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Robert_C._Martin" rel="noopener noreferrer"&gt;Robert Martin&lt;/a&gt; had been teaching us that, in his books and lectures, for years. And one of the remarkable things that Robert said in one of his lectures was that the word "software" is a compound word composed of two words; "ware" which means product, and the word "soft" which means easy to change. We, as newbies programmers (software developers), fulfill just one part; we just write codes and make products that are not "soft", that are not maintainable and flexible.&lt;/p&gt;

&lt;p&gt;Eventually, learning how to write code isn't sufficient to make you and me programmers. Software design and architecture is an essential topic for programmers to learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Software Design &amp;amp; Architecture
&lt;/h2&gt;

&lt;p&gt;Although the word architecture is usually used to refer to the high-level, and the word design to the low-level, we often use the both interchangeably. In software, the high-level and the low-level specifications are made asynchronously, &lt;strong&gt;the architect keeps leaping from one level to the other&lt;/strong&gt;, several times. Until he winds up with the suitable design for the system.&lt;/p&gt;

&lt;p&gt;A software with a good architecture ought to be maintainable and flexible; If some code somewhere has been changed for some reason, it doesn't cause a bunch of bugs throughout various parts of the system. If any new feature would be added to the system, not much code would be changed (if 0 code will be changed, then the architect did his job well). On the other hand, a software with a bad architecture is always hard to change, hard to maintain, and costs a lot of money and time.&lt;/p&gt;

&lt;p&gt;We may define Software Design and Architecture as a set of principles and best practices in software development, that developers should employ in their systems, in order to obtain the highest level of maintainability and flexibility.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In this series, I'll cover some of the principles, and a few design patterns. However, you can take a step further and learn more about these stuff by reading the following two books:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean Architecture, by Robert Martine. &lt;/li&gt;
&lt;li&gt;Design Patterns, Elements of Reusable Object-Oriented Software. &lt;/li&gt;
&lt;li&gt;Or even by watching &lt;a href="https://www.youtube.com/playlist?list=PLmmYSbUCWJ4x1GO839azG_BBw8rkh-zOj" rel="noopener noreferrer"&gt;Robert Martin lectures on YouTube&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>execCommand() Alternative</title>
      <dc:creator>Mahmoud Ehab</dc:creator>
      <pubDate>Thu, 13 Jan 2022 19:26:14 +0000</pubDate>
      <link>https://dev.to/_moehab/documentexeccommand-alternative-5a55</link>
      <guid>https://dev.to/_moehab/documentexeccommand-alternative-5a55</guid>
      <description>&lt;h1&gt;
  
  
  Abstract
&lt;/h1&gt;

&lt;p&gt;Unfortunately, &lt;code&gt;document.execCommand()&lt;/code&gt; function is no longer recommended, as it may be in the process of being dropped. If you are implementing a text editor in your web application, this is probably bad news for you. As this feature (JS feature) is used in making bold and italic texts, and may be in other few things too, like highlighting, redoing, ...etc.&lt;/p&gt;

&lt;p&gt;This article gives you another way for implementing this kind of text manipulating — using built-in JS objects. Although, this article handles only bolding texts, the general approach can be used in implementing almost anything.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction: Some Definitions
&lt;/h1&gt;

&lt;p&gt;Straightforwardly, we shall use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Selection" rel="noopener noreferrer"&gt;Selection&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Range" rel="noopener noreferrer"&gt;Range&lt;/a&gt; built-in JS objects instead of the function &lt;code&gt;document.execCommand()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Range Object
&lt;/h2&gt;

&lt;p&gt;This is considered as the primitive object that makes the whole magic. It's exactly what we need to bold a text.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A range is a contiguous part of a document. A range can contain entire nodes as well as &lt;strong&gt;portions of nodes&lt;/strong&gt; (such as a portion of a text node).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Selection Object
&lt;/h2&gt;

&lt;p&gt;As this object deals with the selected text in the screen via the user. Then it's our key to get a range object represents the text (portion of node) that we desire to manipulate.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Selection object represents the range of text selected by the user or the current position of the caret. To obtain a Selection object for examination or manipulation, call &lt;code&gt;window.getSelection()&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  boldCommand Function
&lt;/h1&gt;

&lt;p&gt;"Writing a function that makes the selected text bold" is kinda synoptic description or fuzzy, I'd say. Let's reformulate it to: a function that wraps the selected text within a node ("strong" HTML tag, for instance). And that's what we exactly are going to do; we'll insert the &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; HTML element in the node of the selected text, in a specific range, using the &lt;code&gt;Range&lt;/code&gt; JS object.&lt;/p&gt;

&lt;p&gt;The logic of our function is simply as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create &lt;code&gt;&amp;lt;strong&amp;gt;&amp;lt;/strong&amp;gt;&lt;/code&gt; HTML element.&lt;/li&gt;
&lt;li&gt;Initialize a variable to the selection of the user (Selection Object).&lt;/li&gt;
&lt;li&gt;Initialize a variable to the Range object from the selection in the previous step.&lt;/li&gt;
&lt;li&gt;insert the created element in the first step using the range object in the previous step.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;boldCommand&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strongElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strong&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSelection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSelection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedTextRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userSelection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRangeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;selectedTextRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;surroundContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strongElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Make Video Cutter with Bash Script + FFmpeg</title>
      <dc:creator>Mahmoud Ehab</dc:creator>
      <pubDate>Fri, 07 Jan 2022 05:33:46 +0000</pubDate>
      <link>https://dev.to/_moehab/make-video-cutter-with-bash-script-ffmpeg-om0</link>
      <guid>https://dev.to/_moehab/make-video-cutter-with-bash-script-ffmpeg-om0</guid>
      <description>&lt;h1&gt;
  
  
  1. Introduction
&lt;/h1&gt;

&lt;p&gt;When I want to take off some clips or scenes from a video on my laptop (with HDD), I usually find it tedious to do such a trivial thing using blender, shotcut, ...etc. Therefore, I wondered if I could simply use the terminal to do that. &lt;/p&gt;

&lt;p&gt;This is what the article is all about. By the end of reading this article, you will not only be able to edit your videos using the terminal, but you will also be able to write your own bash script file.&lt;/p&gt;

&lt;p&gt;I'm not sure if this is useful in the tech industry, but I know that it's kinda interesting for anyone who has already involved in coding before. You could consider this article as a piece of entertainment for CS GEEKS!&lt;/p&gt;




&lt;h1&gt;
  
  
  2. A Sneak Peek of Bash Script
&lt;/h1&gt;

&lt;p&gt;First, and right before demonstrating the basics, we should mention a brief intro to what Bash actually is. In the same way, knowing what is Bash, is inherent from knowing what is GNU.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are familiar with the basics, you can just skip ahead to part 3 below.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2.1 What is GNU?
&lt;/h2&gt;

&lt;p&gt;GNU is an operating system composed entirely of free software, that &lt;em&gt;Richard Stallman&lt;/em&gt; developed and launched in September 1983. Free Software doesn't mean gratis, as &lt;em&gt;Stallman&lt;/em&gt; defines it, it means a software that respects the users' freedom.&lt;/p&gt;

&lt;p&gt;For more elaboration, you can watch &lt;em&gt;Stallman&lt;/em&gt; himself talking about it in the video in the following link.&lt;br&gt;
&lt;a href="https://www.fsf.org/blogs/rms/20140407-geneva-tedx-talk-free-software-free-society" rel="noopener noreferrer"&gt;Richard Stallman's TEDx video: "Introduction to Free Software and the Liberation of Cyberspace"&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  2.2 What is Bash &amp;amp; Bash Scripting?
&lt;/h2&gt;

&lt;p&gt;Bash is just the shell of GNU operating system. It takes commands from the user and execute it. And it considered the both, a command interpreter and a programming language.&lt;/p&gt;

&lt;p&gt;Bash Scripting is collecting/writing bash commands in &lt;code&gt;.sh&lt;/code&gt; file(s), that can then be executed using the bash.&lt;/p&gt;
&lt;h2&gt;
  
  
  2.3 Bash Scripting Basics
&lt;/h2&gt;
&lt;h3&gt;
  
  
  2.3.1 Syntax
&lt;/h3&gt;

&lt;p&gt;Bash simply reads your script line by line, considering each one as a separated &lt;strong&gt;simple command&lt;/strong&gt; or a constituent of a &lt;strong&gt;compound command&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As The form of simple command is just a sequence of words separated by blanks; like so &lt;code&gt;echo "Hello World!"&lt;/code&gt;. You should be careful when you define variables, for instance &lt;code&gt;x = "some string var"&lt;/code&gt; the x in this line would be interpreted as a command.&lt;/p&gt;

&lt;p&gt;A compound command is just a construct, that has a reserved word for indicating its beginning and another reserved word for its ending. It could contain more than simple command within, where each command separated with new line(s) or semicolon. For instance, the if statement &lt;code&gt;if [ condition ]; then echo "Hello"; fi&lt;/code&gt; considered as a compound command.&lt;/p&gt;

&lt;p&gt;For defining strings, you can use either single or double quotes. However, you may want to use double quotes rather than the single, when you need to use '$' as NOT literal. (as we'll see, it's used to retrieve variables values)&lt;/p&gt;

&lt;p&gt;One final thing, the very first line of every script should be the path of the bash on your machine, which is used to interpret and run the current file. &lt;code&gt;#!/bin/bash&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2.3.2 Parameters &amp;amp; Variables
&lt;/h3&gt;

&lt;p&gt;Every variable is a parameter, and not vice verse. A parameter is an entity that stores values, and once you give this parameter a name, It's called a variable.&lt;/p&gt;

&lt;p&gt;You can declare a variable simply like that &lt;code&gt;name=value&lt;/code&gt; or by using &lt;code&gt;declare&lt;/code&gt; built-in command. Using declare command can be useful in several ways, one of which is when you want to declare a readonly (constant) variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;var1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Hello World!"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;declare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Hello World using declare"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;declare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ReadOnly Variable"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, when you want to print the variable value, for instance. You have to use '$' symbol to retrieve the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;var1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: 'var1'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;var1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: 'Hello World!'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Positional Parameters&lt;/strong&gt; are parameters that denoted by one or more digits, other than the single digit 0. They are temporarily replaced when a shell function is executed. And the &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;shift&lt;/code&gt; builtins are used to set and unset them. You can reference them using '$' as with variables, except when denoted with more than one digit. Then you have to use &lt;em&gt;parameter expansion&lt;/em&gt;. &lt;code&gt;$1, $2, ${12} #Examples&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Special Parameters&lt;/strong&gt; are parameters that special for Bash, they can only be referenced, whereas each one expands to some value(s). You can think of them as built-in commands, or functions. We will use two of them in &lt;em&gt;VideoCutter&lt;/em&gt; scripts: the @ parameter and 0. You can read of each one in the following link: &lt;a href="https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html#Special-Parameters" rel="noopener noreferrer"&gt;Special Parameters&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3.3 Expansions
&lt;/h3&gt;

&lt;p&gt;In my opinion, this's the most interesting topic in bash scripting. Expansions are used for several purposes, they are in arithmetic operations, making sequences (for instance, a list containing numbers: from one to ten), word splitting, and other more few things.&lt;/p&gt;

&lt;h4&gt;
  
  
  Brace Expansion
&lt;/h4&gt;

&lt;p&gt;Brace Expansion can be used in two ways. One of them for generating multiple words with prefix or/and postfix.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: abe ace ade&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;videos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#will make two directories&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As in variables, Bash will be confused with spaces in the brace Expansion&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: a{b, c, d}e&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: a b c&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a "&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: a b a c&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the another way is for generating sequences. You can think of it as a function that takes three parameters, the first one is the beginning of the sequence, the second is the ending, and the third is the increment value. The 'parameters' are separated by "..".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;..5..1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: 1 2 3 4 5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a..d..1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: a b c d&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Parameter Expansion
&lt;/h4&gt;

&lt;p&gt;Parameter Expansion is used to reference parameter/variable value. And It may be used with braces to protect the variable name from expanding with the following symbols.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Hello "&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: Hello &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;varWorld&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: ""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;World&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: Hello World&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are many features in this expansion, two of them are specifying the offset and the length of a string parameter.&lt;br&gt;
&lt;code&gt;${parameter:offset}&lt;/code&gt;&lt;br&gt;
&lt;code&gt;${parameter:offset:length}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can check all its features here: &lt;a href="https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion" rel="noopener noreferrer"&gt;Shell-Parameter-Expansion&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Arithmetic Expansion
&lt;/h4&gt;

&lt;p&gt;To evaluate arithmetic expressions, you cannot simply do this &lt;code&gt;var=1+1&lt;/code&gt; as in other programming languages. '1', '+', and '1' are not making any difference than 'a', 'b', and 'c'. They all treated as characters that construct a string.&lt;/p&gt;

&lt;p&gt;Arithmetic Expansion allow us to make arithmetic operations, by enclosing the expression with brackets, like that &lt;code&gt;$(( expr ))&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1+1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: 1+1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: 2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: 8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2**4"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: 16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The evaluation is performed according to the rules of &lt;a href="https://www.gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html" rel="noopener noreferrer"&gt;Shell Arithmetic&lt;/a&gt;. If the expression is invalid, Bash prints a message indicating failure to the standard error and no substitution occurs. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2.3.4 Split Strings
&lt;/h3&gt;

&lt;p&gt;To split strings in Bash, we will use &lt;code&gt;read&lt;/code&gt; built-in command, that will read some input (string) into an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"some string"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: some&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#output: string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;read&lt;/code&gt; splits the string according to each char in &lt;code&gt;IFS&lt;/code&gt; variable. &lt;code&gt;IFS&lt;/code&gt; default value is "{space}{tab}{newline}".&lt;/p&gt;

&lt;p&gt;And the notation &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt; is called &lt;a href="https://www.gnu.org/software/bash/manual/html_node/Redirections.html#Here-Strings" rel="noopener noreferrer"&gt;here-string&lt;/a&gt;. That is used to redirect the &lt;code&gt;read&lt;/code&gt; command to get the string from some source (variable), instead of prompting the user to enter some string. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.3.5 Bash Conditional Expressions
&lt;/h3&gt;

&lt;p&gt;Conditional Expressions return a boolean value; either true or false. They are used in if statement, and loop constructs. Therefore, It's essential to introduce them before going on.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-z&lt;/code&gt; checks if the variable is empty or not.&lt;br&gt;
&lt;code&gt;-gt&lt;/code&gt; checks if the left value is &lt;em&gt;greater than&lt;/em&gt; the right value.&lt;br&gt;
&lt;code&gt;-eq&lt;/code&gt; checks if the left value equals the right value.&lt;br&gt;
&lt;code&gt;-ge&lt;/code&gt; checks if the left value greater than or equal to the right value.&lt;/p&gt;

&lt;p&gt;Check the hole list here: &lt;a href="https://tldp.org/LDP/abs/html/comparison-ops.html" rel="noopener noreferrer"&gt;Comparison Operators&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2.3.6 If Statement
&lt;/h3&gt;

&lt;p&gt;As the reader is supposed to be already involved in coding before. We only concerned to demonstrate the syntax of &lt;em&gt;If Statement&lt;/em&gt; and &lt;em&gt;Loops Constructs&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If Statement&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="n"&gt;consequent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exmaple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The variable is empty!"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;elif&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The variable is smaller than or equal to five."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The variable is greater than five."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3.7 Loops
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;While Loop&lt;/strong&gt;&lt;br&gt;
Execute commands while the expression(s) is/are true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="m"&gt;+1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For Loop&lt;/strong&gt;&lt;br&gt;
Form 1&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;listOfNames&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;John&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Robert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bob&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;listOfNames&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;]};&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Form 2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3.8 Prompt user for inputs
&lt;/h3&gt;

&lt;p&gt;To get inputs from users, we shall use &lt;code&gt;read&lt;/code&gt; built-in command &lt;code&gt;read variable-name&lt;/code&gt;. And for displaying some text for the user to inform him what kind data should he enter, we use -p.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"x: "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Y: "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*$&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;#output:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#x: 4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#y: 5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#20&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3.9 Number Base
&lt;/h3&gt;

&lt;p&gt;A final thing that I'd like to mention in this brief tutorial: is how to convert integer variable base from octal to decimal. By default, Bash reads (interprets) any integer input in decimal base. Hovever, if the integer preceeded with 0, It tries to interpret it in octal base. Therefore, if you tried to add one to "08", Bash will give you an error message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"08"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="c1"&gt;#output: &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#bash: 08: value too great for base (error token is "08")&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to convert the base from octal to decimal. We shall use another form to write the number 08: &lt;code&gt;base#"number"&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="c1"&gt;#"08" + 1 )) &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#output: 9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, here's a handy cheatsheet that you may use to refresh your memory: &lt;a href="https://devhints.io/bash" rel="noopener noreferrer"&gt;Bash Scripting cheatsheet&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Just to know; There are very basic stuff that were NOT mentioned here — they aren't used in &lt;em&gt;VideoCutter&lt;/em&gt;. (pipelines, function, select, case, and many other)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  3. VideoCutter using FFmpeg
&lt;/h1&gt;

&lt;p&gt;Now the action begins, by using what we've learned in the previous section, and few commands from &lt;a href="https://ffmpeg.org/" rel="noopener noreferrer"&gt;FFmpeg&lt;/a&gt;. We are going to write a bash script that prompt the user to input the path of the video file that supposed to be trimmed, and list of periods of that video.&lt;/p&gt;

&lt;p&gt;Before getting started in writing and demonstrating the script step-by-step. You can download and try it from the following repository: &lt;a href="https://github.com/Mahmoud-Ehab/video-cutter" rel="noopener noreferrer"&gt;https://github.com/Mahmoud-Ehab/video-cutter&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can install FFmpeg on ubuntu just by using the following commands:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sudo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sudo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ffmpeg&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3.1 Program Components (Scripts)
&lt;/h2&gt;

&lt;p&gt;The program constructs of only four components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main.sh&lt;/code&gt; this is the file which contains the main logic of the program, and what the user expected to execute.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cutter.sh&lt;/code&gt; used by main.sh as a command to extract clips from a mp4 file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mp4tots.sh&lt;/code&gt; used by main.sh to convert the extracted clips from mp4 extension into ts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tstomp4.sh&lt;/code&gt; used by main.sh to convert "clips.ts" file (the concatenation of the clips with ts extension files) from ts into mp4.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;. TS file extension is a Video Transport Stream file used to store MPEG-2-compressed video data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3.2 main.sh
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1- Get inputs from the user
&lt;/h3&gt;

&lt;p&gt;First we prompt the user to input the mp4 file path and the directory where the clips will be exported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mp4FilePath: "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"outputDir: "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dirpath&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we check if the &lt;code&gt;dirpath&lt;/code&gt; is empty. If it is, then make it equal the current directory path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dirpath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;dirpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Intialize two lists &lt;code&gt;T1 &amp;amp; T2&lt;/code&gt;; The first one is a list of intial time of each clip, and the second of the end of each clip.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#List of clips initial time&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#List of clips end time&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Each clip is a string in the form hh:mm:ss&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And finally make a while loop for prompting user inputs repeatedly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#Var for indicating the end of while loop&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#The number of specified clips&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;# Prompt user for inputs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Clip$count T1: "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Clip$count T2: "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enough? (0 for no, 1 for yes): "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2- Extract clips from the mp4 file
&lt;/h3&gt;

&lt;p&gt;First create the directory the user specified using &lt;code&gt;mkdir&lt;/code&gt; command. If it does exist, nothing happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dirpath&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then by using for loop, $count variable, and cutter.sh script.  Generate $count number of clips out of $Mp4PathFile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;$&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"$dirpath/clip$i.mp4"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;bash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cutter.sh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3- Combine the clips
&lt;/h3&gt;

&lt;p&gt;Convert clips from mp4 to ts using for loop... and mp4tots.sh script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;mp4file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"$dirpath/clip$i.mp4"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;tsfile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"$dirpath/clip$i.ts"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;bash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mp4tots.sh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;mp4file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;tsfile&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;# Remove the mp4 file&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;rm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;mp4file&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then concatenate them using &lt;code&gt;cat&lt;/code&gt; built-in command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;tsfiles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;$&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" $dirpath/clip$i.ts"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;tsfiles&lt;/span&gt;&lt;span class="o"&gt;+=$&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;tsfiles&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dirpath&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;output.ts&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;rm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;tsfiles&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally convert the final ts file into mp4 using tstomp4.sh script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;bash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tstomp4.sh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dirpath&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;output.ts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dirpath&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;output.mp4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;rm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;dirpath&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;output.ts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3.3 cutter.sh
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;cutter.sh&lt;/code&gt; has 4 positional parameters: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$1: the mp4 file path.&lt;/li&gt;
&lt;li&gt;$2: t1, the beginning time of the clip. In the form &lt;code&gt;hh:mm:ss&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;$3: t2, the ending time of the clip. in the form &lt;code&gt;hh:mm:ss&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;$4: the output clip path.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1- Check if the required positional parameters are given
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Valid Usage: ./script.sh src.mp4 hh:mm:ss hh:mm:ss out.mp4"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;INP&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;OUT&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2- Initialize start and end time variables
&lt;/h3&gt;

&lt;p&gt;start and end will be arrays with three elements: hours, minutes, and seconds.&lt;br&gt;
To split the user inputs $2 and $3, we shall use split strings (section 2.3.4 of this article) as descriped above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;':'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#For splitting T1 and T2&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;# Initialize start time list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;]};&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;# Initialize end time list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;]};&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3- Evaluate the duration between T1 and T2
&lt;/h3&gt;

&lt;p&gt;The following algorithm (code) is trivial, and elaborating it is out of the scope of the article.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Evaluate the duration between T1 and T2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;# secs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;ss&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="c1"&gt;#${end[2]} - 10#${start[2]} ))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="c1"&gt;#${end[1]} - 1 ))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;ss&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="c1"&gt;#${end[2]} + 60 - 10#${start[2]}))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;# mins&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="c1"&gt;#${end[1]} - 10#${start[1]} ))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="c1"&gt;#${end[0]} - 1 ))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="c1"&gt;#${end[1]} + 60 - 10#${start[1]} ))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;# hours&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;hh&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="c1"&gt;#${end[0]} - 10#${start[0]} ))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After initializing $ss, $mm, and $hh. We shall assert that eachone of them is a string of length 2. Then construct the dur variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ss&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"0$ss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"0$mm"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;hh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hh&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"0$hh"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;dur&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="n"&gt;hh&lt;/span&gt;&lt;span class="o"&gt;:$&lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="o"&gt;:$&lt;/span&gt;&lt;span class="n"&gt;ss&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4- Export the clip using FFmpeg command
&lt;/h3&gt;

&lt;p&gt;Finally, we can take off the clip from the source mp4 using FFmpeg.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;ffmpeg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$INP"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ss&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$T1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$dur"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$OUT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3.4 mp4tots.sh
&lt;/h2&gt;

&lt;p&gt;This script has jsut two positional parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$1: the mp4 file path&lt;/li&gt;
&lt;li&gt;$2: the ts file path&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1- Check if the required positional parameters are given
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Valid Usage: ./script.sh input.mp4 output.ts"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2- Convert the mp4 file using FFmpeg
&lt;/h3&gt;

&lt;p&gt;Using FFmpeg command as found in the docs. (you can find it in the references)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;ffmpeg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vcodec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vbsf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;h264_mp4toannexb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;acodec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$2"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3.5 tstomp4.sh
&lt;/h2&gt;

&lt;p&gt;This script has jsut two positional parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$1: the ts file path&lt;/li&gt;
&lt;li&gt;$2: the mp4 file path&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1- Check if the required positional parameters are given
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Valid Usage: ./script.sh input.mp4 output.mp4"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2- Convert the ts file using FFmpeg
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;ffmpeg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;acodec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;44100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ab&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;96&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;coder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ac&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vbsf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;h264_mp4toannexb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$2"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gnu.org/" rel="noopener noreferrer"&gt;https://www.gnu.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gnu.org/software/bash/manual/html_node/index.html" rel="noopener noreferrer"&gt;https://www.gnu.org/software/bash/manual/html_node/index.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tldp.org/LDP/abs/html/comparison-ops.html" rel="noopener noreferrer"&gt;https://tldp.org/LDP/abs/html/comparison-ops.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ffmpeg.org/ffmpeg.html#Main-options" rel="noopener noreferrer"&gt;https://ffmpeg.org/ffmpeg.html#Main-options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ffmpeg.org/ffmpeg.html#Advanced-options" rel="noopener noreferrer"&gt;https://ffmpeg.org/ffmpeg.html#Advanced-options&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>bash</category>
      <category>linux</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Animate Components - ReactJS</title>
      <dc:creator>Mahmoud Ehab</dc:creator>
      <pubDate>Sun, 26 Dec 2021 19:22:22 +0000</pubDate>
      <link>https://dev.to/_moehab/animate-components-reactjs-49gh</link>
      <guid>https://dev.to/_moehab/animate-components-reactjs-49gh</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;If you want to animate your ReactJS Components in a rapid and easy manner, without using CSS. Then this post is for you.&lt;/p&gt;

&lt;p&gt;To make it possible to define our own animations in ReactJS, without using CSS. We'll just use style prop, hooks and transition. However, to do so in a flexible manner with all CSS keyframes/animation features (loop, backward animation, ...etc) that goes beyond using just transition. And so, we ought to create an external reusable component that carries the whole logic of switching between different stages in the animation.&lt;/p&gt;

&lt;p&gt;I already wrote such a component and deployed it on &lt;a href="https://www.npmjs.com/package/react-animation-maker" rel="noopener noreferrer"&gt;npm&lt;/a&gt;, with an additional feature: useAnimate hook that makes it more elegant and powerful. And this post elaborates how to use it in your project. However, if you want a post in how it actually works, let me know in the comments.&lt;/p&gt;

&lt;h1&gt;
  
  
  Installing
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install react-animation-maker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source Code: &lt;a href="https://github.com/Mahmoud-Ehab/react-animation-maker" rel="noopener noreferrer"&gt;react-animation-maker&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Usage
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Animate Component
&lt;/h2&gt;

&lt;p&gt;This component is used to define your own animations only using css-js objects. It animate the div from the object of the 'from' prop, to the list of objects of the 'to' prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Animate&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-animation-maker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Animate&lt;/span&gt; 
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f00&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; 
&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#0f0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Animate&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can create multi-staged animation, as well. In other words, adding more than one object in the 'to' prop list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Animate&lt;/span&gt; 
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f00&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; 
&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#0f0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#00f&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Animate&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Other props (OPTIONAL)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;style: js-css object&lt;/code&gt; for the general style of all stages.&lt;br&gt;
&lt;code&gt;durations: string[]&lt;/code&gt; the durations between stages, its default value ['1s'].&lt;br&gt;
&lt;code&gt;delay: int&lt;/code&gt; specifies the delay time in milliseconds.&lt;br&gt;
&lt;code&gt;loop: boolen&lt;/code&gt; to indicate wheather the animation loops forever or not.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using 'durations' Prop
&lt;/h2&gt;

&lt;p&gt;This is an optional prop, whose only purpose is to descripe the duration between each stage and the one preceeding, starting from the first stage in "to" prop. The durations list length should be as the length of "to" list. If it's not, then the first value of the durations list is considered as the duration between each stage and the another.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Animate&lt;/span&gt; 
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f00&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; 
&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#0f0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#00f&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f0f&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;span class="nx"&gt;durations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;250ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;500ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;750ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Animate&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Using Pre-defined Animations
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Animate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FancyPopIn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-animation-maker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Animate&lt;/span&gt; 
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;FancyPopIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;FancyPopIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;durations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;FancyPopIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;durations&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Animate&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Checkout the whole list here:&lt;br&gt;
&lt;a href="https://mahmoud-ehab.github.io/react-animation-maker" rel="noopener noreferrer"&gt;https://mahmoud-ehab.github.io/react-animation-maker&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Using useAnimate Hook
&lt;/h2&gt;

&lt;p&gt;Another way to use Animate Component is using it through useAnimate Hook. This gives you the ability to rename your Animate Components and consequently increase the readibilty of your code. What makes it more powerful, that it allows you to change the animation of the component using event handlers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useAnimate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FadeIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FadeOut&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-animation-maker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Anim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAnim&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAnimate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FadeIn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Anim&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Anim&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setAnim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FadeOut&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;Change&lt;/span&gt; &lt;span class="nx"&gt;Anim&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that setAnim in the above example; just takes a props object,&lt;br&gt;
hence you can do the following, as well...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useAnimate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FadeIn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-animation-maker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Anim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAnim&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAnimate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FadeIn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Anim&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Anim&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setAnim&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{[{&lt;/span&gt;&lt;span class="na"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}]})}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;Change&lt;/span&gt; &lt;span class="nx"&gt;Anim&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
  </channel>
</rss>
