Javascript
Introduction
External Links
- The size of the World Wide Web (The Internet)
@[https://www.worldwidewebsize.com/]
- State Of JS:
@[https://stateofjs.com/]
  Check out our results to find out which libraries developers want to learn 
  next, which have the best satisfaction ratings, and much more.
-@[https://developer.mozilla.org/en-US/]
-@[https://eloquentjavascript.net/]
-@[https://www.infoq.com/articles/javascript-web-development-trends]
  how well does your browser support HTML5?
@[http://html5test.com/] 
- webplatform. Your Web, Documented.  
-@[https://webplatform.github.io/]
  The latest information on how to use the technology 
  that runs the web — HTML, CSS, JavaScript and more.  WebPlatform.org is a 
  work in progress. We could use your help in making it better. Join us.
- Great blog about CSS design and  HTML5
@[http://www.smashingmagazine.com/]
@[https://jvns.ca/blog/2018/11/01/tailwind--write-css-without-the-css/]

- Browser Built-in objects:
@[http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects]
- @[https://css-tricks.com/learning-to-learn/]
Arrays
var l = [1,2,3,4,1]
l.length         // 5
1 in l           // true
l.indexOf(1)     // ← 0 (-1 if not found)
l.lastIndexOf(1) // ← 4
l.join()         // ← "1,2,3,4,1" string
l.pop(2/*index*/)// ← returns 3. after  l = [1,2,4,1]
l.pop()          // ← returns 1. after  l = [1,2,4]
l.push(5)        // ← 4 (new length)    l = [1,2,4,5]
l.reverse()      //                     l = [5,4,2,1]
l.  shift()      // ← 5 (1st element)   l =   [4,2,1]
l.unshift(5)     // ← 4 (new length)    l = [5,4,2,1]
l.slice()        // TODO: return part of the array as new array.
l.sort()         //                     l = [1,2,4,5]
                 //ºA sort function can be providedº
l.splice()       // Adds/removes elements from array.
                    splice accepts two lists of elements: the
                    elements to remove and the ones to be added.
l.toString()
l.valueOf()      // TODO:  Returns the primitive value of the array.
Immutable JS Code
- const doesn't make an object inmutable.
  It just avoid re-referencing or adding atributes. Ej:
  const a = [1,2,3]
  a[0] = 3 ; // Mutable

- Object.freeze(objInstance)

-ºInmutable JSº
TODO: @[https://facebook.github.io/immutable-js/]
  Arrays:
  .push(...) add an object to the current array
  .concat(...) returns a new array with the added object, doesn't modify the 
  original array


ºDate and Timeº @[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date] var date1 = new Date('December 17, 1995 03:24:00'); // Sun Dec 17 1995 03:24:00 GMT... var date2 = new Date('1995-12-17T03:24:00'); // Sun Dec 17 1995 03:24:00 GMT... console.log(date1 === date2); // expected output: false; console.log(date1 - date2); // expected output: 0 var date3 = Date.now()
ºStringsº - String object are immutable. - methods do NOT alter the original String, but return new ones. s = "1234" s.length // 4 s.charAt(1) // 2 s.charCodeAt(index) // 49 (Unicode Code for "1") String.concat(s1,..)// Joins Strings, returns copy of result. s.indexOf(2) // 2 (1st occurrence) , -1 if doesn't exists s.lastIndexOf(2) // 2 " s.match(/^1/) // ["1"] (returns matching array) s.replace(/^./,"A") // "A234" s.search(/2.4/) // 1 position of 1st match. slice(startPos, endPos): Extracts the part of the String between the specified start and end positions. TODO split(token): Splits the String into an array of subStrings, using the specified token as the delimiter. TODO substr(startPos, numChars): Extracts a subString from the String, beginning at the start position through the specified number of characters. subString(startPos, endPos): Extracts a subString from the String, between the specified start position and end position. toLowerCase(): Returns the String in all lowercase characters. toUpperCase(): Returns the String in all uppercase characters. trim(): Returns the String without any of the whitespace at either end. valueOf(): Returns the primitive value of the String. String.fromCharCode() // Converts Unicode → characters. ECMAScript 6.0: Template strings support string interpolation. Example: let a="A" let t = `a: ${a}` console.log(t) "a: A"
Introduction++
"OOP"
    function Message (subject, recipient, content){
      this.subject = subject;
      this.recipient = recipient;
      this.content = content;
    }
    Now that we have created a Message function we define its ".prototype" to complete the "Class":
    Message.prototype = {
      constructor: Message,   ← !!

      sendMessage: function(){
        console.log('Sending message to ' + this.recipient);
      },

      show : function(){
        console.log('To:' + this.recipient + 'Subject: ' + this.subject + 'Message:' + this.content);
      }
    };

    The complete definition of the Message object is now in one place, and the same methods are available to all
    instances of Message we create. Each message created can have its own instance properties that are passed through to
    the constructor.

    var workMessage = new Message('Work complete'', 'boss@mycorp.com', 'My work is done here');
    var socialMessage = new Message('Time to go out', 'friend@gmail.com', 'Finished work now.');
    workMessage.send();
    socialMessage.send();
    ________________________
    var F = function() {};// This is a function object.
    var p = F.prototype; // prototype object associated.
    var c = p.constructor; // function associated with pro.

    c === F
    true: F.prototype.constructor==F for any function
    ________________________
    Method overide:

    Dog.prototype.talk = function(){
     console.log('The dog says');
     Animal.prototype.talk.call(this);
    }

    When calling the parent object method earlier, we needed to know that the
    parent was Animal.prototype. We can make the code more elegant by keeping a
    record of what the parent object is.

    Dog.prototype = new Animal();
    Dog.prototype.constructor = Dog;
    //define the parent property
    Dog.prototype.parent = Animal.prototype;
    Dog.prototype.talk = function(){
    console.log('The dog says'); //use the parent property to invoke the method
    this.parent.talk.call(this);
    }
    __________________
    Namespaces:
    var com = com || {};
    com.apress = com.apress || {};
    com.apress.chapterone = com.apress.chapterone || {};
    com.apress.chapterone.Message = function Message(...) {...}

    The usage of a Message object will now need to respect the namespace as follows:

    var myMessage = new com.apress.chapterone.Message(...);
Webpack assets bundle
"webpack: module ""loader""

(vs require.js vs browserify)

scripts.js:
require('../lib/module1.js') // sync run
____________________
"Install webpack (into the project & globally):
$ npm install -g webpack
$ npm init
$ npm install --save webpack
____________________
Configure webpack project
$ vim webpack.config.js
var debug = process.env.NODE_ENV !== ""production"";
var webpack = require('webpack');

module.exports = {
  context: __dirname,
  devtool: debug ? 'inline-sourcemap' : null,
  entry: './js/scripts.js',
  output: {
    path: __dirname + '/js',
    filename: 'scripts.min.js'
  },
  plugins: debug ? [] : [
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.optimize.UglifyJsPlugin({
        mangle: false, sourcemap: false
    })
  ],
};
_____________________
Run webpack: (generates scripts.min.js)
$ NODE_ENV=development webpack
$ NODE_ENV=production  webpack
Compressing JS
We use uglify for this purpose like shown in the next script snipet:

rm -rf packaging/html # Avoid packaging old stuff by mistake

if [ -d compiledJS ];  then
    rm -rf compiledJS
    if [ $? != 0 ]; then
        echo "couldn't remove compiledJS"
        exit 1
    fi
fi
mkdir compiledJS
cp -R html compiledJS/
rm -rf compiledJS/html/html_tests

echo "debug: $BASEDIR/compiledJS/html/services"
cd $BASEDIR/compiledJS/html/services || exit 1

find ./ -name "*js" -type f | grep -v "media" | while read f ; do
    uglifyjs --max-line-len 80 -o tmp.js ${f} 1˃/dev/null
    mv tmp.js ${f} 1˃/dev/null
Parcel Packet bundler
(Simpler to use that WebPack)
REF: https://hack.aragon.org/docs/tutorial.html

""" Since we're importing Node.js modules in our front-end, we need a build
script. For this, we opted to use parcel because it has zero config, but you
can use your favorite bundler.

Let's install Parcel first:
$ npm i parcel-bundler -D

Next, let's add the build script to package.json:

{
  // ...
  "scripts": {
    "build": "parcel build app/script.js -d dist/ ⅋⅋ parcel build app/index.html -d dist/ --public-url '.'"
  }
  // ...
}

You can now build the front-end of your app by running npm run build.
Async Programming

Convert callback API to Promise API
When a function returns a promise, modern browsers let us use the new await
keyword. This new keyword (which will be familiar for C# developer) let you
create asynchronous code like it would be synchronous:

function setPromiseTimeout() {
    return new Promise(function(callbackOK, callbackError) {
        setTimeout(callbackOK, 500)
    });
}

async function start() {
   for (idx=0; idx˂3; idx++) {  // ← loops will be very-difficult/imposible with Callbacks
      await setPromiseTimeout()
      console.log(idx)
   }
}
start();

RºWARN!!!º:
  Promise can not throw since that would
  client code using the promise to both " }cath{" and ".catch(...)"

Concurrency
WebWorkers
- http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#concept-transferable-neutered
   In order to enable repeated transfer of large amounts of data between Web
  Workers [WEBWORKERS], ArrayBuffer implements the Transferable interface [HTML
  ]. This section defines the behavior of ArrayBuffers and views under the
  structured cloning [HTML] and transfer algorithms.

- https://serviceworke.rs/
  The Service Worker Cookbook is a collection of working, practical examples
  of using service workers  in modern web apps.
Service workers
(See also)
- key functionality for Progressive Web Apps, allowing them to be ‘installed’,
  send relevant push notifications, and load quickly even on flaky networks.
- Other commonly touted benefits include reducing bandwidth.
- (REF: engineering blog post)

 º"""Service workers is probably the single most powerful       º
 ºAPI added to the web platform recently. It gives you access toº
 ºa programmable proxy in JavaScript land. You can do anything  º
 ºyou want with each request made and the response received by  º
 ºthe browser - cancel the request, re-route it, modify the     º
 ºresponse(in some cases), cache it, etc."""                    º

- Some of the applications highlighted included client side load balancing,
  image optimization per device and bandwidth conditions, and even advanced image decoding
- Workbox library allows to
  rapidly integrate a number of common Service Worker functionality such as precaching, runtime
  caching, request routing, background sync, and more.
- It is designed to be fully async; as a consequence, APIs such as synchronous
  XHR and localStorage can't be used inside a service worker.
Improving Performance via Workers
@[https://www.infoq.com/news/2019/08/postMessage-performance-study/]
Debugging
Basic_Debugging
ºPlay with ajax requests (Firefox only?)º
    Go to inspector → network tab → RightClick on request
    → choose Edit and Resend: Now you can change anything
    you want: header, params, ... and resend.

- "debugger" keyword: pause in code just when console is open

- dump object to string:ºJSON.stringify(window.document)º

  To avoid cicular dependencies problems redefine stringify like:
  REF: @[https://stackoverflow.com/questions/11616630/how-can-i-print-a-circular-structure-in-a-json-like-format]
  // Demo: Circular reference
  JSON.stringifySec = function (circ) {
    cache = []
    result = JSON.stringify(circ, function(key, value) {
        if (typeof value === 'object' ⅋⅋ value !== null) {
            if (cache.indexOf(value) !== -1) {
                // Duplicate reference found, discard key
                return
            }
            // Store value in our collection
            cache.push(value)
        }
        return value
    })
    cache = null
    return result
  }
  var circ = {};
  circ.circ = circ;
  JSON.stringifySec (circ)






- Print the calling function in the called function:
  var f1 = function(...){
     console.warn("Called from:"+ arguments.callee.caller.toString());
     ...

- Quickly access elements in the console:
   $(‘css-selector’) will return the first match of CSS selector.
  $$(‘css-selector’) will return all of them.
  }
-Dump async func.chain
("stack-trace")
@[https://stackoverflow.com/questions/40300996/nodejs-is-is-possible-to-show-the-stack-trace-of-a-calling-async-function]
@[https://gist.github.com/lll000111/3d6a53da4d53beb909189793c7631ba6]

BºUPDATE 2019-08-04º: In Node.js 12, Async Stack Traces come out of the box
with flag '--async-stack-traces'
@[https://medium.com/@nodejs/introducing-node-js-12-76c41a1b3f3f]

// @flow
'use strict';

// Note: Promise.reject() can be used to trigger the stack-trace creation
const wait = delay =˃ new Promise(resolve =˃ setTimeout(() =˃ resolve(), delay));

const fnError = async () =˃ {
    await wait(1);
   ºthrow new Error('Ooohhhh my god, this went wrong!');º
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   Some deeply nested (in the actual call hierarchy)
   asynchronous function that throws an error.
};

HOW-TO:
Alternative 1:
  STEP 1: ºAlways catch errorsº, never return the promise directly
          (because then you cannot add the local stack trace)

  STEP 2: Add a locally generated stack trace to the one already
          existing on the error object

  const fn2 = async () =˃ {
      let result;
      try {
          result = await fnError();
      } catch(err) {                         // ← STEP 1
          err.stack +=º(new Error()).stackº; // ← STEP 2
          throw err;
      }

      // Do stuff with result

      return result;
  };

Alternative 2: (Syntax alternative)
  STEP 1: Instead of try/catch use a promise-method based version,
          which has the advantage to allow assignment to "const":
       const result = fnError()
                      º.catchº(                // ← STEP 1
           err =˃ {
             err.stack += (new Error()).stack; // ← STEP 2 doesn't change
             throw err;
           }
       );

Callning fn2 asyncrhonously from fn1 and dumping "async" stack-trace

// stack "Level 1"
const fn1 = async () =˃ {
    try {
        return await fn2();
        ^^^^^^^^^^^^^^^^^^^
RºWARNº:if something more complex than just retuning is executed the
        err can be different to the fn1 async err and the async stack trace
        will be "false"
    } catch(err) {
        err.stack += (new Error()).stack;
        throw err;
    }
};

// stack "Level 0"
const fn0 = async () =˃ {
    try {
        return await fn1();
    } catch(err) {
        err.stack += (new Error()).stack;
        throw err;
    }
};

fn0().catch(console.error);

Web Console, Advanced tricks:
- REF 1: (TODO)
  @[https://raygun.io/blog/2015/06/useful-javascript-debugging-tips-you-didnt-know/]
(Chrome only?)
Display object as tables in the console:
  console.table(animals);

Dump stack trace for a function:
  this.funcZ = function(){
    console.trace('trace car'); // ← show the stack trace up to this function
  }

Quick find a function to debug:
  debug(car.functY)   Chrome only?
  (not the same that console.debug)

monitor(funct1); Every time the function is
  called it will be logged with the values
  that was passed in


Quick find your DOM elements:
  Mark a dom element in the elements panel and
 use it in your console. Chrome inspector keeps the last 5 elements in its
 history, so the last marked element will be displayed with $0, second to last
 marked element $1 and so on.

Quick find a function to debug:  debug(car.functY)  -Note: is not the same that console.debug-
FlowType: Find
type-infer.bugs

Flow uses type inference to find bugs even without type annotations. It
precisely tracks the types of variables as they flow through your program.

Flow is designed for JavaScript programmers. It understands common JavaScript
idioms and very dynamic code.

Flow incrementally rechecks your changes as you work, preserving the fast
feedback cycle of developing plain JavaScript.
Black Block Script
while debugging
CHROME:                                                      FIREFOX:
– Alt 1. inspector → source → Right click                    Inspector → Debugger → Mark scriptto black list →
  the file to black list and choose black box script.        Click on the eye in the very bottom left corner.
– Alt 2. Open up settings view → Click                       https://hacks.mozilla.org/2013/08/
  "manage framework black boxing" → write a regexp in          new-features-of-firefox-developer-tools-episode-25/
  popup to blackbox, for example, the entire vendor folder.
  https://developer.chrome.com/devtools/docs/blackboxing
DOM-INSPECTING
Quickly access elements in the console:
  $(‘css-selector’)  returns first match of CSS selector
  $$(‘css-selector’) returns all matches
SOURCE MAPPING
http://blog.getsentry.com/2015/10/29/debuggable-javascript-with-source-maps.html
source maps are JavaScript’s version of debug symbols: Include with:

//# sourceMappingURL=/path/to/app.min.js.map

modern JavaScript transpilers (TypeScript,...) has a command-line option for generating the associated source map.

source map example:
{
  version : 3,  // version of source map spec (should be 3)
  file: "app.min.js", // generated filename associated to
  sourceRoot : "",    // all sources are relative to it (opt)
  sources: ["foo.js", "bar.js"], // URLs to original  files
  names: ["src", "maps", "are"], // variable/method names found in your code
  mappings: "AAgBC,SAAQ,CAAEA"   // base64Enc VLQ values source code mappings
}
Fiddler Debug Proxy
Fiddler. HTTP proxy debugger:
- Allows to replace remote html/css/... with local one.
  Very useful when deploying to remote server can be "slow" due
  to CI constrains.
- Allows to see the "total page weight"  HTTP caching and compression at a glance

  Video Tutorial: http://www.youtube.com/watch?v=TP_5JYatlNQ
Functional Testing
Mocha
@[https://mochajs.org/]
Mocha is a feature-rich JavaScript test framework running on Node.js
and in the browser, making asynchronous testing simple and fun.
Mocha tests run serially, allowing for flexible and accurate
reporting, while mapping uncaught exceptions to the correct test
cases. Hosted on GitHub.
Selenium
test Automation
@[http://docs.seleniumhq.org/]

- http://code.tutsplus.com/tutorials/headless-functional-testing-with-selenium-and-phantomjs--net-30545

- http://docs.seleniumhq.org/
http://docs.seleniumhq.org/projects/ide/
http://stackoverflow.com/search?q=selenium

Selenium automates browsers. That's it! What you do with that  power is
entirely up to you. Primarily, it is for automating web applications for
testing purposes, but is certainly not limited to just that. Boring web-based
administration tasks can (and should!) also be automated as well.
Selenium has the support of some of the largest browser vendors who have
taken (or are taking) steps to make Selenium a native part of their browser
. It is also the core technology in countless other browser automation tools
, APIs and frameworks.
Python scripted
webkit engine
@[https://github.com/jeanphix/Ghost.py]
Behavior-Driven
JS testing
@[https://jasmine.github.io/]
Profiling
es5 vs es6 degradation
Up to 2500x decrease!!!
@[http://incaseofstairs.com/six-speed/]
YSlow
YSlow analyzes web pages and why they're slow
based on Yahoo!'s rules for high performance web sites

Feature highlights
- Grades web page based on one of three predefined ruleset
  or a user-defined ruleset;
- It offers suggestions for improving the page's performance;
- Summarizes the page's components;
- Displays statistics about the page;
- Provides tools for performance analysis, including Smush.it™
  and JSLint.
Mozilla Perf.Tool
The Performance tool gives you insight into your site's general responsiveness
, JavaScript and layout performance. With the Performance tool you create a
recording, or profile, of your site over a period of time. The tool then
shows you an overview of the things the browser was doing to render your site
over the profile, and a graph of the frame rate over the profile.
Javascript Alternatives
Elm
 └BºNo Runtime Exceptionsº
    Elm uses type inference to detect corner cases and give friendly 
    hints.
     NoRedInk switched to Elm about two years ago, and 250k+ lines 
    later, they still have not had to scramble to fix a confusing runtime 
    exception in production. 
    Ex:
      -- TYPE MISMATCH ---------------------------- Main.elm
      The 1st argument to `drop` is not what I expect:
      8|   List.drop (String.toInt userInput) [1,2,3,4,5,6]
                      ^^^^^^^^^^^^^^^^^^^^^^
                 This `toInt` call produces:
                 Maybe Int
                 But `drop` needs the 1st argument to be:
                 Int
      Hint: Use Maybe.BºwithDefaultº to handle possible errors.

 └BºGreat Performanceº

 └BºEnforced Semantic Versioningº
    automatically detecting changes thanks to its type system.
    We use that information to guarantee that every single Elm package
    follows semantic versioning precisely. BºNo surprises in PATCH releasesº

    $ Bºelm diffº Microsoft/elm-json-tree-view 1.0.0 2.0.0
    This is a MAJOR change.
    ---- JsonTree - MAJOR ----
        Changed:
          - parseString : String -> Result String Node
          + parseString : String -> Result Error Node
    
          - parseValue : Value -> Result String Node
          + parseValue : Value -> Result Error Node

 └BºSmall Assetsº
    (faster page loads)
    Just compile with the --optimize flag, let compiler do the rest.
    No complicated set up.

 └BºJavaScript Interopº
TypeScript
@[https://www.typescriptlang.org/]
AAA
W3C OpenSocial
@[http://www.w3.org/blog/2014/12/opensocial-foundation-moves-standards-work-to-w3c-social-web-activity/]
Firefox Web Auth API
@[https://www.infoq.com/news/2018/05/firefox-web-authentication-api]
Facebook login
jQuery plugin
@[http://garyrafferty.com/2013/08/20/Stupidly-Simple-Facebook-Login-JQuery-Plugin.html]
˂html˃
˂head˃
˂script type='text/javascript' src='jquery.js'˃˂/script˃
˂script type='text/javascript' src='flogin.js'˃˂/script˃
˂script type='text/javascript'˃
$(function() {
  $('#login').facebook_login({
    appId: 'YOUR-FACEBOOK-APP-ID',
    endpoint: '/sessions/new',   # where to POST the response to
    onSuccess: function(data) {},# ← usually redirect
    onError: function(data) {}   #
    permissions: 'read_stream'   # ← OAuth permissions
                                 #   (default to email)
  });
});
˂/script˃
˂/head˃
  ˂a href='#' id='login'˃Login with Facebook˂/a˃
˂/body˃
˂/html˃
Decentralized Indentifiers (DID) Summary
- blockchain-agnostic spec implementation.
@[https://github.com/decentralized-identity/universal-resolver]
Supports DIDs on Sovrin, BTCR, uPort, Jolocom, Veres One,
ERC-725, Blockstack, IPFS, and DNS via community-contributed
drivers built on top of the Universal Resolver.

- ºUniversal DID Operationsº
@[https://github.com/WebOfTrustInfo/rwot8-barcelona/blob/master/topics-and-advance-readings/Universal-DID-Operations.md]
 Markus Sabadello (markus@danubetech.com),Nader Helmy(nader.helmy@danubetech.com),
 Vienna, 8th February 2019

All DID methods commonly share 4 operations:
Registar (Counterpart to "Resolver")
- Create: (All params are optional)
  create(method, options, did-doc, wallet)→ state, metadata
         ^       ^         ^       ^  
         │       │         │       └  storage for existing/generated Priv.Keys
         │       │         │          (text file, wallet API endpoint,
         │       │         │           local wallet, etc.)
         │       │         └  new DID Document
         │       └ mainnet, testnet,...
         └───── sov, btcr, v1, ...
- Update: 
  First, ownership over DID is verified
  update(identifier, options, wallet, did-doc/-doc-op) 
                                      ^
                                      └ replace existing doc or
                                        incremental update to existing Doc
                                        - add-service
                                        - remove-service
                                        - add-publickey
                                        - remove-publickey

- Revoke:

  First, ownership over DID is verified
  revoke(identifier, options, wallet) → state, metadata

- CheckOperation:
  checkOperation(jobid     ) → state, metadata
  checkOperation(identifier) → state, metadata

At any time, we can query the Registrar to find the state of a 
previous DID operation, or the last known state of the identifier.

jobid
    returned as part of the state object
    generated by the Registrar



Resolver: Read operations
- Resolve: straightforward implementation:
    - no authentication/secrets required.
    - atomic operation
    - web friendly. 
   
Registar
states
---------
finished ( DID , wallet {optional}
action   ( jobid, actiontype )
wait     ( jobid, waittype ) 
fail     ( error message )

metadata
--------
operation metadata  : duration
method metadata     : method-specific hash,
                      token balance


Example states for btcr DID:
{                                {
º"state" : "action"º             º"state" : "wait"º
 "jobid": "aa1231",               "jobid": "aa1231",
 "action": "fundingrequired",     "action": "confirmingtransaction",
 "bitcointaddress": "3QA21f...",  "waittime": "100000"             ,
 "satoshis" : "111222"           }
}

{                                {
º"state" : "finished"º           º"state" : "failed"º
 "jobid": "aa1231",               "jobid" : "aa1231",
 "identifier": "did:btcr:1a..."   "reason": "network_unavailable"
}                                }


w3c spec @[https://w3c.github.io/did-core/] (revision 2020-01-22) Targets: - provide verifiable, (D)ecentralized (D)igital (I)dentity. independent of any centralized registry/Cert-Authority. DIDs:ºURLs that relate a DID subject to a DID document º ºallowing trustable interactions with that subject.º - component of larger system like Verifiable Credentials ecosystem ########### # DID UML # ########### ┌───────────────────────────────┐ │DID Registry ┌──┐│ │(Registar) ─┼─ ││ │ ─┼─ ││ │ └──┘│ ┌───────────────────────┐ │mediates creation, verification│ │DID Resolver ┌──┐│ │updating, and deactivation of │ │ ─┼─ ││ │decentralized identifiers. │ │Retrieves DID-doc ─┼─ ││ │"type of" verifiable data │ │for a given DID └──┘│ │ registry. │ │ │ └───────────────────────────────┘ └───────────────────────┘ ↓ DID Controller 1←→1+ DID ┌────────→1 DID document ────────────── ↑ ─── │ ─────────────── (human|...)entity │ URL 1←──┘ + data set describing the DID-subject or a group of │ + 0+ cryptographic keys entities, in │ + mechanisms/verify methods(pub.keys,...) control of a │ that DID subject can use to authenticate DID and/or │ itself and prove their association DID document. │ with the DID. ┌─ SERVICE ENDPOINT DID subject (opt) │ + 0+ attributes/claims describing the │ ──────────────── ┌──────────────────┘ subject. │ ─ represented by URI, UUID,... ─ As many DIDs as necessary to respect + graph─based data structures │ ─ network address at which a service entity's desired separation of typically expressed using [JSON─LD]. │ operates on behalf of a DID subject. identities,personas and contexts in + 0+ service endpoints enabling ←───┘ Exs services include: the everyday sense of these words. trusted interactions with the ·ºdiscovery servicesº ─ Different DIDs can be needed to DID subject. ·ºsocial networksº support different DID methods ·ºfile storageº and different cryptographic schemes ·ºverifiable claim repositoryº Non-normative DID example: Non-normative (self-managed) DID-document example: "did:btcr:1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2" "did:id_of_DID_method:DIDI_method_specific_id" Minimal self-managed DID document └─────────────────────┬──────────────────────┘ { "@context": "https://www.w3.org/ns/did/v1", resolves to a DID document with info like: "id": "did:id_of_DID_method:DIDI_method_specific_id", - ways to cryptographically authenticate "authentication": [{ the entity in control of the DID. "id": "did:id_of_DID_method:DIDI_method_specific_id#keys-1", - services that can be used to interact "type": "RsaVerificationKey2018", with the entity. "controller": "did:id_of_DID_method:DIDI_method_specific_id", URI scheme [RFC3986] "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n" DID URL: }], DID "service": [{ + 0|1 DID path (/..path...) "id":"did:id_of_DID_method:123456789abcdefghi#vcs", + 0|1 DID query (?..query..) "type": "VerifiableCredentialService", + 0|1 DID fragment(#..fragment..): "serviceEndpoint": "https://example.com/vc/" }] } ºSPEC AIMSº DID-methods (separate spec) ─────────── ─────────── - Define Generic DID scheme: - CRUD DID/DID-document mechanisms - Define Generic set of DID-documents operations (Deletion → deactivation) - Define conformance requirements for a - Apply to (D)IDs in centralized/federated/Decen. DID-method-spec. did:btrc:21tDAKCERh95uGgKbJNHYp;foo:bar=high ← Inmutable 1 ←→ 1 subject ───┬──── non-reusable ┌──────────────────────────────────────┘ generic DID parameter names. hl resource hash of the DID document to add integrity protection, as specified in [HASHLINK]. ------------------------------------------------------------------------ service Identifies a service from the DID document by service ID. ------------------------------------------------------------------------ version-id Identifies a specific version of a DID document to be resolved (the ------------------------------------------------------------------------ version ID could be sequential, or a UUID, or method-specific). Note that this parameter might not be supported by all DID methods. ------------------------------------------------------------------------ version-time Identifies a certain version timestamp of a DID document to be resolved. That is, the DID document that was valid for a DID at a certain time. Note that this parameter might not be supported by all DID methods. The exact processing rules for these parameters are specified in [DID-RESOLUTION]. ------------------------------------------------------------------------ 6.3 Public Keys A DID document MAY include a publicKey property. DID document.publicKey (optional) property value MUST public_key[]. ┌ RsaVerificationKey2018 ---------- ├ Ed25519VerificationKey2018 URI id ├ Ieee2410VerificationKey2018 Pub Key Type type ──┼ ... DID controller ←────── Authentication used to prove its specific pub.key properties association with a DID. from the Linked Data (10.2 Binding of Identity ) Cryptographic Suite Registry. A DID-document MAY contain revoked keys, by adding/refering to the revocation information for the key (revocation list,...). Public keys: expressed in either - JSON Web Key (JWK) format using the publicKeyJwk property - one of the formats listed in next table below. (table currently assume PEM and Base58) (it might change to base64url and/or base16) | Key Type Support } -----------+------------------------------------------------------------------------------ | RSA | JWK or Privacy Enhanced Mail (PEM) encoding | | } -----------+------------------------------------------------------------------------------ | ed25519 | Ed25519 public key values MUST either be encoded as a JWK or be | | encoded as the raw 32-byte public key value in Base58 Bitcoin format using the | | publicKeyBase58 property. } -----------+------------------------------------------------------------------------------ | secp256k1- | Secp256k1 Koblitz public key values MUST either be encoded | koblitz | as a JWK or be encoded as the raw 33-byte public key value in Base58 Bitcoin | | format using the publicKeyBase58 property. } -----------+------------------------------------------------------------------------------ | secp256r1 | Secp256r1 public key values MUST either be encoded as a JWK or be | | encoded as the raw 32-byte public key value encoded in Base58 Bitcoin format | | using the publicKeyBase58 property. } -----------+------------------------------------------------------------------------------ | Curve25519 |Curve25519 (also known as X25519) public key values MUST either be | | encoded as a JWK or be encoded as the raw 32-byte public key value in Base58 | | Bitcoin format using the publicKeyBase58 property. \_-----------^------------------------------------------------------------------------------ ºCaching and expiration of the keys in a DID document is entirely theº ºresponsibility of DID resolvers and other clients.º DID_document.authentication: (Optional) - Authentication is separate from authorization: - DID controllers might wish to enable others to update their DID document. Ex: { "@context": "https://www.w3.org/ns/did/v1", "id": "did:id_of_DID_method:123456789abcdefghi", º"authentication":º[ "did:id_of_DID_method:123456789abcdefghi#keys-1", "did:id_of_DID_method:123456789abcdefghi#biometric-1", { "id": "did:id_of_DID_method:123456789abcdefghi#keys-2", "type": "Ed25519VerificationKey2018", "controller": "did:id_of_DID_method:123456789abcdefghi", "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV" } ], } ºAuthorization and Delegationº - Operation-Authorization: - Operation-Delegation: ºSecurity Considerationsº Each DID method MUST define how authorization and delegation are implemented, including any necessary cryptographic operations. There are at least two suggested methods for implementing Authorization and Delegation, which may be layered: A DID registry could implement a coarse-grained controller pattern by enabling DID documents to express the DID of another DID controller that controls it, or additionally, A DID registry could implement a capabilities-based approach enabling further fine-grained control of authorization and delegation. Example 15: DID document with a controller property { "@context": "https://www.w3.org/ns/did/v1", "id": "did:id_of_DID_method:123456789abcdefghi", "controller": "did:id_of_DID_method:bcehfew7h32f32h7af3", "service": [{ "type": "VerifiableCredentialService", "serviceEndpoint": "https://example.com/vc/" }] }
Styling
CSS Selectors
By Coordinate
    lector                    Example                  Example description
    .class                    .intro                   Selects all elements with class="intro"
    #id                       #firstname               Selects the element with id="firstname"
    º                         º                        Selects all elements
    element                   p                        Selects all ˂p˃ elements
    element,element           div, p                   Selects all ˂div˃ elements and all ˂p˃ elements
    element element           div p                    Selects all ˂p˃ elements inside ˂div˃ elements
    element˃element           div ˃ p                  Selects all ˂p˃ elements where the parent is a ˂div˃ element
    element+element           div + p                  Selects all ˂p˃ elements that are placed immediately after ˂div˃ elements
    element1~element2         p ~ ul                   Selects every ˂ul˃ element that are preceded by a ˂p˃ element
    [attribute]               [target]                 Selects all elements with a target attribute
    [attribute=value]         [target=_blank]          Selects all elements with target="_blank"
    [attribute~=value]        [title~=flower]          Selects all elements with a title attribute containing the word "flower"
    [attribute|=value]        [lang|=en]               Selects all elements with a lang attribute value starting with "en"
    [attribute^=value]        a[href^="https"]         Selects every ˂a˃ element whose href attribute value begins with "https"
    [attribute$=value]        a[href$=".pdf"]          Selects every ˂a˃ element whose href attribute value ends with ".pdf"
    [attributeº=value]        a[hrefº="w3schools"]     Selects every ˂a˃ element whose href attribute value contains the substring "w3schools"
    :active                   a:active                 Selects the active link

By Relative Coordinate
    :first-of-type            p:first-of-type          Selects every ˂p˃ element that is the first ˂p˃ element of its parent
    :last-of-type             p:last-of-type           Selects every ˂p˃ element that is the last ˂p˃ element of its parent
    :not(selector)            :not(p)                  Selects every element that is not a ˂p˃ element
    :first-child              p:first-child            Selects every ˂p˃ element that is the first child of its parent
    :last-child               p:last-child             Selects every ˂p˃ element that is the last child of its parent
    :nth-child(n)             p:nth-child(2)           Selects every ˂p˃ element that is the second child of its parent
    :nth-last-child(n)        p:nth-last-child(2)      Selects every ˂p˃ element that is the second child of its parent, counting from the last child
    :nth-last-of-type(n)      p:nth-last-of-type(2)    Selects every ˂p˃ element that is the second ˂p˃ element of its parent, counting from the last child
    :nth-of-type(n)           p:nth-of-type(2)         Selects every ˂p˃ element that is the second ˂p˃ element of its parent
    :only-of-type             p:only-of-type           Selects every ˂p˃ element that is the only ˂p˃ element of its parent
    :only-child               p:only-child             Selects every ˂p˃ element that is the only child of its parent
    :root                     :root                    Selects the document's root element
    ::after                   p::after                 Insert content after every ˂p˃ element
    ::before                  p::before                Insert content before the content of every ˂p˃ element
    :empty                    p:empty                  Selects every ˂p˃ element that has no children (including text nodes)
    ::first-letter            p::first-letter          Selects the first letter of every ˂p˃ element
    ::first-line              p::first-line            Selects the first line of every ˂p˃ element

By From StatusA
    :checked                  input:checked            Selects every checked ˂input˃ element
    :disabled                 input:disabled           Selects every disabled ˂input˃ element
    :enabled                  input:enabled            Selects every enabled ˂input˃ element
    :valid                    input:valid              Selects all input elements with a valid value
    :invalid                  input:invalid            Selects all input elements with an invalid value
    :read-only                input:read-only          Selects input elements with the "readonly" attribute specified
    :read-write               input:read-write         Selects input elements with the "readonly" attribute NOT specified
    :required                 input:required           Selects input elements with the "required" attribute specified
    :in-range                 input:in-range           Selects input elements with a value within a specified range
    :out-of-range             input:out-of-range       Selects input elements with a value outside a specified range
    :optional                 input:optional           Selects input elements with no "required" attribute
    :focus                    input:focus              Selects the input element which has focus

Links
    ::selection               ::selection              Selects the portion of an element that is selected by a user
    :target                   #news:target             Selects the current active #news element (clicked on a URL containing that anchor name)
    :visited                  a:visited                Selects all visited links
    :link                     a:link                   Selects all unvisited links

Others
    :hover                    a:hover                  Selects links on mouse over
    :lang(language)           p:lang(it)               Selects every ˂p˃ element with a lang attribute equal to "it" (Italian)
CSS variables
https://www.infoq.com/news/2020/06/css-variables-design-systems/
Why We Don't Use a CSS Framework
css calc
calc support in browsers:
@[http://caniuse.com/#feat=calc]

css calc alternative:
@[http://stackoverflow.com/questions/16034397/css-calc-alternative]
  box-sizing: content-box|border-box|initial|inherit;
  Property     Values
  Value        Description
  content-box  Default. width and height (and min/max) includes only the content. Border/padding/margin not included
  border-box   The width and height properties (and min/max properties) includes content, padding and border, but not the margin
  initial      Sets this property to its default value. Read about initial
  inherit      Inherits this property from its parent element. Read about inherit"
CSS3 3D animation
- http://codepen.io/dehash/pen/Bfory
  CSS3 3D image animation
CSS Layout
display:=
   none
   inline: render in same line than parent
   block: mode block render (a box in its own line)
   inline-block: in-line box. It can be assigned a size (width, height) and it can have
          margin and padding.
   list-item: render as a list
   table, inline-table, table-header-group, table-footer-group, table-row, table-row-group,
   table-column, table-column-group, table-cell, table-caption

float := left | right (only for inline|inline-block)

ºclearº
  The clear property is used to control the behavior of floating elements.
  Elements after a floating element will flow around it. To avoid this, use the
  clear property.
  The clear property specifies on which sides of an element floating elements
  are not allowed to float. Example:
  div {    clear: left;  }
CSS Image Mask
Ref: http://www.html5rocks.com/en/tutorials/masking/adobe/

TODO: Luminance, Alpha,

img {
  clip-path: url(#clipping);
}

˂svg˃
  ˂defs˃
    ˂/clipPath id="clipping"˃
      ˂circle cx=284 cy=213 r=213 /˃
    ˂/clipPath˃
  ˂/defs˃
˂/svg˃

˂img src=image.jpg width=568˃
Animated Clipping:
img:hover {
  clip-path: polygon(0px 208px, 146.5px 207px, 147px 141.2px, ...);
  animate: star 3s;
}

@keyframes star {
  0% {
    clip-path: polygon(0px 208px, 146.5px 207px, 147px 141.2px, ...);
  },
  100% {
    clip-path: polygon(0px 208px, 146.5px 207px, 147px 141.2px, ...);
  }
}
CSS Flex/Grid
- http://flexbox.malven.co/
- http://grid.malven.co/
CSS3 Animations
Ref @[http://css3.bradshawenterprises.com/]

#id_of_element {
· · -webkit-transition: all 1s ease-in-out;
· · -moz-transition: all 1s ease-in-out;
· · -o-transition: all 1s ease-in-out;
· · transition: all 1s ease-in-out;
}

CSS:

@-webkit-keyframes dash {
 70%,80% {
 stroke-dashoffset: 0;
 fill-opacity: 0;
 }

 85% {
 fill-opacity: 0;
 stroke-opacity: 1;
 }

 95% {
 stroke: #17739D;
 stroke-dashoffset: -301;
 stroke-opacity: 0;
 }

 100% {
 fill-opacity: 1;
 stroke-dashoffset: -301;
 }
}

@-ms-keyframes dash {
 70%,80% {
 stroke-dashoffset: 0;
 fill-opacity: 0;
 }

 85% {
 fill-opacity: 0;
 stroke-opacity: 1;
 }

 95% {
 stroke: #17739D;
 stroke-dashoffset: -301;
 stroke-opacity: 0;
 }

 100% {
 fill-opacity: 1;
 stroke-dashoffset: -301;
 }
}

@-moz-keyframes dash {
 70%,80% {
 stroke-dashoffset: 0;
 fill-opacity: 0;
 }

 85% {
 fill-opacity: 0;
 stroke-opacity: 1;
 }

 95% {
 stroke: #17739D;
 stroke-dashoffset: -301;
 stroke-opacity: 0;
 }

 100% {
 fill-opacity: 1;
 stroke-dashoffset: -301;
 }
}

@keyframes dash {
 70%,80% {
 stroke-dashoffset: 0;
 fill-opacity: 0;
 }

 85% {
 fill-opacity: 0;
 stroke-opacity: 1;
 }

 95% {
 stroke: #17739D;
 stroke-dashoffset: -301;
 stroke-opacity: 0;
 }

 100% {
 fill-opacity: 1;
 stroke-dashoffset: -301;
 }
}

#Layer_1 {
 margin-left: auto;
 margin-right : auto;
 top: 50%;
 position: absolute;
 left: 50%;
 margin-left: -65px;
 margin-top: -35px;
}

svg {
 background: #fff;
 display: block;
}

svg * {
 stroke: #666;
 #stroke: #17739D;
 stroke-width: 1;
 fill-opacity: 0;
 stroke-dasharray: 350;
 stroke-dashoffset: 440;
}

svg #bp_svg * {

 -webkit-animation-name : dash;
 -moz-animation-name : dash;
 -ms-animation-name : dash;
 animation-name : dash;

 -webkit-animation-duration: 4s;
 -moz-animation-duration: 4s;
 -ms-animation-duration: 4s;
 animation-duration: 4s;

 -webkit-animation-timing-function : linear;
 -moz-animation-timing-function : linear;
 -ms-animation-timing-function : linear;
 animation-timing-function : linear;

 -webkit-animation-fill-mode : forwards;
 -moz-animation-fill-mode : forwards;
 -ms-animation-fill-mode : forwards;
 animation-fill-mode : forwards;
}
CSS Background
                        background-color: red;

 Image background:      background-image: url(image);
                        background-repeat: repeat | repeat-x  | repeat-y
                        background-position: top | center | bottom

 Gradient:              p1: coordinates gradient start
                            TODO: Firefox(top|left|right|down)
                            Webkit: % horizontal/vertical
                        p2: coodinates gradinet end
                        1: color start
                        c2: color end
                        (-webkit|moz)-gradient(linear, p1, p2, from(c1), to(c2));
                        linear-gradient(p1, c1, c2) no-repeat;

Gradient Vertical:      background: -moz-linear-gradient(top, red, blue);
                        background: -webkit-gradient(linear, 0%, 0%, 0%, 100%, from(red), to(blue));
Gradient Horizontal:    background: -moz-linear-gradient(left, red, blue);
                        background: -webkit-gradient(linear, 0%, 0%, 100%, 0%, from(red), to(blue));
Gradient Radial:        background: -webkit-gradient(radial, p1, r1, p2, r2, from(c1), to(c2));

PostCSS
The end of global CSS

From @[https://www.infoq.com/news/2018/11/ring-1-jetbrains]
"""Many projects have begun embracing PostCSS as a replacement for traditional
CSS preprocessors due to its alignment with modern CSS standards. Ring UI 1.0
follows this approach to support CSS properties and CSS modules, and
deprecates support for the previous usage of SASS, providing better CSS
encapsulation."""
State of CSS (2019)

Fonts/Art Gallery
fontsquirrel
Declaring external font:
@font-face
{
   font-family: MyFontFamilyName; /* "id" to be used in CSS for this font*/
   src: url('my_font.ttf');
   src: url('my_font.eot');
   src: url('my_font.svg');
   src: url('my_font.woff');
}

use:
h1 { font-family: 'MyFontFamilyName'; }
- https://www.fontsquirrel.com/
    Free fonts have met their match. We know how hard it is to find quality
    freeware that is licensed for commercial work. We've done the hard work, hand-
    selecting these typefaces and presenting them in an easy-to-use format. Here
    are some of our favorites:
   http://christ-offer.blogspot.com.es/2011/05/html5css3-fonts-with-font-face.html

- Embedding specific fonts on a web page, traditionally, has been
  accomplished using images.  Though IE 5.0+ allowed you to embed fonts on your
  web page, they needed to be in EOT (Embedded OpenType) format.  Other
  browsers supported TTF (TrueType) and OTF (OpenType) fonts.  IE9 now supports
  TTF, OTF and also WOFF (Web Open Font).  To accomplish the task of embedded
  real fonts into your web pages, use the CSS3 @font-face rule.

- Where to get quality FREE fonts for use in web pages?  FontSquirrel is a
  great place with hundreds of free fonts, including kits that demonstrate how
  to embed and use them into a web page, plus a generator to create your own.
  With the kit, you get the font in all the formats so that you can craft your
  web pages to support all the major
Art Gallery
Icon Gallery:
@[https://github.com/NitruxSA/nitrux-icons]
@[http://tiheum.deviantart.com/art/Faience-icon-theme-255099649]
@[http://tiheum.deviantart.com/art/Faenza-Icons-173323228]
@[http://0rax0.deviantart.com/art/Uniform-Icon-Theme-453054609]
@[http://gnome-look.org/content/show.php/Dalisha?content=166286]
SweetAlert
Replacement for Alert
@[https://github.com/t4t5/sweetalert]
"Random" toolkits
Dojo Toolkit
@[https://dojotoolkit.org]
"Everything you need to build a Web app. Language utilities, UI components,
 and more, all in one place, designed to work together perfectly."
Coil: monetizing the Web
@[https://medium.com/coil/coil-building-a-new-business-model-for-the-web-d33124358b6]
Gtk+ to JS
@[https://www.rollapp.com/]
GTK+ apps ported to Javascript (HTML5)
npx ==
"run once npm install"
https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b

Those of you upgrading npm to its latest version, npm@5.2.0, might notice
that it installs a new binary alongside the usual npm: npx.

Have you ever run into a situation where you want to try some CLI tool, but it
’s annoying to have to install a global just to run it once? npx is great for
that, too. Calling npx  when  isn’t already in your $PATH
will automatically install a package with that name from the npm registry for
you, and invoke it. When it’s done, the installed package won’t be anywhere
in your globals, so you won’t have to worry about pollution in the long-term.
Vue.js
@[https://www.infoq.com/news/2019/01/vue-3-preview]
single-spa
https://single-spa.js.org
- Framework freedom:
  Use multiple frameworks in a single-page application, allowing you to split code
  by functionality and have Angular, React, Vue.js, etc. apps all living in harmony.

- Lazy load applications
  Stand up new apps next to the old one. You write the applications, single-spa makes
  them work together and won't load them until they're needed.

- Front-end microservices
  Combine many small apps, empowering teams to choose their technology. Stay nimble as
  your team, product, and tech stack grows and changes over time.
JS Decorators
@[https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841]
gRPC
Introduction
@[https://grpc.io/]
@[https://en.wikipedia.org/wiki/GRPC]
- Cloud Native Foundation incubating project.
- open source high performance RPC framework cross-platform and multi-language.
- It can efficiently connect services in and across data centers
  with pluggable support for load balancing, tracing, health checking and
  authentication.
- It is also applicable in last mile of distributed computing to connect devices,
  mobile applications and browsers to backend services.
- bidirectional streaming and flow control
- blocking or nonblocking bindings, and cancellation and timeouts.
- initially developed at Google.
- It uses HTTP/2 for transport, Protocol Buffers as the interface description language,
- Proxy objects can be genrated for many languages with safe type checking
  (when available in the underlying language)

PROTOC + gRPC INSTALLATION STEPS
- STEP 1: ProtoC installation:
   Unpack protoc-3.x...x86_64.zip
from  https://github.com/google/protobuf/releases to /opt/protoc
$ sudo ln -s \
  /opt/protoc/include/google/protobuf \
  /usr/include/google/protobuf
$ sudo ln -s /opt/protoc/bin/protoc \
  /usr/bin/protoc

- Install Node/Python/Go/... tools: REF: @[http://www.grpc.io/blog/installation]
Language |Platform|Command
---------+--------+------------------------------------
Node.js  |All     |npm install -g grpc
         |        |(installs the grpc_node_plugin @
         |        |/usr/(local/)lib/node_modules
         |        |/grpc-tools/bin
---------+--------+------------------------------------
Python   |All     |pip install grpcio
---------+--------+------------------------------------
Ruby     |All     |gem install grpc
---------+--------+------------------------------------
PHP      |All     |pecl install grpc-beta
---------+--------+------------------------------------
Go       |All     |go get google.golang.org/grpc
---------+--------+------------------------------------
Objective|Mac     |Runtime source fetched automatically
-C        |        |from Github by Cocoapods
---------+--------+------------------------------------
C#       |Windows |Install gRPC NuGet package from your
         |        |IDE(V.Studio, Monodevelop, ...)
---------+--------+------------------------------------
Java     |All     |Use our Maven and Gradle plugins
         |        |that provide gRPC with statically
         |        |linked boringssl
---------+--------+------------------------------------
C++      |All     |Currently requires manual
         |        |build and install
Compiling

ºNodeJSº
  (COMMENTED SHELL EXAMPLE TO GENERATE JS PROTOBUF & gRPC SERVICE)
  #!/bin/sh
  set -e # script option. Abort on first error.

  PROTOC=/opt/protoc_v3/bin/protoc # ← PATH to protoc compiler executable
  OUT_DIR="./src/lib/protobuf"

  if [ ! -d ${OUT_DIR} ]; then mkdir -p ${OUT_DIR} ; fi

  # protoc fails if relative path is provided. (2017-01)
  GRPC_NODE_PLUGIN=/usr/local/lib/node_modules/grpc-tools/bin/grpc_node_plugin

  ${PROTOC} \
   --proto_path=../project_proto_definition/   # ← Path to search *proto for
   --js_out=import_style=commonjs,\
                            binary:${OUT_DIR} \# ← JS protobuf output path
  \
   --grpc_out=${OUT_DIR} \                     # ← gRPC(services) output path
   --plugin=protoc-gen-grpc=\                  # ← gRPC service related
            ${GRPC_NODE_PLUGIN} \
   file1.proto


ºJAVAº
@[https://github.com/grpc/grpc-java/blob/master/README.md]
- Gradle protobuf conf:
  apply plugin: 'java'
  apply plugin: 'com.google.protobuf'

  buildscript {
    repositories {
      mavenCentral()
    }
    dependencies {
      classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
    }

  }

- Gradle+grpc conf
compile 'io.grpc:grpc-netty:1.0.1'        non-Android
compile 'io.grpc:grpc-protobuf:1.0.1'
compile 'io.grpc:grpc-stub:1.0.1'

compile 'io.grpc:grpc-okhttp:1.0.1'       Android:
compile 'io.grpc:grpc-protobuf-lite:1.0.1'
compile 'io.grpc:grpc-stub:1.0.1'

...
protobuf {
  protoc { artifact = "com.google.protobuf:protoc:3.1.0" }
  plugins {
    grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.0.1' }
  }
  generateProtoTasks { all()*.plugins { grpc {} } }
}
gRPC PROTOBUF
EXCEPTION HANDLING
C⅋P FROM @[http://stackoverflow.com/questions/38810657/exception-handling-in-grpc]
Q: I have a server written in Java and client written in PHP.
   How can client catch exception from server if anything goes wrong?
   I can't find anything about exception handling in gRPC documentation.


A: For handled exceptions, call responseObserver.onError(). If you pass in a
   StatusRuntimeException or StatusException (generally created via
   status.asRuntimeException()) the status code and description will be
   communicated to the client.

   Unhandled exceptions within a callback will cancel the RPC and will continue
   propagating the exception (generally leading in an UncaughtExceptionHandler being
   called for the executor).
JAVA
Implementation
Summary

GºJAVA SERVER IMPEMENTATION SUMMARYº                                                                   │ GºJAVA CLIENT IMPEMENTATION SUMMARYº
                                                                                                       │
ºgRPC definitionsº                                                                                     │    ºInitialization codeº
service RouteGuide {                                                                                   │     function getServer() {                             │  if (require.main === module) {
  rpc GetFeature(Point) returns (Feature) {}                                                           │       var server = new grpc.Server();                  │    var routeServer = getServer();
  rpc ListFeatures(Rectangle) returns (stream Feature) {}                                              │       server.addService(services.RouteGuideService, {  │    routeServer.bind('0.0.0.0:50051',
  rpc RecordRoute(stream Point) returns (RouteSummary) {}                                              │         getFeature: getFeature,                        │        grpc.ServerCredentials.createInsecure());
  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}                                        │         listFeatures: listFeatures,                    │    ...
}                                                                                                      │         recordRoute: recordRoute,                      │    routeServer.start();
                                                                                                       │         routeChat: routeChat                           │  });
ºRouteGuideServer.javaº                                                                                │       });                                              │  exports.getServer = getServer;
public class RouteGuideServer                                                                          │       return server;                                   │
  ... initialization code ...                                                                          │     }
   private static class RouteGuideService                                                              │          ┌───────────────────────────────────────────────────┬──────────────────────────────────────────
     ºextends RouteGuideGrpc.RouteGuideImplBaseº                                                       │          │ºSINGLE RESPONSEº                                  │ºSTREAM RESPONSEº
       ...                                                                                             │ ─────────┼───────────────────────────────────────────────────┼──────────────────────────────────────────
         ┌──────────────────────────────────────────────┬────────────────────────────────────────────  │ ºSINGLE º│ feature = blockingStub.                           │ Rectangle request =
         │ºSINGLE RESPONSEº                             │ºSTREAM RESPONSEº                             │ ºREQUESTº│             getFeature(                           │      Rectangle.newBuilder()
─────────┼──────────────────────────────────────────────┼────────────────────────────────────────────  │          │              Point.newBuilder()                   │        .setXXX
ºSINGLE º│  @Override                                   │  @Override                                   │          │               .setXXX()                           │        ...
ºREQUESTº│  public void getFeature(                     │  public void listFeatures(                   │          │               ....                                │        .build();
         │      Point request,                          │       Rectangle request,                     │          │              .build());                           │ Iterator˂Feature˃ features
         │      StreamObserver responseObserver)        │       StreamObserver responseObserver) {     │          │                                                   │     = blockingStub
         │  {                                           │    for (Feature feature : features)          │          │                                                   │       .listFeatures(request);
         │    // Single onNext iteration                │    {                                         │ ─────────┼───────────────────────────────────────────────────┼───────────────────────────────────────────
         │    responseObserver.onNext(                  │      ...                                     │ ºSTREAM º│ public void recordRoute(                          │  public void routeChat()
         │      _checkFeature(request));                │      responseObserver.onNext(feature);       │ ºREQUESTº│     List˂Feature˃ features, int numPoints)        │    throws InterruptedException
         │    responseObserver.onCompleted();           │                 Oº   ^^^^^^^º                │          │      throws InterruptedException                  │  {
         │  //^ ends inmediatelly  ^                    │                 Oºfor each feature foundº    │          │   // NOTE: java.util.concurrent.CountDownLatch    │  //
         │  }                                           │    }                                         │          │      details removed                              │  // rpc RouteChat(stream RouteNote)
         │                                              │     //*streaming response*                   │          │                                                   │  //     returns (stream RouteNote) {}
         │                                              │   responseObserver.onCompleted();            │          │   // STEP 1. SETUP RESPONSE OBSERVER              │  //
         │                                              │  }                                           │          │   StreamObserver˂RouteSummary˃ responseObserver = │
─────────┼──────────────────────────────────────────────┼────────────────────────────────────────────  │          │       new StreamObserver˂RouteSummary˃() {        │  //*STEP 1. SETUP RESPONSE OBSERVER*
ºSTREAM º│  @Override                                   │  @Override                                   │          │     @Override                                     │    final CountDownLatch finishLatch
ºREQUESTº│  public StreamObserver recordRoute(          │  public StreamObserver routeChat(            │          │     public void onNext(RouteSummary summary) {    │       = new CountDownLatch(1);
         │      final StreamObserver responseObserver)  │      final StreamObserver responseObserver)  │          │         info... summary.get*());                  │    StreamObserver˂RouteNote˃
         │  {                                           │  {                                           │          │     }                                             │       requestObserver =
         │    return new StreamObserver() {             │    return new StreamObserver() {             │          │     @Override                                     │        asyncStub.routeChatBº(º
         │      @Override                               │      @Override                               │          │     public void onError(Throwable t) {            │          new StreamObserver˂RouteNote˃()Oº{º
         │      public void onNext(Point point) {       │      public void onNext(RouteNote note)      │          │         //    Rº^^^^^^^   º                       │            @Override
         │       ...                                    │      {                                       │          │         //    RºRPC Failedº                       │            public void onNext(RouteNote note)
         │      }                                       │        for (RouteNote prevNote :             │          │         log ... Status.fromThrowable(t););        │            {
         │                                              │            notes.toArray(new RouteNote[0]))  │          │     }                                             │                info"Got message ... ";
         │      @Override                               │        {                                     │          │     @Override                                     │            }
         │      public void onError(Throwable t) {      │          responseObserver.onNext(prevNote);  │          │     public void onCompleted(){                    │            @Override
         │          logger.... "recordRoute cancelled");│        }                                     │          │         finishLatch.countDown();                  │            public void onError(Throwable t)
         │      }                                       │        ...                                   │          │     }                                             │            {
         │                                              │      }                                       │          │   };                                              │                warn ... Status.fromThrowable(t);
         │      @Override                               │                                              │          │                                                   │            }
         │      public void onCompleted() {             │      @Override                               │          │   // STEP 2. SETUP REQUEST OBSERVER               │            @Override
         │        long seconds =                        │      public void onError(Throwable t) {      │          │   StreamObserver˂Point˃ requestObserver =         │            public void onCompleted()
         │            NANOSECONDS.toSeconds(            │          logger.... "routeChat cancelled");  │          │       asyncStub.recordRoute(responseObserver);    │            {
         │          System.nanoTime() - startTime);     │      }                                       │          │                                                   │                finishLatch.countDown();
         │        responseObserver                      │                                              │          │   try {                                           │            }
         │        Oº.onNext(º                           │      //*Do not complete until receivedº      │          │     for (int i = 0; i ˂ numPoints; ++i) {         │         º}*
         │           RouteSummary.newBuilder()          │      //*onCompleted for peerº                │          │       // push point to req.stream                 │    Bº)*;
         │            .setPointCount(pointCount)        │      @Override                               │          │       requestObserver.onNext(point);              │
         │            .setFeatureCount(featureCount)    │      public voidºonCompleted()º{             │          │       if (finishLatch.getCount() == 0 ) {         │  //*STEP 2: SETUP REQUEST OBSERVER*
         │            .setDistance(distance)            │         responseObserver.onCompleted();      │          │         /* RPC completed|failed before end of     │        try {
         │            .setElapsedTime((int) seconds)    │      }                                       │          │          * request stream                         │    RouteNote[] requests =
         │            .build()                          │    };                                        │          │          * Sending further requests won't error,  │      {newNote(...), newNote .. };
         │         Oº)º;                                │  }                                           │          │          * but they will just be thrown away.     │    for (RouteNote request : requests)
         │        responseObserver.onCompleted();       │                                              │          │          */                                       │    {
         │                        ^^^^^^^^^^^^^^        │                                              │          │         //                                        │      requestObserver.onNext(request);
         │                        end stream            │                                              │          │         return;                                   │      //             ^^^^^^^
         │      }                                       │                                              │          │       }                                           │      //             Send Message
         │    };                                        │                                              │          │     }                                             │    }
         │  }                                           │                                              │          │   } catch (RuntimeException e) {                  │        } catch (RuntimeException e) {
─────────┴──────────────────────────────────────────────┴────────────────────────────────────────────  │          │       requestObserver.onError(e) /  Cancel RPC  /;│    requestObserver.onError(e); throw e;
                                                                                                       │          │       throw e;                                    │                 Rº^^^^^^^^^^^º
                                                                                                       │          │   }                                               │                 RºCancel RPC º
                                                                                                       │          │   requestObserver.onCompleted();                  │    requestObserver.onCompleted();
                                                                                                       │          │                  º^^^^^^^^^^^^^ º                 │                   ^^^^^^^^^^^^^^
                                                                                                       │          │                  ºMark the end of requestsº       │                // Mark the end of requests
                                                                                                       │          │                                                   │    finishLatch.await(1, TimeUnit.MINUTES);
                                                                                                       │          │   // Receiving happens asynchronously             │    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                                                                                       │          │   finishLatch.await(1, TimeUnit.MINUTES);         │    // Receiving happens asynchronously
                                                                                                       │          │                        ^^^^^^^^^^^^^^^^           │  }
                                                                                                       │          │                        java.util.concurrent.      │
                                                                                                         ─────────┴───────────────────────────────────────────────────┴────────────────────────────────────────────

BºgRPC ecosystemº:
-@[https://github.com/grpc-ecosystem]

NodeJS
Implementation
Summary
GºNODE.JS SERVER PROTO IMPLEMENTATION SUMMARYº

- ºSERVER INITIALIZATIONº
@[https://github.com/grpc/grpc/blob/master/examples/node/static_codegen/route_guide/]

  var routeServer = new grpc.Server();
  routeServer.addService(services.RouteGuideService, {
    getFeature: getFeature,
    listFeatures: listFeatures,
    recordRoute: recordRoute,
     routeChat: routeChat
  });
  routeServer.bind('0.0.0.0:50051',
                   grpc.ServerCredentials.createInsecure());
  ... "any other initialization"...
  routeServer.start();
         ┌────────────────────────────────────┬──────────────────────────────────────────
         │ ºSINGLE RESPONSEº                  │ºSTREAM RESPONSEº
─────────┼────────────────────────────────────┼──────────────────────────────────────────
ºSINGLE º│ function getFeature(               │ function listFeatures(
ºREQUESTº│    call, responseCallback )        │   call) { // ← where call.request is
         │ {                                  │                     Rectangle(lo, hi)
         │   responseCallback(null, feature); │   _.eachBº(ºfeature_list, feature =˃ Oº{º
         │   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │     if ("feature OK") {
         │        write response              │       call.write(feature)
         │ }                                  │       ^^^^^^^^^^^^^^^^^^^
         │                                    │       write to response stream
         │                                    │     }
         │                                    │ Oº}º
         │                                    │ Bº)º
         │                                    │   call.end();
         │                                    │   ^^^^^^^^^^^
         │                                    │   end stream
         │                                    │ }
─────────┼────────────────────────────────────┼──────────────────────────────────────────
ºSTREAM º│ function recordRoute (             │ function routeChat (
ºREQUESTº│     call // ← stream, callback)    │    call // ← stream. NOTE: no callback )
         │ {                                  │ {
         │   call.on('data',                  │   call.on('data',
         │     (point) =˃ { ... }             │     (note) =˃ {
         │   )                                │     _.each(internal_data,
         │   call.on('end',                   │     (note) =˃ {
         │     () =˃ {                        │       call.write(note)
         │       var summary = new            │            ^^^^^^^^^^^
         │         messages                   │           write to resp.stream
         │        .RouteSummary().set...      │     })
         │       callback(null, summary);     │   })
         │     })                             │   call.on('end',
         │ }                                  │     () =˃ { call.end(); }
         │                                    │  )
         │                                    │ }
─────────┴────────────────────────────────────┴──────────────────────────────────────────

GºNODE.JS CLIENT IMPLEMENTATION SUMMARYº

  messages = require('...._pb')
  services = require('...._grpc_pb')
  grpc = require('grpc')

  client = new services
             .RouteGuideClient(
      'localhost:50051',
      grpc
        .credentials
        .createInsecure())

          ┌────────────────────────────────┬───────────────────────────────────
          │ºSINGLE RESPONSEº               │ºSTREAM RESPONSEº
──────────┼────────────────────────────────┼───────────────────────────────────
ºSINGLE º │ function featureCallback(      │ function runListFeatures(callback)
ºREQUESTº │       error, feature)          │ {
          │ {                              │   call = client
          │   if (error) {                 │            .listFeatures(rect);
          │      ....                      │   call.on(
          │      return                    │      'data',
          │   }                            │      (feature) =˃ {
          │   var latitude = feature.get.. │       //  process feature 'event'
          │   ...                          │   })
          │   next();                      │   call.on('end', callback);
          │ }                              │ }
          │ client                         │
          │   .getFeature(                 │
          │      point1,                   │
          │      featureCallback);         │
──────────┼────────────────────────────────┼───────────────────────────────────
ºSTREAM º │ //* a) Create call.write(able)*│ function runRouteChat(callback)
ºREQUESTº │ //*    object*                 │ {
          │ var call = client.recordRoute( │   //*1) create call.write(able)*
          │   function(                    │   //*   object with onData notifier*
          │     error,                     │   var call = client.routeChat()
          │     stats // ← server response │   call.on(
          │   )                            │     'data',
          │   {                            │     (note)=˃ { // ← response from stream /
          │     if (error) {               │       //*2) callback for stream response*
          │       ...                      │       //*   object received*
          │       return                   │       .. do whatever with note response
          │     }                          │     }
          │     // process stats response  │   )
          │   }                            │   //*3) Setup onEnd*
          │ );                             │   call.on('end', callback)
          │ //* b) Write to stream*        │
          │ for ("location in ddbb") {     │   //*4) Write to request stream*
          │    call.write(location);       │   for ("note in note_ddbb") {
          │ }                              │     var noteMsg = new messages
          │                                │           .RouteNote().setXXX..;
          │                                │     call.write(noteMsg);
          │                                │   }
          │                                │   call.end();
          │                                │ }
──────────┴────────────────────────────────┴───────────────────────────────────
Rsocket
Rsocket authors claim that it's better than gRPC:
- @[https://github.com/rsocket/rsocket/blob/master/Motivations.md]
- @[https://medium.com/netifi/rpc-thunder-dome-3103e2449957]
Data Visualization
Perspective
@[https://github.com/jpmorganchase/perspective]
   A streaming data visualization engine for Javascript, Perspective makes
   it simple to build real-time & user configurable analytics entirely in the browser.

D3
  D3 Announces 5.0 Release of SVG, Canvas, and HTML Library for Manipulating Data
  The D3 team has announced their 5.0 release, which embraces several newer
  asynchronous patterns such as promises and fetch, and updates key visualization APIs.

  D3.js is a JavaScript library for producing dynamic, interactive data
  visualizations in web browsers. As stated in the D3 5.0 release notes:

  With the adoption of promises, D3 now uses the Fetch API instead of XMLHttpRequest:
  the d3-request module has been replaced by d3-fetch. Fetch supports many
  powerful new features, such as streaming responses.

RaphaelJS
- http://raphaeljs.com/
  D3 is certainly a very powerful tool and will do much of what Raphael does.
  Most of what you can do in Raphael you can also do in D3. Many will argue
  that D3 is far more powerful, and indeed it can handle more complex graphics,
  particularly for business purposes. However, from an artistic standpoint, you
  already know that you don’t always want to use the same tool for everything.
  Sure D3 is powerful. So is a heavy duty spray gun. That does not mean that it
  is right for all artistic purposes. Sometimes you only need a simple brush.


JointJS
http://www.jointjs.com/tutorial
http://www.jointjs.com/demos/umlcd
- Diagrams consist of elements connected with links.
- A diagram in JointJS is represented by a model joint.dia.Graph.
- This model then collects cells (a term representing both elements and links).
- A cell could therefore be either an element (joint.dia.Element or its inheritants) or a link (joint.dia.Link).
- In JointJS (starting from version 0.6), you manipulate models, not views."
- To be able to see something on the screen, the graph model must be attached to the joint.dia.Paper view.

   - Joint.JS  "Hello World!:
       ˂link rel="stylesheet" href="joint.css" /˃
       ˂script src="joint.js"˃˂/script˃

       var graph = new joint.dia.Graph;

       var paper = new joint.dia.Paper({
           el: $('#myholder'),
           width: 600,
           height: 200,
           model: graph, ← instance of graph
           gridSize: 1
       });
       var paperSmall = new joint.dia.Paper({
           el: $('#myholder-small'),
           width: 600,
           height: 100,
           model: graph, ← instance of graph
           gridSize: 1
       });
       paperSmall.scale(.5);
       paperSmall.$el.css('pointer-events', 'none');

       var rect = new joint.shapes.basic.Rect({
           position: { x: 100, y: 30 },

     - Event handling (based on the Backbone MVC)
       See all events triggered by any model in the graph:

       graph.on('all', function(eventName, cell) {
           console.log(arguments);
       });

       rect.on('change:position', function(element) {
           console.log(element.id, ':', element.get('position'));
       });

     - Styling:
       rect.attr({
           rect: { fill: '#2C3E50', rx: 5, ry: 5, 'stroke-width': 2, stroke: 'black' },
           text: {
               text: 'my label', fill: '#3498DB',
               'font-size': 18, 'font-weight': 'bold', 'font-variant': 'small-caps', 'text-transform': 'capitalize'
           }
       });

     - Setting vertices on a link is as simple as:
       link.set('vertices', [{ x: 300, y: 60 }, { x: 400, y: 60 }, { x: 400, y: 20 }])
       If you prefer the link to not be sharply broken at the vertices but instead interpolated by a curve,
       set the smooth attribute:
       link.set('smooth', true)

     - JointJS has built-in elements for basic shapes.
       These shapes are all in the joint.shapes.basic namespace and consist of
       - joint.shapes.basic.Rect
       - joint.shapes.basic.Circle
       - joint.shapes.basic.Text
       - joint.shapes.basic.Image

Babylon.js 3D Game Engine
https://blogs.windows.com/buildingapps/2018/05/01/announcing-babylon-js-v3-2/#yDoTuK4LbD0yxLd3.97
Babylon.js is an open source framework designed from ground up to help create
easy and powerful 3D experiences in your browser or your web apps.

@[https://www.youtube.com/watch?v=m-YWBmim2Fo]

ThreeJS
@[http://threejs.org/]

Pixi (Adobe Flash alternative)
@[https://www.infoq.com/news/2019/05/pixi-webgl-html5-v5-games/]
PixiJS, a standard-based, open-source alternative to Adobe Flash,
recently released its fifth major version. PixiJS v5 abstracts a
large set of WebGL features behind a new API which falls back to
HTML5's canvas if needed

JS Pivot Tables
@[https://github.com/search?q=pivot+table]

@[https://pivottable.js.org/examples/] @[https://github.com/nicolaskruchten/pivottable]
@[https://www.flexmonster.com/demos/pivot-table-js/]
Advanced Topics
JiSON
context-free
grammar to JS
http://zaach.github.io/jison/docs/
Jison takes a context-free grammar as input and outputs a JavaScript
file capable of parsing the language described by that grammar.
You can  then use the generated script to parse inputs and accept,
reject, or perform actions based on the input. If you’re familiar
with Bison or Yacc, or other clones, you’re almost ready to roll.
Multimedia
- http://www.w3.org/2010/05/video/mediaevents.html

- http://stackoverflow.com/questions/14317179/display-a-video-from-a-blob-javascript
  var reader = new FileReader();
  reader.readAsDataURL(vid);

  function display(vid){
      var video = document.getElementById("video");
      video.src = window.URL.createObjectURL(vid);

  }

- http://html5doctor.com/video-canvas-magic/
  http://html5doctor.com/demos/video-canvas-magic/demo2.html
  https://developer.mozilla.org/en-US/docs/Web/HTML/Manipulating_video_using_canvas

- Video & MediaSource:
  https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html
 During playback, the media element pulls segment data out of the source
buffers, demultiplexes it if necessary, and enqueues it into track buffers so
it will get decoded and displayed. buffered describes the time ranges that
are covered by media segments in the source buffer.
  Once a new SourceBuffer has been created, it expects an initialization
segment to be appended first. This first segment indicates the number and
type of streams contained in the media segments that follow. This allows the
media element to configure the necessary decoders and output devices

  A MediaSource object can be attached to a media element by assigning a
MediaSource object URL to the media element src  attribute or the src
attribute of a ˂source˃ inside a media  element. MediaSource object URLs are
created by passing a MediaSource  object to window.URL.createObjectURL().
Initialization segments are an optimization. They allow a byte stream format
to avoid duplication of information in Media Segments that is the same for
many Media Segments. Byte stream format specifications need not specify
Initialization Segment formats, however. They may instead  require that such
information is duplicated in every Media Segment.


   | http://updates.html5rocks.com/2011/11/Stream-video-using-the-MediaSource-API
   |*//SUMMARY:
   | video.src = video.webkitMediaSourceURL;
   | ...
   | video.webkitSourceAppend(new Uint8Array(...));
   | if (endOfStreamDetected) {
   |     video.webkitSourceEndOfStream(HTMLMediaElement.EOS_NO_ERROR);
   | }
   |
   |*//FULL CODE:*
   | const chunkSize = Math.ceil(file.size / 5 /*number of Chunks */); // file is a video file
   | var video = document.querySelector('video');
   |     video.src = video.webkitMediaSourceURL;
   |     video.addEventListener('webkitsourceopen', function(e) {
   |         for (var i = 0; i ˂ NUM_CHUNKS; ++i) {
   |             var startByte = chunkSize * i;
   |             var chunk = file.slice(startByte, startByte + chunkSize); // get slice
   |             var reader = new FileReader();
   |             reader.onload = (function(idx) {
   |                 return function(e) {
   |                     video.webkitSourceAppend(new Uint8Array(e.target.result)); // appending chunk:
   |                     if (idx == NUM_CHUNKS - 1) {
   |                       video.webkitSourceEndOfStream(HTMLMediaElement.EOS_NO_ERROR);
   |                     // appending chunk:
   |                     }
   |                 };
   |             })(i);
   |             reader.readAsArrayBuffer(chunk);
   |         }
   |     }, false);
   |
   | splits video into chunks, then "stream" to a ˂video˃ tag by appending each chunk to the element using the MediaSource API.
   |
   | If you're interested in learning more about the API, see the specification.
   |
   | Support: Currently, the MediaSource API is only available in Chrome Dev Channel 17+ with the
   |  --enable-media-source flag set or enabled via about:flags.
   |
   | CONST chunkSize = Math.ceil(file.size / 5 /*number of Chunks */); // file is a video file


Web-Audio
Components
@[https://github.com/web-audio-components]
Binary Data
@[https://github.com/jDataView]
- jBinary High-level API for working with binary data.
- jDataView. DataView. Extended. Anywhere.
@[https://github.com/jDataView/jBinary/wiki/jBinary-Constructor]
@[https://github.com/jDataView/jDataView]
@[http://www.khronos.org/registry/typedarray/specs/latest/]
  | "* BufferArray: Array of Bytes. Constructor BufferArray(byte length)
  | * TypedArray: Type view of the Buffer Array (Ui|i)nt(8|16|32)Array , Float(32|64)Array
  |     Constructors:
  |       +- TypedArray(byte length) ← Creates new BufferArray
  |       +- TypedArray(TypedArray (existing)array) ← Creates new BufferArray duplicated of array
  |       +- TypedArray(sequence array) ← Creates new BufferArray from Javascript array
  |       +- TypedArray((existing)buffer[, byteOffset, length]) ← Creates new view from existing buffer
  |     Methods:
  |       +- void set( TypedArray array[, offset]) ← copy values from TypedArray
  |       +- void set( type[] array[, offset])     ← copy values from JS array
  |       +- TypedArray subarray(offsetFirstElement [, offsetLastElement=""last one""]) ← Creates a view, not a new buffer!!
  |
  | * DataView: Low level endianess aware view of the Buffer (use for file/hardware/network access with a defined endianess defined ""outside"" our computer)
  |     Contructor:
  |       +- DataView(ArrayBuffer buffer[, byteOffset, byteLength])
  |     Methods (Read):
  |       +- get(Ui|I)nt(8|16|32)(byteOffset[, littleEndian])
  |       +- getFloat(32|64)(byteOffset[, littleEndian])
  |     Methods (Write):
  |       +- set(Ui|I)nt(8|16|32)(byteOffset, value[, littleEndian] )
  |       +- setFloat(32|64)(byteOffset, value[, littleEndian] )
  | Note: Detecting endianness:
  |   var littleEndian = function() {
  |     var buffer = new ArrayBuffer(2);
  |     new DataView(buffer).setInt16(0, 256, true);
  |     return new Int16Array(buffer)[0] === 256; /* true | false */
  | };

- Creating a simple array of 128 32-bit floats and filling with 8 consecutive floats:

  var f32s = new Float32Array(128);

  var groupLength = 8;
  for (var i = 0; i ˂ 128/groupLength; ++i) {
    var sub_f32s = f32s.subarray(i, i+groupLength);
    for (var j = 0; j ˂ 8; ++j) {
       sub_f32s[j] = j;
    }
  }

- Representing a point with 3xFloat32 coordinates values plus 4xUint8 color data values:

  var elementSize = 3 º Float32Array.BYTES_PER_ELEMENT + 4 º Uint8Array.BYTES_PER_ELEMENT;
  var buffer = new ArrayBuffer(4 * elementSize);
  var coords = new Float32Array(buffer, 0);
  var colors = new Uint8Array(buffer, 3 * Float32Array.BYTES_PER_ELEMENT);

- Slicing a large array into multiple regions:
  var buffer = new ArrayBuffer(1024);
  var floats = new Float32Array(buffer,   0 /*     0 offset*/, 128); (128*4 = 512 bytes)
  var shorts = new Uint16Array (buffer, 512 /*floats offset*/, 128); (12*2  = 256 bytes)
  var bytes = new Uint8Array   (buffer, shorts.byteOffset + shorts.byteLength);

- JBinary
  ref: https://github.com/jDataView/jBinary

  - Typical scenario:
  - Create your custom types using jBinary.Type (if needed).
  - Describe type set with JavaScript-compatible declarative syntax.
  - Create jBinary instance from jDataView (or any underlying type) and your type set.

- Constructors:
  +- new jBinary(jDataView data[, typeSet])
  +- new jBinary(javascript Byte array[, typeSet])
  Read Methods:
  +- read(type[, offset = binary.tell()]) ← If offset is provided internal pointer doesn't moves
  Pointer Methods:
  +- tell(): Return the current position. Ex: var currentPos = binary.tell();
  +- seek(position[, callback]): Go to position; if callback → execute it and reset position.
  +- skip(count[, callback]): Advance by count bytes; same callback behavior as seek
  Instance helpers
  +- slice(start, end[, forceCopy = false]): Returns sliced version of current binary with same type set.
  +- as(typeSet[, modifyOriginal = false]): Casts instance to typeSet
  Loading Data
  +- jBinary.loadData(source, callback(error, data)) (static method)
  |     source := Blob/File | HTTP(S)_URL | Data-URI (simple|base64-encoded) | Node.js (local file path|stream)

  var b1 = new jBinary([0x05, 0x03, 0x7F, 0x1E]); // with default typeset
  var b2 = new jBinary(new jDataView(data, 5, 10, true), { MetaName: ['string', 30]}); // typeset with custom type MetaName.
  var firstInt = b1.read('uint32');           // uint32 value at offset 0 → Pointer moves 4 bytes
  var byteAtOffset100 = b2.read('uint8', 100);// uint8 value at custom position → Pointer unchanged(offset provided)
  var intAt200 = binary.seek(200, function () { return this.binary.read('int32') });
  var intAfter8 = binary.skip(8, function () { return this.binary.read('int32') });
  var binary = someExternalBinary.as(TAR); // casting
  fileInput.addEventListener('change', function () {
    jBinary.loadData(fileInput.files[0], function (error, data) {
      if (error) { return console.log(error); }
      ...
    });
  });

  jBinary.load('sample.tar', function (error, binary) {
    if (error) { return console.log(error); }
    var tar = binary.read('File'); // TAR format auto-detected (using jBinary.Repo)
  });

  - Typesets normally are object dictionaries
    { typeName1 : type1 , ← types that can refer to each other but they may also contain special config
      typeName2 : type2 , values that set some global options or modes for entire typeset. Options are:
      typeName3 : type3 ,
      typeName4 : type4 ,
      typeName5 : type5 ,
      typeName6 : type6 ,
       ...
    }
    - jBinary.all - reference to general type that represents entire data; required for enabling user to read/write entire file at once.
    - jBinary.mimeType - sets mime-type which should be used for saving data from this typeset (i.e., when calling toURI without argument).
    - jBinary.littleEndian - sets endianness for this format.

  - __________ Integers ______________
      uint8 (byte) / int8 - one-byte integer.
      uint16 / int16 - word.
      uint32 / int32 - dword (double-word).
      uint64 / int64 - qword - please see warning about precision loss in jDataView documentation.
    ___________ Floats  ______________
      float32 (float) - classic 32-bit float used in languages like C.
      float64 (double) - 64-bit float with double precision (double in C), default for JavaScript number representation.
    ___________ Strings ______________
      char - one-byte binary character.
      string(@length, encoding = 'binary') - string of given length in binary or 'utf8' encoding, reads/writes to the end of binary if length is not given.
      string0(@length, encoding = 'binary') - null-terminated string stored in given number of bytes; treated as dynamic null-terminated string if length is not given.
    _________ Complex types __________
      const(baseType, value, strict = false) - treats type as constant; if read value does not match expected and strict mode is enabled, calls strict(readValue) if it is function or simply throws TypeError if not.
      array(baseType, @length) - array of given type and length, reads/writes to the end of binary if length is not given.
      object(structure, proto = Object.prototype) - complex object of given structure (name → type), creates new context while processing inner properties; object may also contain functions instead of types for calculating some values during read/write for internal purposes.
      extend(...object structures...) - extends one structure with others; merges data into one object when reading and passing entire object when writing.
      enum(baseType, matches) - enumeration type with given key <=> value map (if value not found in the map, it's used "as-is").
    _________ Binary types __________
      bitfield(length) - unsigned integer of given bit length (supports up to 32 bits, wraps around 2^32).
      blob(@length) - byte array represented in most native type for current engine; reads/writes to the end of binary if length is not given.
      binary(@length, typeSet = {}) - jBinary instance on part of original one with given length and optional custom typeset (useful for container formats); accepts also raw binary data when writing.
    _____ Control statements   ______
      if(@condition, trueType, falseType) - conditional statement.
      if_not(@condition, falseType, trueType) - same but inverted.
      skip(@length) - simply skips given length on read/write.
    ______About @  __________________

    All the arguments marked with @(references) can be passed not only as direct values, but also as getter functions callback(context) or string property names inside current context chain.

  - Usage (in Browser): Include scripts for jDataView and jBinary like that:
    ˂script src="//jdataview.github.io/dist/jbinary.js"˃˂/script˃
    ˂script˃
      var typeSet = { magic: ['array', 'uint8', 4] };
      jBinary.load('file.bin', typeSet, function (err, binary) {   console.log(binary.read('magic')); } );
    ˂/script˃
  - HLS player using JBinary
    http://rreverser.github.io/mpegts/

  - Ex1: Audio Data Transport Stream (ADTS):
    (function (exports) {
    var ADTS = {
    /* :
     * Structure: AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP (QQQQQQQQ QQQQQQQQ)
     *            ^bit (not byte)
     * Header consists of 7 or 9 bytes (without or with CRC).
     * Usage in MPEG-TS
     * - ADTS packet must be a content of PES packet. Pack AAC data inside ADTS frame, than pack inside PES packet, then mux by TS packetizer.
     * - ADTS frames goes one by one in TCP stream. Look for syncword, parse header and look for next syncword after.
    */
        ADTSPacket: {
    /*bits Letter*/  _start            : function () { return this.binary.tell() },
    /*12       A */  _syncWord         : ['const', 12, 0xfff, true],           // syncword 0xFFF, all bits must be 1
    /* 1       B */  version           : ['enum',   1, ['mpeg-4', 'mpeg-2']],  // MPEG Version: 0 for MPEG-4, 1 for MPEG-2
    /* 2       C */  layer             : ['const',  2, 0],                     // Layer: always 0
    /* 1       D */  isProtectionAbsent: 1,                                    // protection absent, Warning, 1 → no CRC, 0 → CRC
    /* 2       E */  profileMinusOne   : 2,                                    // Audio_Object_Types
    /* 4       F */  samplingFreq      : ['enum',   4, [96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350]],// MPEG4 Sampl.FrequencyIndex
    /* 1       G */  _privateStream    : 1,                                    // private stream, set to 0 when encoding, ignore when decoding
    /* 3       H */  channelConfig     : 3,                                    // MPEG4 Audio Channel_Configurations(if 0, configuration is sent via an inband PCE)
    /* 4    IJKL */  _reserved         : 4,                                    // originality, home, copyrighted, copyright start bits
    /*13       M */  frameLength       : 13,                                   // frame length value. Must include 7 or 9 bytes of header length: = (ProtectionAbsent == 1 ? 7 : 9) + size(AACFrame)
    /*11       O */  bufferFullness    : 11,                                   // Buffer fullness
    /* 2       P */  aacFramesCountMinusOne: 2,                                 // # of AAC frames(RDBs) in ADTS frame minus 1, for maximum compatibility always use 1 AAC frame per ADTS frame
    /*16       Q */  data              : ['blob', function (context) { return context.frameLength - (this.binary.tell() - context._start) }] // CRC if protection absent is 0
        }
    };

    if (typeof module !== 'undefined' && exports === module.exports) {
        module.exports = ADTS;
    } else {
        exports.ADTS = ADTS;
    }

    })(this);

   - Ex2: MPEG-TS Packet:
   MPEG-TS Packet:
   Name                          |#bits|Description
   _______________________________________________________________________________________________
   sync byte                     |8    |Bit pattern from bit 7 to 0 as 0x47 or ASCII char 'G"
   Transport Error Indicator(TEI)|1    |Set by demodulator if can't correct errors in the stream, to tell the demultiplexer that the packet has an uncorrectable error
   Payload Unit Start Indicator  |1    |Boolean flag with a value of true meaning the start of PES data or PSI otherwise zero only.
   Transport Priority            |1    |Boolean flag with a value of true meaning the current packet has a higher priority than other packets with the same PID.
   PID                           |13   |Packet Identifier
   Scrambling control            |2    |'00' = Not scrambled. For DVB-CSA only→'01':Reserved,'10':Scrambled with even key,'11':Scrambled with odd key
   Adaptation field exist        |1    |Boolean flag
   Contains payload              |1    |Boolean flag
   Continuity counter            |4    |Sequence number of payload packets.  Incremented only when a payload is present (i.e., payload value is true)
   Note: the total number of bits above is 32 and is called the transport stream 4-byte prefix or Transport Stream Header.
   Adaptation field              |0+   |If adaption field exist value is true
   Payload Data                  |0+   |If contains payload value is true

   jBinary Packet Representation: {
       _startof: function () { return this.binary.tell() },

       _syncByte: ['const', 'uint8', 0x47, true],
       transportError: 1,
       payloadStart: 1,
       transportPriority: 1,
       pid: 13,
       scramblingControl: 2,
       _hasAdaptationField: ['Flag', 'adaptationField'],
       _hasPayload: ['Flag', 'payload'],
       contCounter: 4,
       adaptationField: ['FlagDependent', '_hasAdaptationField', 'AdaptationField'],
       payload: ['FlagDependent', '_hasPayload', jBinary.Template({
           getBaseType: function (context) {
               var pid = context.pid, file = this.binary.getContext(1);
               if (pid ˂ 2 || pid in file.pat) {
Java JVM
JS imple.
@[https://github.com/ghewgill/lentil]
JS Oscillator
@[https://tonejs.github.io/examples/oscillator]
WebAssembly
Roadmap
@[https://hacks.mozilla.org/2018/10/webassemblys-post-mvp-future/]
Mozilla
WASI
@[https://www.infoq.com/news/2019/04/wasi-wasm-system-interface/]

Mozilla WASI Initiative:
- Run Web Assembly on All Devices, Computers, Operating Systems
Fastly Lucet
@[https://www.infoq.com/news/2019/04/fastly-lucet-web-assembly-open/]
WebAssembly Compiler and Runtime
Emscripten
"Emscripten is an LLVM to JavaScript
compiler. It takes LLVM bitcode (which can be generated from C/C++ using
 Clang, or any other language that can be converted into LLVM bitcode)
and compiles that into JavaScript, which can be run on the web (or
anywhere else JavaScript can run)."
https://github.com/kripken/emscripten/wiki
http://stackoverflow.com/questions/14902514/installing-emscripten-on-ubuntu

http://asmjs.org/spec/latest/


ANGULAR
External Links
- @[https://angular.io/docs]
Architecture
@[https://angular.io/guide/architecture]
ºView     =  @Compoment                        + Templateº
 ^^^^        ^^^^^^^^^^                          ^^^^^^^^
 screen      Compoment = Class +                 HTML + Directives   + data binding markup
 element     ^           metadata-decorators            ^^^^^^^^^^     ^^^^^^^^^^^^^^^^^^^
 on target   |           ^^^^^^^^^^^^^^^^^^^            provide        DOM changes  ←→  program data
 environ.    |           include pointer to             program logic  Binding types:
             |           associated template                           - Event   : user input  → data update
           - Typically a component defines many                        - Property: data update → DOM
             views, arranged hierarchically and
             the ºRouter serviceº defines                         Template Evaluation:
             navigation paths among them.                              tpl
           - At least one ºroot componentº                              → evaluate directives
             is needed by App, connecting a                              → resolve binding syntax
             component hierarchy with the                                 → modify HTML elem. + DOM
             page document object model (DOM).
           - ºServiceº (providers) are injected                        Template Pipes
             (@Injectable() decorator) to provide                      -  Ex: date data → pipe → locale-date
             needed non-visual functionality                           -  predefined pipes are provided for
           - When a component is instantiates,                            common transforms
             it's associated directly with
             the (root) host view.

IMPORTANT: hierarchical structure of views is a key factor in the way Angular detects and responds to changes
           in the DOM and app data.

The host view can be the root of a view hierarchy, which can contain embedded views, which
are in turn the host views of other components.

ºRouter NgModule Serviceº
  MAP of:
  URL-like paths  ← → views
  ^^^^^^^^
  also integrates
  program data

- When a user performs an action (clicking a link, select drop box, ...)
  the router intercepts the browser's behavior, and shows
  or hides view hierarchies, lazy-loading new modules on demand


ºView/Component treeº
view root    ← NgModule1.rootComponent
 +- view1    ← NgModule1.component1
 +- view2    ← NgModule2.rootComponent
   +- view2  ← NgModule2.component3
               ^^^^^^^^^^^^^^^^^^^^
               A view hierarchy can include
               views from components in the
               same or different NgModule
Modules
@[https://angular.io/guide/architecture-modules]
- NgModule == container (scope) set of components, service providers, ...
              offerent  a cohesive block of code dedicated to
              an application domain/workflow/capabilities set.
- They can import / export functionality from/to other NgModules
- Allows for lazy-loading.
- provides a ºcompilation contextº for components:
- Angular app == tree of NgModules
                 (bootstrapping root module plus others)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^
                 ex. app.module.ts:
                 import {OºNgModuleº }      from '@angular/core';   ←  Javascript input
                 import {BºBrowserModuleº } from '@angular/platform-browser'; ← Javascript input
                 @NgModule({                         ← Decorator function.
                   imports:      [ BºBrowserModuleº ],  ← Imported modules
                   providers:    [ Logger ],         ← Creators of services that this NgModule
                                                       contributes to the global collection of
                                                       services, accessible in all parts of the
                                                       app.
                                                       (providers at component level can also
                                                       be specified , which is often preferred.
                   declarations: [ AppComponent ],   ← components,directives,pipes
                                                       of this NgModule
                   exports:      [ AppComponent ],   ← (optional) Subset of declarations visible
                                                       and usable in the templates of
                                                       other NgModules
                   bootstrap:    [ AppComponent ]    ← main app view (root component)
                                                       hosting all other app views.
                                                       Only the root NgModule should set
                                                       the bootstrap property.

                 })
                 export class AppModule { }          ← Javascript export (vs NgModule export)

Components
@[https://angular.io/guide/architecture-components]
- A component controls a patch of screen called a view.
- Developers define the component as a typescript class
  with the application logic:
  - The class interacts with the view through an API of
    properties and methods.

Ex: src/app/hero-list.component.ts


@Component({
  selector:    'app-hero-list', ← instantiates a new component for each
                                  HTML ˂app-here-list˃ tag
  templateUrl: './hero-list.component.html',  ← Links component with module relate html tpl
                                                (it can be set programatically by setting
                                                 the template property)
  providers:  Bº[HeroService]º                ← Serv.prov. array required by component.
                                                Size must match constructor arg. size

})
export class HeroListComponent implements ºOnInitº {
  heroes: Hero[];      ← data app property
  selectedHero: Hero;  ← data app property

  constructor Bº(private service:HeroService)º { }
  //          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  //          will be Dep.Injected

 ºngOnInit()º {
//^^^^^^^^
//Angular lifeCycle hook
    this.heroes = this.service.getHeroes();
  }

  selectHero(hero: Hero) { this.selectedHero = hero; }
}
Template syntax
@[https://angular.io/guide/architecture-components]
- A template looks like regular HTML plus OºAngular template syntaxº
Ex.: src/app/hero-list.component.html
˂h2˃Hero List˂/h2˃
˂p˃˂i˃Pick a hero from the list˂/i˃˂/p˃
˂ul˃
  ˂li˃ OººngForº="let hero of heroes" Oº(click)*="selectHero(hero)"
    Oº{{hero.name | UpperCase}}º
  ˂/li˃
˂/ul˃

 ˂Oºapp-hero-detailº
  OººngIf*="selectedHero"
  Oº[hero]º="selectedHero"˃
 ˂/Oºapp-hero-detailº˃

- *ngFor : iterate over a list.
- {{hero.name}}: binding
  [hero]
  (click)
- | UpperCase  : pipe
DATA BINDING
          {{value}}
     ←────────────────────
        [property]="value"
DOM  ←────────────────────   COMPONENT
       (event)="handler"
      ────────────────────→
      [(ng-model)]="property  ← Two-way data binding
     ←────────────────────→     (used mainly in template-driven forms)
                                Ex.:
                                ˂input [(ngModel)]="hero.name"˃


Angular processes all data bindings once for each JavaScript event cycle,
from the root of the application component tree through all child components.
@Directive()
- Angular transform HTML templates according to the instructions in directives.

- Directive types:
  - Component  :
  - structural : alter layout by adding|removing|replacing elements in the DOM.
                 Example:
                 ˂li             OººngFor*="let hero of heroes"˃˂/li˃
                 ˂app-hero-detailOº ºngIf*="selectedHero"˃˂/app-hero-detail˃
                 *ngFor is an iterative; stamp out one 
  • per hero in the heroes list. *ngIf is a conditional; includes HeroDetail component only if a selected hero exists. - attribute : alter the appearance or behavior of an existing element. Ex: ˂input [(ngModel)]="hero.name"˃ ngModel: modifies ˂input˃ behavior by setting its display value property and responding to change events.
  • Services and Dep.Inj.
    Service: broad category encompassing any value, function, or
             feature that an app needs.
             - Typically a class with a narrow, well-defined purpose.
               (do one thing and do it right)
    
    Ex Service:
    src/app/logger.service.ts
    @Injectable()
    export class Logger {
      log  (msg: any) { console.log  (msg); }
      error(msg: any) { console.error(msg); }
      warn (msg: any) { console.warn (msg); }
    }
    Note: Other than services a dependency can be a function or value.
    
    OºInjection Seq. Diagramº
    
    for each injectable service/function/value create at least one provider:
    The provider can be part of the service's own metadata, making that service
    available everywhere, or you can register providers with specific modules
    or components.
    Providers are registed in the the metadata of the service
    (@Injectable(), @NgModule() or @Component() decorators)
    Registering the provider in the @Injectable() metadata also allows Angular
    to optimize an app by removing the service from the compiled app if it
    isn't used.
    
    App Bootstrap → +app-wide inj.: create App.wide injector
    app-wide inj. →  app-wide inj.: creates container of
                                     dependency instances (reuses when possible)
    ...
      ???         →     +provider : Create provider
                                          ^^^^^^^^
                                        - tells an injector how to obtain|create a dependency.
                                        - (Usually the service class itself for service providers)
    
      ???           →  app.wide inj.: register provider
      ...
    angular       →  +Component class instance:
    injector      →   injector: determines which services (and extra deps)
                                are needed by ºlooking at the constructor parameter types.º
    
    injector      →   injector: checks if the injector has any existing instances of
                                requested service or instantiate new one using the registered
                                provider.
    injector      →   angluar : returning service
    angular       →   Component class instance: call component constructor
    
    
    $ ng generate service # By default registers a provider with the root injector
                            for your service by including provider metadata in the
    
    REGISTER SCOPE
     | ROOT LEVEL:                    | NgModule LEVEL:                | Component LEVEL:
     |                                |                                |
     | Angular creates a single,      | same instance of a service     | A new instance of the service
     | shared instance of the         | available to all components in | is created for each new new
     | service and injects it into    | the NgModule.                  | instance of the component.
     | any class that asks for it.    |                                |
     |                                |                                |
     | @Injectable() decorator like:  | @NgModule({                    | @Component({
     | @Injectable({                  |   providers: [                 |   selector:    'app-hero-list',
     |  providedIn: 'root', ←         |   BackendService,              |   templateUrl: './hero-list.component.html',
     | })                             |   Logger                       |   providers:  [ HeroService ]
     |                                |  ],                            | })
     |                                |  ...                           |
     |                                | })                             |
    
    Predefined Pipes
    @[https://angular.io/api?type=pipe"
    AsyncPipe
    CurrencyPipe
    DatePipe
    DecimalPipe
    DeprecatedCurrencyPipe
    DeprecatedDatePipe
    DeprecatedDecimalPipe
    DeprecatedPercentPipe
    I18nPluralPipe
    I18nSelectPipe
    JsonPipe
    KeyValuePipe
    LowerCasePipe
    PercentPipe
    SlicePipe
    TitleCasePipe
    UpperCasePipe
    
    Responsive Programming
    Component Lifecycle hooks
    @[https://angular.io/guide/lifecycle-hooks]
    Component and Directives have the same lifecycle
    (Remember that a component is a type of directive)
    
    - One interface exist for each existing life-cycle defined on the Angular lib.
    - The hook name is the interface name prefixed with ng (OnInit iface -> ngOnInit)
    
    Ex:
    Oºº
    export class PeekABook implements OºOnInitº {
      constructor(private logger: LoggerService) { }
    
      // implement OnInit's `ngOnInit` method to tap into life-cycle
      OºngOnInit()º { this.logIt(`OnInit`); }
    
      logIt(msg: string) {
        this.logger.log(`#${nextId++} ${msg}`);
      }
    }
    
    Main Hooks:
    Hook                    Purpose and Timing
    ngOnChanges()           (re)sets data-bound input properties.
    ngOnInit()              Initialize directive/component after first displays
                            the data-bound properties and sets the
                            directive/component's input properties.
    ngDoCheck()             Detect and act upon changes that Angular
                            can't or won't detect on its own.
    ngAfterContentInit()    Respond after Angular projects external content
                            into the component's view
    ngAfterContentChecked() ...
    ngAfterViewInit()       ...
    ngAfterViewChecked()    ...
    ngOnDestroy()           tap into Cleanup just before Angular destroy
                            Use it to Unsubscribe Observables and detach
                            event handlers to avoid memory leaks.
    
    Other hooks:
    - Angular sub-systems
    - 3rd party libraries may add new hooks.
    
    ºLifecycle examplesº
    @Component...
    
      @Input() hero: Hero;
      @Input() power: string;
      ...
      ngOnChanges(changes: SimpleChanges) {
                  ^^^^^^^^^^^^^^^^^^^^^^
              //  object mapping each changed property
              //  name to a SimpleChange object holding
              //  the current and previous property values.
        for (let propName in changes) {
          let chng = changes[propName];
          let cur  = JSON.stringify(chng.currentValue);
          let prev = JSON.stringify(chng.previousValue);
          this.changeLog.push(
             '${propName}: currentValue = ${cur}, previousValue = ${prev}');
        }
      }
    
    
    
    Check Component Lifecycle hooks for detailed examples.
    
    Observables,event processing
    @[https://angular.io/guide/observables]
    
    Observables,event processing
    Observables provide publishers/subscriber messaging pattern support
    
    Messages can be of any type: literals, messages or events depending on the context.
    
    Publisher → +"Subcriber-func01" : defines "subcriber function" defining the messages
                                       to be published.
                                       executed when a consumer calls the subscribe() method.
    Publisher  → +Observable01 : Creates Observable instance associated to the "Subcriber-func01"
    
    Subscriber →  Observable01 : subscribe(observer)
                                            ^^^^^^^^
                                      object implementing the
                                      ˂˂Observer˃˃ Interface
                                      defining handlers
                                      for arriving notifications
    Subscriber ← Observable01 :  subscription01
    .... subscriber start consuming values ...
    Subscriber → subscription01 : unsubscribe()
    
    Ex: Using an observable to provide geolocation updates.
    | // Create an Observable that will start listening to geolocation updates
    | // when a consumer subscribes.
    | const OºlocationsObservableº = new Observable((observer) =˃ {
    |   const {next, error} = observer; // get next,error callbacks, passed-in
    |                                   // when consumer subscribes.
    |
    |   let watchId = navigator.geolocation.watchPosition(next, error);
    |
    |   return { // reset when consumer unsubscribes
    |     unsubscribe() { navigator.geolocation.clearWatch(watchId); }
    |   };
    | });
    |
    | const BºlocationsSubscriptionº =
    |           OºlocationsObservableº.subscribe({
    |           Oº                   º.^^^^^^^^^
    |           O*                 *// start listening
    |           O*                 *// for updates
    |
    |   next(position) { console.log(position *1);       },
    |   error(msg)     { console.log('Error: ', msg); }
    | });
    |
    | ...
    | locationsSubscription.unsubscribe();
    |
    | *1: message strings, event object, numeric value or structures
    |
    
    ˂˂Observer˃˃
    Notification type   Description
    next     (req)      handler for each delivered value.
    error    (opt)      handler for error notification.
                        An error halts execution of the observable instance.
    complete (opt)      A handler for the execution-complete
                        notification.
    
    MULTICASTING
    
    - each subscription/observer gets the same value
    - With a multicasting observable, you don't register multiple listeners
      on the document, but instead re-use the first listener and send
      values out to each subscriber.
    
    Ex: // @ma
    
        function sequenceSubscriber(observer) {
          const seq = [1, 2, 3];
          let timeoutId;
    
          // Will run through an array of numbers, emitting one value
          // per second until it gets to the end of the array.
          function doSequence(arr, idx) {
            timeoutId = setTimeout(() =˃ {
              observer.next(arr[idx]);
              if (idx === arr.length - 1) {
                observer.complete();
              } else {
                doSequence(arr, ++idx);
              }
            }, 1000);
          }
    
          doSequence(seq, 0);
    
          // Unsubscribe should clear the timeout to stop execution
          return {unsubscribe() {
            clearTimeout(timeoutId);
          }};
        }
    
        // Create a new Observable that will deliver the above sequence
        const sequence = new Observable(sequenceSubscriber);
    
        sequence.subscribe({
          next(num) { console.log(num); },
          complete() { console.log('Finished sequence'); }
        });
    
        // Logs:
        // (at 1 second): 1
        // (at 2 seconds): 2
        // (at 3 seconds): 3
        // (at 3 seconds): Finished sequence
    
    
    
    
    Notice that if you subscribe twice, there will be two separate streams, each emitting values every second. It looks something like this:
    Two subscriptions
    
    
    
        // Subscribe starts the clock, and will emit after 1 second
        sequence.subscribe({
          next(num) { console.log('1st subscribe: ' + num); },
          complete() { console.log('1st sequence finished.'); }
        });
    
        // After 1/2 second, subscribe again.
        setTimeout(() =˃ {
          sequence.subscribe({
            next(num) { console.log('2nd subscribe: ' + num); },
            complete() { console.log('2nd sequence finished.'); }
          });
        }, 500);
    
        // Logs:
        // (at 1 second): 1st subscribe: 1
        // (at 1.5 seconds): 2nd subscribe: 1
        // (at 2 seconds): 1st subscribe: 2
        // (at 2.5 seconds): 2nd subscribe: 2
        // (at 3 seconds): 1st subscribe: 3
        // (at 3 seconds): 1st sequence finished
        // (at 3.5 seconds): 2nd subscribe: 3
        // (at 3.5 seconds): 2nd sequence finished
    
    
    
    
    Changing the observable to be multicasting could look something like this:
    Create a multicast subscriber
    
    
    
        function multicastSequenceSubscriber() {
          const seq = [1, 2, 3];
          // Keep track of each observer (one for every active subscription)
          const observers = [];
          // Still a single timeoutId because there will only ever be one
          // set of values being generated, multicasted to each subscriber
          let timeoutId;
    
          // Return the subscriber function (runs when subscribe()
          // function is invoked)
          return (observer) =˃ {
            observers.push(observer);
            // When this is the first subscription, start the sequence
            if (observers.length === 1) {
              timeoutId = doSequence({
                next(val) {
                  // Iterate through observers and notify all subscriptions
                  observers.forEach(obs =˃ obs.next(val));
                },
                complete() {
                  // Notify all complete callbacks
                  observers.slice(0).forEach(obs =˃ obs.complete());
                }
              }, seq, 0);
            }
    
            return {
              unsubscribe() {
                // Remove from the observers array so it's no longer notified
                observers.splice(observers.indexOf(observer), 1);
                // If there's no more listeners, do cleanup
                if (observers.length === 0) {
                  clearTimeout(timeoutId);
                }
              }
            };
          };
        }
    
        // Run through an array of numbers, emitting one value
        // per second until it gets to the end of the array.
        function doSequence(observer, arr, idx) {
          return setTimeout(() =˃ {
            observer.next(arr[idx]);
            if (idx === arr.length - 1) {
              observer.complete();
            } else {
              doSequence(observer, arr, ++idx);
            }
          }, 1000);
        }
    
        // Create a new Observable that will deliver the above sequence
        const multicastSequence = new Observable(multicastSequenceSubscriber());
    
        // Subscribe starts the clock, and begins to emit after 1 second
        multicastSequence.subscribe({
          next(num) { console.log('1st subscribe: ' + num); },
          complete() { console.log('1st sequence finished.'); }
        });
    
        // After 1 1/2 seconds, subscribe again (should "miss" the first value).
        setTimeout(() =˃ {
          multicastSequence.subscribe({
            next(num) { console.log('2nd subscribe: ' + num); },
            complete() { console.log('2nd sequence finished.'); }
          });
        }, 1500);
    
        // Logs:
        // (at 1 second): 1st subscribe: 1
        // (at 2 seconds): 1st subscribe: 2
        // (at 2 seconds): 2nd subscribe: 2
        // (at 3 seconds): 1st subscribe: 3
        // (at 3 seconds): 1st sequence finished
        // (at 3 seconds): 2nd subscribe: 3
        // (at 3 seconds): 2nd sequence finished
    
    Multicasting observables take a bit more setup, but they can be useful for
    certain applications. Later we will look at tools that simplify the process
    of multicasting, allowing you to take any observable and make it multicasting.
    
    ºError handlingº
    Because observables produce values asynchronously, try/catch will not
    effectively catch errors. Instead, you handle errors by specifying an error
    callback on the observer. Producing an error also causes the observable to
    clean up subscriptions and stop producing values. An observable can either
    produce values (calling the next callback), or it can complete, calling
    either the complete or error callback.
    
    myObservable.subscribe({
      next(num) { console.log('Next num: ' + num)},
      error(err) { console.log('Received an errror: ' + err)}
    });
    
    
    
    Error handling (and specifically recovering from an error) is covered in more detail in a later section.:
    
    Client-server interaction
    HTTP
    @[https://angular.io/guide/http]
    - Communicate with a server to get data, save data, and invoke server-side actions with an HTTP client.
    
    Server-side Rendering
    @[https://angular.io/guide/universal]
    - Angular Universal generates static application pages
      on the server through server-side rendering (SSR).
      This allows you to run your Angular app on the server
      in order to improve performance and show the first page
      quickly on mobile and low-powered devices, and also facilitate web crawlers.
    
    Service Workers
    @[https://angular.io/guide/service-worker-intro]
    Use a service worker to reduce dependency on the network
    significantly improving the user experience.
    
    Domain-specific libs
    Animations
    @[https://angular.io/guide/animations]
     Use Angular's animation library to animate component behavior
    without deep knowledge of animation techniques or CSS.
    
    Forms
    @[https://angular.io/guide/forms]
    Support complex data entry scenarios with HTML-based validation and dirty checking.
    
    Dev.cycle
    JIT Compilation
    @[https://angular.io/guide/aot-compiler]
    - Angular provides just-in-time (JIT) compilation for the
      development environment, and ahead-of-time (AOT) compilation
      for the production environment.
    
    Testing platform
    @[https://angular.io/guide/testing]
    - Run unit tests on your application parts as they interact with the Angular framework.
    
    Internationalization
    @[https://angular.io/guide/i18n]
    - Make your app available in multiple languages
      with Angular's internationalization (i18n) tools.
    
    Security guidelines
    @[https://angular.io/guide/security]
    - Learn about Angular's built-in protections against common
      web-app vulnerabilities and attacks such as cross-site scripting attacks.
    
    Setup, build, deploy config
    ng CLI reference
    @[https://angular.io/cli]
    -  The Angular CLI is a command-line tool that you use to create projects,
       generate application and library code, and perform a variety of
       ongoing development tasks such as testing, bundling, and deployment.
    
    Workspace Layout
    @[https://angular.io/guide/file-structure]
    
    npm packages
    @[https://angular.io/guide/npm-packages]
    - The Angular Framework, Angular CLI, and components used by Angular applications
      are packaged as npm packages and distributed
      via the npm registry. The Angular CLI creates a default package.json file,
      which specifies a starter set of packages that work well together and jointly
      support many common application scenarios.
    
    TypeScript configuration
    @[https://angular.io/guide/typescript-configuration]
     - TypeScript is the primary language for Angular application development.
    
    Browser support
    @[https://angular.io/guide/browser-support]
    - Make your apps compatible across a wide range of browsers.
    
    Building and Serving
    @[https://angular.io/guide/build]
    - Learn to define different build and proxy server configurations
      for your project, such as development, staging, and production.
    
    Deployment
    @[https://angular.io/guide/deployment]
    - Learn techniques for deploying your Angular application to a remote server.
    
    pm2+angular
    @[https://www.tecmint.com/create-and-run-angular-apps-using-angular-cli-and-pm2/#]
    
    React
    External Links
    @[https://reactjs.org/] A JS library for building user interfaces
    
    React Suspense (alt. to Redux)
    @[https://www.infoq.com/news/2018/12/react-suspense-redux-alternative]
    
    "If your primary use-case for Redux is using it as a client-side cache of
    server-side data, then Suspense could replace your redux usage. I’d consider
    it because you’d have simpler code and the ability to tame all those spinners."
    
    Native React
    @[https://www.infoq.com/articles/affordable-react-native-development]
    
    Is a React Mobile App Worth Building?
    
    React Native is a framework for developing native applications for Android
    and iOS. It is widely used by web developers, and judging by the survey for
    The State of JavaScript, it is the most used frontend framework in the web.
    Its position is even higher than AngularJS. The first and the most important
    advantage of using this technology is the fact that you can get two React
    Native mobile applications for the price of one.
    
    The main benefits of React Native mobile app development are:
    - Instant feedback
    - Common set of tools for web and mobile development
    - Almost identical code base for iOS and Android
    - Declarative way of developing React mobile UI
    
    React+Flux Docker Dev Workflow
    @[https://medium.com/@tribou/react-and-flux-a-docker-development-workflow-469957f3bbf0]
    
    Hooks:Reusable+Composable
    Logic in Components
    
    XML
    ...
    
    SOAP
    ...
    
    See also: WS-Security
    - SOAP extension.
    - It specifies how ºintegrity and confidentialityº can be
      enforced ºon messagesº and allows the communication of
      various security token formats, such as:
      - Security Assertion Markup Language (SAML)
      - Kerberos
      - X.509.
    
    
    SAML
    ...
    
    OASIS WSS
    @[https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss]
    
    V8 JS 7.x Perf Improvements
    @[https://www.infoq.com/news/2019/07/v8-76-google-js-engine/]
    
    Unclassified
    WebRTC
    - http://gingertech.net/2014/01/08/use-deck-js-as-a-remote-presentation-tool/
    - http://www.html5rocks.com/en/tutorials/getusermedia/intro/
    
    HTTP/3: From root to tip
    @[https://blog.cloudflare.com/http-3-from-root-to-tip/]
    
    Progressive Web Apps
    - Web apps are apps built using standard Web technologies. They work in any
      modern Web browser, and can be developed using your favorite tools. Some
      characteristics that distinguish Web apps from websites: Apps are installed
      by a user, they are self-contained and don't always require the chrome of a
      browser window, and they can be built to run offline. Gmail, Twitter, and
      Etherpad are Web apps.
    
    - The Mozilla Open Web Apps project proposes some small additions to existing
      sites to turn them into apps that run in a rich, fun, and powerful computing
      environment. These apps run on desktop browsers and mobile devices, and are
      easier for a user to discover and launch than Web sites. They have access to
      a growing set of novel features, such as synchronizing across all of a user's devices.
    
    Mortar: Quick Build WebApp
    Android WebApp integration
    Test you mobile web app with WebDriver
    
    OpenAPI Spec 3.x
    @[https://swagger.io/specification/]
    Introduction
    
    The OpenAPI Specification (OAS) defines a standard, language-agnostic
    interface to RESTful APIs which allows both humans and computers to discover
    and understand the capabilities of the service without access to source code,
    documentation, or through network traffic inspection. When properly defined,
    a consumer can understand and interact with the remote service with a minimal
    amount of implementation logic.
    
    An OpenAPI definition can then be used by documentation generation tools to
    display the API, code generation tools to generate servers and clients in
    various programming languages, testing tools, and many other use cases .
    
    TOP Open APIs
    REF: @[https://projects.tmforum.org/wiki/display/API/Open+API+Table]
    TM Forum Open APIs
    
    ºAccount Management APIº
    Provides standardized mechanism for the management of billing and settlement
    accounts, as well as for financial accounting (account receivable) either in
    B2B or B2B2C contexts
    
    ºAppointment APIº
    The appointment API provides a standardized mechanism to book an appointment
    with all the necessary appointment characteristics. The API allows searching
    of free slots based on parameters, as for example a party, then creating the
    appointment. The appointment has characteristics such as nature of appointment
    , place of appointment.
    
    ºCustomer Management APIº
    Provides a standardized mechanism for customer and customer account management
    , such as creation, update, retrieval, deletion and notification of
    events.
    
    ºPartnership Type Management APIº
    Standardized mechanisms for creating partnership types. It is one of the APIs
    involved in an onboarding process. Identifies a type of a partnership between
    parties, including the list of role types that are permitted (i.e Buyer,
    Seller, Developer). Role types may refer to agreement specifications to be
    signed by parties playing the role.
    The API allows the retrieval, creation, update, and deletion of partnership
    type and its owned sub-resources.
    
    ºParty Management APIº
    Provides a standardized mechanism for party management such as creation,
    update, retrieval, deletion and notification of events.
    Party can be an individual or an organization that has any kind of
    relationship with the enterprise.
    
    ºParty Role Management APIº
    A standardized mechanism for general party roles and includes operations such
    as creation, update, retrieval, deletion and notification of events. Notice
    that for the management of customers there is a specific Customer Management API.
    Party Role management API manages the following data resources: PartyRole
    
    ºProduct Catalog Management APIº
    Provides a standardized solution for rapidly adding partners’ products to an
    existing Catalog. It brings the capability for Service Providers to directly
    feed partners systems with the technical description of the products they
    propose to them.
    
    ºProduct Inventory Management APIº
    Provides standardized mechanism for product inventory management such as
    creation, partial or full update and retrieval of the representation of a
    product in the inventory. It also allows the notification of events related
    to product lifecycle.
    
    ºProduct Offering Qualification APIº
    Product Offering Qualification API is one of Pre-Ordering Management API
    Family. Product Offering Qualification API goal is to provide Product
    Offering commercial eligibility.
    
    
    ºProduct Ordering APIº
    Provides a standardized mechanism for placing a product order with all of the
    necessary order parameters. The API consists of a simple set of operations
    that interact with CRM/Order negotiation systems in a consistent manner. A
    product order is created based on a product offering that is defined in a
    catalog. The product offering identifies the product or set of products that
    are available to a customer and includes characteristics such as pricing,
    product options and market.
    
    ºQuote Management APIº
    The Quote API is one of the Pre-Ordering Management APIs. The customer Quote
    API provides a standardized mechanism for placing a customer quote with all
    of the necessary quote parameters.
    
    ºShopping Cart APIº
    A standardized mechanism for the management of shopping carts. Including
    creation, update, retrieval, deletion and notification of an event. Shopping
    Cart entity is used for the temporary selection and reservation of product
    offerings in e-commerce and retail purchase.
    
    ºTrouble Ticket APIº
    Provides a standardized client interface to Trouble Ticket Management Systems
    for creating, tracking and managing trouble tickets among partners as a
    result of an issue or problem identified by a customer or another system.
    Examples of Trouble Ticket API clients include CRM applications, network
    management or fault management systems, or other trouble ticket management
    systems (e.g. B2B).
    
    ºAgreement Management APIº
    The Agreement API provides a standardized mechanism for managing agreements,
    especially in the context of partnerships between partners.
    
    
    ºCommunication APIº
    Provides a capability to create and send communications, notifications, and
    instructions to Parties, Individuals, Organizations or Users.
    
    ºEntity Catalog Management APIº
    The entity catalog is intended to provide any SID entity to consumers via a
    catalog, with its specification and policy providing governance over its
    content. The API provides management of the entity specifications and their
    associations thru CRUD operations.
    
    
    ºFederated Identity APIº
    The management of principals of any kind (persons, objects, …) and their
    access to resources in an open environment which can span across different
    enterprise boundaries. It relies on authentication, authorization and consent
    mechanisms to protect privacy with a simple and easy user experience.
    Different parties can provide identity services (operators, social networks, GSMA, …).
    
    
    ºGeographic Address Management APIº
    Provides a standardized client interface to an Address management system. It
    allows looking for worldwide addresses. It can also be used to validate
    geographic address data, to be sure that it corresponds to a real geographic
    address. Finally, it can be used to look for a geographic address by:
    searching an area as a start (city, town ...), then zooming on the streets of
    this area, and finally listing all the street segments (numbers) in a street.
    
    ºGeographic Location Management APIº
    Provides the information of a geographic region of the entity (customer,
    equipment, address).
    
    
    ºGeographic Site Management APIº
    Covers the operations to manage (create, read, delete) sites that can be
    associated with a customer, account, service delivery or other entities. This
    API defines a Site as a convenience class that allows easy reference to
    places important to other entities, where a geographic place is an entity
    that can answer the question “where?”
    
    
    ºLoyalty Management APIº
    Supports the management of loyalty program specifications, loyalty program
    members, their associated products and loyalty accounts with loyalty balances
    
    
    ºPartnership Type Management APIº
    Standardized mechanisms for creating partnership types. It is one of the APIs
    involved in an onboarding process. Identifies a type of a partnership between
    parties, including the list of role types that are permitted (i.e Buyer,
    Seller, Developer). Role types may refer to agreement specifications to be
    signed by parties playing the role.
    The API allows the retrieval, creation, update, and deletion of partnership
    type and its owned sub-resources.
    
    
    ºParty Interaction Management APIº
    A User Interaction captures information about past interactions in order to re
    -use it in future ones. This allows agents to serve users better by knowing
    the steps they went through. It also allows customers to see better the
    actions they have performed and how they interacted with us.
    
    
    ºParty Management APIº
    Provides a standardized mechanism for party management such as creation,
    update, retrieval, deletion and notification of events.
    Party can be an individual or an organization that has any kind of
    relationship with the enterprise.
    
    
    ºParty Role Management APIº
    A standardized mechanism for general party roles and includes operations such
    as creation, update, retrieval, deletion and notification of events. Notice
    that for the management of customers there is a specific Customer Management
    API.
    Party Role management API manages the following data resources: PartyRole
    
    
    ºPayment Management APIº
    The Payments API provides the standardized client interface to Payment
    Systems for notifying about performed payments or refunds. Examples of
    Payment API originators (clients) include Web servers, mobile app servers,
    Contact center dashboards or retail store systems.
    
    ºPayment Methods APIº
    This API supports the frequently-used payment methods for the customer to
    choose and pay the usage, including voucher card, coupon, and money transfer.
    
    ºPrepay Balance Management APIº
    REST API for Balance Management. It includes the model definition as well as
    all available operations for prepay balance management. Prepaid subscribers
    pay fees before using services. Therefore, the subscribers must have
    sufficient balances. Operators can provide multiple recharge channels for
    subscribers. Subscribers can pass credit between different subscriptions,
    therefore transferring the balance from one account to another.
    
    ºPrivacy Management APIº
    The Privacy management APIprovidesstandardizedmechanismfor privacy profile
    types, privacy profiles and privacy agreements such as creation, update,
    retrieval, deletion and notification of events..
    
    ºProduct Catalog Management APIº
    Provides a standardized solution for rapidly adding partners’ products to an
    existing Catalog. It brings the capability for Service Providers to directly
    feed partners systems with the technical description of the products they
    propose to them.
    
    ºProduct Inventory Management APIº
    Provides standardized mechanism for product inventory management such as
    creation, partial or full update and retrieval of the representation of a
    product in the inventory. It also allows the notification of events related
    to product lifecycle.
    
    ºProduct Offering Qualification APIº
    Product Offering Qualification API is one of Pre-Ordering Management API
    Family. Product Offering Qualification API goal is to provide Product
    Offering commercial eligibility.
    
    ºProduct Ordering APIº
    Provides a standardized mechanism for placing a product order with all of the
    necessary order parameters. The API consists of a simple set of operations
    that interact with CRM/Order negotiation systems in a consistent manner. A
    product order is created based on a product offering that is defined in a
    catalog. The product offering identifies the product or set of products that
    are available to a customer and includes characteristics such as pricing,
    product options and market.
    
    ºQuote Management APIº
    The Quote API is one of the Pre-Ordering Management APIs. The customer Quote
    API provides a standardized mechanism for placing a customer quote with all
    of the necessary quote parameters.
    
    ºResource Catalog Management APIº
    The Resource Catalog Management API REST specification allows the management
    of the entire lifecycle of the Resource Catalog elements and the consultation
    of resource catalog elements during several processes such as ordering
    process.
    
    ºResource Function Activation and Configuration APIº
    This API introduces Resource Function which is used to represent a Network
    Service as well as a Network Function. The Network Service and Network
    Function class definitions and associations in TR244 (which, in turn, builds
    on concepts from the SID addenda on Logical Resource and Service) are
    utilized to define the Resource Function
    
    ºTrouble Ticket APIº
    Provides a standardized client interface to Trouble Ticket Management Systems
    for creating, tracking and managing trouble tickets among partners as a
    result of an issue or problem identified by a customer or another system.
    Examples of Trouble Ticket API clients include CRM applications, network
    management or fault management systems, or other trouble ticket management
    systems (e.g. B2B).
    
    ºUsage Consumption Management APIº
    This API should allow viewing in real-time the balance of the various buckets
    (SMS, Voice, Data for example) that a user consumes with each of his devices
    and the usages done out of the bucket. A usage report retrieves the data
    related to these balances. This API should also allow performing a direct top-
    up on the balance of a prepaid bucket with voucher references or with a given
    credit value after a payment done by a credit card or with a credit value transfer.
    
    ºUsage Management APIº
     Provides standardized mechanism for usage management such as creation, update
    , retrieval, import and export of a collection of usages. The API manages
    both rated and non-rated usage. For example, it allows a service provider to 1)
    retrieve usage generated by a partner service platform in order to rate it
    and 2) to provide rated usage to a partner for consumption follow up purposes.
    
    ºUser Roles & Permissions APIº
    A user role is defined as the entity that defines a set of privileges
    covering various functions and/or manageable assets. When a user is assigned
    a given role then it is actually allocated all the privileges defined for
    that role type and the corresponding permissions are created for that user.
    
    OpenAPI Tools
    - OepnAPI-diff
     @[https://github.com/quen2404/openapi-diff] 
    
    Canvas
    Mozilla's canvas is extended with the drawWindow() method. This method draws
    a snapshot of the contents of a DOM window into the canvas. For example,
    
    ctx.drawWindow(window, 0, 0, 100, 200, "rgb(255,255,255)");
    
    would draw the contents of the current window, in the rectangle (0,0,100,200)
    in pixels relative to the top-left of the viewport, on a white background,
    into the canvas. By specifying "rgba(255,255,255,0)" as the color, the
    contents would be drawn with a transparent background (which would be slower).
    
    It is usually a bad idea to use any background other than pure white "rgb(255,
    255,255)" or transparent, as this is what all browsers do, and many websites
    expect that transparent parts of their interface will be drawn on white background.
    
    trackingjs
    (Face detection,...)
    @[https://trackingjs.com]
    The tracking.js library brings different computer vision algorithms and techniques into the
    browser environment. By using modern HTML5 specifications, we enable you to do real-time color
     tracking, face detection and much more — all that with a lightweight core (~7 KB) and intuitive
     interface.
    
    Tensorflow.org
    Tensorflow using JS + WebGL
    @[https://js.tensorflow.org/]
    
    Monaco Editor
    VSCode,Che..
    - Blazeling fast web-editor (Used by VSCode, Che, ...)
    @[https://code.visualstudio.com/docs/editor/editingevolved]
    
    NodeJS on Windows
    @[https://www.npmjs.com/package/windows-build-tools]
    
    XSSight
    @[https://github.com/PoeBlu/XSSight]
    - script that can scan for XSS vulnerabilites and inject payloads.