diff --git a/ivette/.eslintrc.js b/ivette/.eslintrc.js
index 99d874dc84fbd8cd595d7b37c558c2af268cb6f6..7d1798cfb90ad18e1d1702b6662b11d21b9a2b1d 100644
--- a/ivette/.eslintrc.js
+++ b/ivette/.eslintrc.js
@@ -5,14 +5,18 @@ module.exports = {
     '@typescript-eslint',
   ],
   extends: [
+    'airbnb-typescript',
     'eslint:recommended',
     'plugin:react/recommended',
     'plugin:react-hooks/recommended',
     'plugin:@typescript-eslint/eslint-recommended',
     'plugin:@typescript-eslint/recommended',
   ],
+  parserOptions: {
+    project: './tsconfig.json',
+  },
   rules: {
-    "react/display-name": 'off',
+    "react/display-name": "off",
     // Allow type any, even if it should be avoided
     "@typescript-eslint/no-explicit-any": "off",
     // Allow functions without return type, even if exported function should have one
@@ -31,5 +35,34 @@ module.exports = {
       "error",
       { "destructuring": "all", "ignoreReadBeforeAssign": false }
     ],
+    // Allow declarations with char '_' as prefix/suffix
+    "no-underscore-dangle": "off",
+    // Allow return statements even if not strictly needed
+    "no-useless-return": "off",
+    // Just warn about shadowing concerning variables
+    "no-shadow": "warn",
+    "lines-between-class-members": [
+      "error", "always", { "exceptAfterSingleLine": true }
+    ],
+    // Allow ++/-- operators only in for-loops
+    "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
+    // Just warn about simple promise rejections
+    "prefer-promise-reject-errors": "warn",
+    // Force code to 80 columns, but for trailing comments
+    "max-len": ["error", { "code": 80, "ignoreTrailingComments": true, }],
+    // Allow more than one class per file, even if not a good practice
+    "max-classes-per-file": "off",
+    // Allow assignment in return statements only with outer parenthesis
+    "no-return-assign": ["error", "except-parens" ],
+    // Allow single line expressions in react
+    "react/jsx-one-expression-per-line": "off",
+    // Allow all sorts of linebreaking for operators
+    "operator-linebreak": "off",
+    // Force curly brackets on newline if some item is
+    "object-curly-newline": ["error", { "multiline": true }],
+    // Allow non-destructed assignments
+    "react/destructuring-assignment": "off",
+    // Allow console errors and warnings
+    "no-console": ["error", { allow: ["warn", "error"] }],
   }
 };
\ No newline at end of file
diff --git a/ivette/package.json b/ivette/package.json
index 4f674a7ee55d28fc5d0f1bf59ffbd578886decc7..6e6fdbb307b69d351ef934e596df1bb51d33dc79 100644
--- a/ivette/package.json
+++ b/ivette/package.json
@@ -35,6 +35,10 @@
     "electron-devtools-installer": "^2.2.4",
     "electron-webpack": "^2.8.2",
     "eslint": "^6.8.0",
+    "eslint-config-airbnb": "^18.1.0",
+    "eslint-config-airbnb-typescript": "^7.2.1",
+    "eslint-plugin-import": "^2.20.2",
+    "eslint-plugin-jsx-a11y": "^6.2.3",
     "eslint-plugin-react": "^7.19.0",
     "eslint-plugin-react-hooks": "^3.0.0",
     "html-loader": "1.0.0-alpha.0",
diff --git a/ivette/src/dome/src/renderer/text/buffers.js b/ivette/src/dome/src/renderer/text/buffers.js
index 5b67d43eceaa172baffb9c121546b4236940ec71..4711a6a063b6e31bc7372f842fea2525a189381d 100644
--- a/ivette/src/dome/src/renderer/text/buffers.js
+++ b/ivette/src/dome/src/renderer/text/buffers.js
@@ -68,7 +68,7 @@ class Proxy {
 
  */
 
-export class Buffer extends Emitter {
+export class RichTextBuffer extends Emitter {
 
   /**
      @param {object} [props] - Constructor properties (see below)
@@ -453,6 +453,6 @@ is blocked.
 
 // --------------------------------------------------------------------------
 
-export default { Buffer };
+export default { RichTextBuffer };
 
 // --------------------------------------------------------------------------
diff --git a/ivette/src/frama-c/LabViews.tsx b/ivette/src/frama-c/LabViews.tsx
index 660f46cd929c64e6cd6b49038dd27628c31e552a..db23aa4b00565938526d992d9cfecb16918d93a6 100644
--- a/ivette/src/frama-c/LabViews.tsx
+++ b/ivette/src/frama-c/LabViews.tsx
@@ -18,7 +18,7 @@ import { Label } from 'dome/controls/labels';
 import { Icon } from 'dome/controls/icons';
 import {
   Item as ItemToRender,
-  Render as RenderItem
+  Render as RenderItem,
 } from 'dome/layout/dispatch';
 import './labviews.css';
 
@@ -41,14 +41,19 @@ class Library {
 
   commit() {
     if (!_.isEqual(this.collection, this.virtual)) {
-      this.collection = Object.assign({}, this.virtual);
+      this.collection = { ...this.virtual };
       this.items = _.sortBy(this.collection, ['order', 'id']);
       this.modified = false;
       Dome.emit('labview.library');
     }
   }
 
-  useItem(id: string, gcontext: any, path: any[], props: { rank: undefined; group: any }) {
+  useItem(
+    id: string,
+    gcontext: any,
+    path: any[],
+    props: { rank: undefined; group: any },
+  ) {
     if (!this.modified) {
       this.modified = true;
       setImmediate(() => this.commit());
@@ -59,19 +64,23 @@ class Library {
       : path.slice(0, -1).concat([props.rank]);
     const group = props.group || gcontext;
     const collection: any = this.virtual;
-    collection[id] = Object.assign({ id, order, group }, props);
+    collection[id] = { id, order, group, ...props };
     return (): boolean => delete collection[id];
   }
-
 }
 
 // --------------------------------------------------------------------------
 // --- Library Components
 // --------------------------------------------------------------------------
 
-const isItemId = (fd: string, id: string) => id.startsWith(fd) && id[fd.length] === '.';
-const getItemId = (fd: string, id: string) => isItemId(fd, id) ? id.substring(fd.length + 1) : undefined;
-const getItems = (items: any[], fd: string) => items.filter((item) => isItemId(fd, item.id));
+const isItemId =
+  (fd: string, id: string) => id.startsWith(fd) && id[fd.length] === '.';
+const getItemId =
+  (fd: string, id: string) => (
+    isItemId(fd, id) ? id.substring(fd.length + 1) : undefined
+  );
+const getItems =
+  (items: any[], fd: string) => items.filter((item) => isItemId(fd, item.id));
 
 const LibraryManager = React.createContext(undefined);
 
@@ -80,31 +89,32 @@ const useLibraryItem = (fd: string, { id, ...props }: any) => {
   React.useEffect(() => {
     if (context) {
       const { group, order, library }: any = context;
-      const itemId = fd + '.' + id;
+      const itemId = `${fd}.${id}`;
       return library.useItem(itemId, group, order, props);
-    } else
-      return undefined;
+    }
+    return undefined;
   });
   return context;
 };
 
-const Rankify = ({ library, group, order, children }: any) => {
-  let rank = 0;
-  const rankify = (elt: any) => {
-    const context: any = { group, order, library };
-    context.order.concat([rank++])
+const Rankify =
+  ({ library, group, order, children }: any) => {
+    let rank = 0;
+    const rankify = (elt: any) => {
+      rank += 1;
+      const context: any = { group, order: [...order, rank], library };
+      return (
+        <LibraryManager.Provider value={context}>
+          {elt}
+        </LibraryManager.Provider>
+      );
+    };
     return (
-      <LibraryManager.Provider value={context}>
-        {elt}
-      </LibraryManager.Provider>
+      <>
+        {React.Children.map(children, rankify)}
+      </>
     );
   };
-  return (
-    <React.Fragment>
-      {React.Children.map(children, rankify)}
-    </React.Fragment>
-  );
-};
 
 const HIDDEN = { display: 'none' };
 
@@ -120,22 +130,22 @@ const UseLibrary = ({ library, children }: any) => (
    @summary Ordered collection of LabView Components.
    @description
    Renderers its children in the specified order.
-   Otherwized, elements are ordered by `rank` and `id`.
+   Otherwise, elements are ordered by `rank` and `id`.
  */
 export const Fragment = ({ group, children }: any) => {
   const context: any = React.useContext(LibraryManager);
-  if (!context)
-    return null;
-  else {
-    return (
-      <Rankify
-        group={group || context.group}
-        order={context.order}
-        library={context.library} >
-        {children}
-      </Rankify>
-    );
-  }
+
+  if (!context) return null;
+
+  return (
+    <Rankify
+      group={group || context.group}
+      order={context.order}
+      library={context.library}
+    >
+      {children}
+    </Rankify>
+  );
 };
 
 /**
@@ -157,7 +167,8 @@ export const Group = ({ children, ...props }: any) => {
     <Rankify
       group={props.id}
       order={context.order}
-      library={context.library} >
+      library={context.library}
+    >
       {children}
     </Rankify>
   );
@@ -181,7 +192,8 @@ export const Group = ({ children, ...props }: any) => {
    - `<GridVbox>…</GridVbox>` a vertical grid of `GridContent` elements;
    - `<GridItem id=…>` a single component.
 
-   These grid content components must be imported from the `dome/layout/grids` module:
+   These grid content components must be imported from the `dome/layout/grids`
+   module:
    ```
    import { GridItem, GridHbox, GridVbox } from 'dome/layout/grids';
    ```
@@ -224,16 +236,21 @@ const TitleContext: any = React.createContext(undefined);
    @property {React.Children} children - additional components to render
    @description
    Defines an alternative component title bar.
-   If specified, the icon, label and title properties are rendered in an `<Label/>` component.
-   By default, the component title bar is labelled according to the component properties.
+   If specified, the icon, label and title properties are rendered in an
+   `<Label/>` component.
+   By default, the component title bar is labelled according to the component
+   properties.
  */
 export const TitleBar = ({ icon, label, title, children }: any) => {
   const context: any = React.useContext(TitleContext);
   return (
-    <ItemToRender id={'labview.title.' + context.id}>
-      <Label className='labview-handle' icon={icon}
+    <ItemToRender id={`labview.title.${context.id}`}>
+      <Label
+        className="labview-handle"
+        icon={icon}
         label={label || context.label}
-        title={title || context.title} />
+        title={title || context.title}
+      />
       {children}
     </ItemToRender>
   );
@@ -252,7 +269,7 @@ const GRIDITEM = {
   minWidth: 40,
   minHeight: 40,
   width: 120,
-  height: 120
+  height: 120,
 };
 
 const GRIDITEM_PLAIN = { fill: 'both' };
@@ -262,41 +279,55 @@ const GRIDITEM_VPANE = { fill: 'vertical' };
 const makeGridItem = (customize: any, onClose: any) => (comp: any) => {
   const { id: libId, label, title, layout = 'PLAIN', children } = comp;
   const id = getItemId('components', libId);
-  const properties: any = Object.assign({}, GRIDITEM);
+  let properties: any = { ...GRIDITEM };
   switch (layout) {
     case 'PLAIN':
-      Object.assign(properties, GRIDITEM_PLAIN);
+      properties = { ...properties, ...GRIDITEM_PLAIN };
       break;
     case 'HPANE':
-      Object.assign(properties, GRIDITEM_HPANE);
+      properties = { ...properties, GRIDITEM_HPANE };
       break;
     case 'VPANE':
-      Object.assign(properties, GRIDITEM_VPANE);
+      properties = { ...properties, GRIDITEM_VPANE };
       break;
     default:
       console.warn(`[labviews] unexpected layout for ${id} component`, layout);
       break;
   }
-  for (const fd in properties) {
-    const prop = comp[fd];
-    if (prop) properties[fd] = prop;
-  }
+  Object.keys(properties).forEach((key) => {
+    const prop = comp[key];
+    if (prop) properties[key] = prop;
+  });
   let CLOSING;
-  if (customize) CLOSING = (
-    <IconButton
-      className='labview-close'
-      offset={-1} icon='CROSS'
-      onClick={() => onClose(id)} />
-  );
+  if (customize) {
+    CLOSING = (
+      <IconButton
+        className="labview-close"
+        offset={-1}
+        icon="CROSS"
+        onClick={() => onClose(id)}
+      />
+    );
+  }
   return (
-    <GridItem id={id} {...properties}>
-      <Vfill className='labview-content'>
-        <Hbox className='labview-titlebar'>
+    <GridItem
+      id={id}
+      className={properties.className}
+      handle={properties.handle}
+      resize={properties.resize}
+      fill={properties.fill}
+      shrink={properties.shrink}
+      minWidth={properties.minWidth}
+      minHeight={properties.minHeight}
+      width={properties.width}
+      height={properties.height}
+    >
+      <Vfill className="labview-content">
+        <Hbox className="labview-titlebar">
           <Hfill>
             <Catch title={id}>
-              <RenderItem id={'labview.title.' + id}>
-                <Label className='labview-handle'
-                  label={label} title={title} />
+              <RenderItem id={`labview.title.${id}`}>
+                <Label className="labview-handle" label={label} title={title} />
               </RenderItem>
             </Catch>
           </Hfill>
@@ -324,15 +355,23 @@ function CustomViews({ settings, shape, setShape, views: libViews }: any) {
   const theViews: any = {};
 
   _.forEach(libViews, (view) => {
-    const { id: origin, order, label = '(Stock View)', title, defaultView } = view;
-    const id = 'builtin.' + origin;
-    theViews[id] = { id, order, label, title, builtin: true, defaultView, origin };
+    const {
+      id: origin,
+      order,
+      label = '(Stock View)',
+      title, defaultView,
+    } = view;
+    const id = `builtin.${origin}`;
+
+    theViews[id] =
+      { id, order, label, title, builtin: true, defaultView, origin };
   });
 
   _.forEach(customs, (view) => {
     const { id, order, label = '(Custom View)', title, origin } = view;
-    if (id && !theViews[id])
+    if (id && !theViews[id]) {
       theViews[id] = { id, order, label, title, builtin: false, origin };
+    }
   });
 
   const getStock = (origin: any) => (
@@ -370,21 +409,25 @@ function CustomViews({ settings, shape, setShape, views: libViews }: any) {
     const RENAME = () => setEdited(id);
 
     const DUPLICATE = () => {
-      const base = 'custom.' + view.origin;
+      const base = `custom.${view.origin}`;
       const stock = getStock(view.origin);
-      let k = 1, newId = base;
-      while (theViews[newId]) newId = base + '~' + (++k);
+      let k = 1;
+      let newId = base;
+      while (theViews[newId]) {
+        k += 1;
+        newId = `${base}~${k}`;
+      }
       let newOrder = view.order;
       if (newOrder && newOrder.concat) newOrder = newOrder.concat([k]);
-      let newLabel = 'Custom ' + stock.label;
-      if (k > 1) newLabel += '~' + k;
+      let newLabel = `Custom ${stock.label}`;
+      if (k > 1) newLabel += `~${k}`;
       customs[newId] = {
         id: newId,
         label: newLabel,
         order: newOrder,
-        title: 'Derived from ' + stock.label,
+        title: `Derived from ${stock.label}`,
         origin: view.origin,
-        builtin: false
+        builtin: false,
       };
       setCustoms(customs);
       if (current) shapes[current] = shape;
@@ -401,11 +444,11 @@ function CustomViews({ settings, shape, setShape, views: libViews }: any) {
     };
 
     Dome.popupMenu([
-      { label: "Rename View", display: (!edited && isCustom), onClick: RENAME },
-      { label: "Restore Default", display: isCurrent, onClick: DEFAULT },
-      { label: "Duplicate View", onClick: DUPLICATE },
+      { label: 'Rename View', display: (!edited && isCustom), onClick: RENAME },
+      { label: 'Restore Default', display: isCurrent, onClick: DEFAULT },
+      { label: 'Duplicate View', onClick: DUPLICATE },
       'separator',
-      { label: "Remove View", display: isCustom, onClick: REMOVE }
+      { label: 'Remove View', display: isCustom, onClick: REMOVE },
     ]);
   };
 
@@ -420,45 +463,52 @@ function CustomViews({ settings, shape, setShape, views: libViews }: any) {
         setEdited(undefined);
       };
       const FIELD = (
-        <Field className='labview-field'
-          placeholder='View Name'
-          autoFocus value={label}
-          onEnter={RENAMED} />
+        <Field
+          className="labview-field"
+          placeholder="View Name"
+          autoFocus
+          value={label}
+          onEnter={RENAMED}
+        />
       );
       return (
-        <Item key={id} id={id} icon='DISPLAY' title={title} label={FIELD} />
-      );
-    } else {
-      const FLAGS = [];
-      if (builtin) FLAGS.push('LOCK');
-      return (
-        <Item
-          key={id} id={id}
-          icon='DISPLAY'
-          label={label}
-          title={title}
-          selected={id && current === id}
-          onSelection={SELECT}
-          onContextMenu={POPUP}
-        >
-          {FLAGS.map((icn) => (
-            <Icon key={icn} className='labview-icon' size={9} offset={1} id={icn} />
-          ))}
-        </Item>
+        <Item key={id} id={id} icon="DISPLAY" title={title} label={FIELD} />
       );
     }
+    const FLAGS = [];
+    if (builtin) FLAGS.push('LOCK');
+    return (
+      <Item
+        key={id}
+        id={id}
+        icon="DISPLAY"
+        label={label}
+        title={title}
+        selected={id && current === id}
+        onSelection={SELECT}
+        onContextMenu={POPUP}
+      >
+        {FLAGS.map((icn) => (
+          <Icon
+            key={icn}
+            className="labview-icon"
+            size={9}
+            offset={1}
+            id={icn}
+          />
+        ))}
+      </Item>
+    );
   };
 
   if (!current && !triggerDefault.current) {
     const theDefault = _.find(theViews, (item) => item.defaultView);
     triggerDefault.current = theDefault;
-    if (theDefault) setTimeout(() => {
-      SELECT(theDefault.id);
-    });
+    if (theDefault) setTimeout(() => { SELECT(theDefault.id); });
   }
 
   return (
-    <Section label='Views'>
+    <Section label="Views">
       {_.sortBy(theViews, ['order', 'id']).map(makeViewItem)}
     </Section>
   );
@@ -470,17 +520,26 @@ function CustomViews({ settings, shape, setShape, views: libViews }: any) {
 
 const DRAGOVERLAY = { className: 'labview-stock' };
 
-function CustomGroup({ dnd, shape, setDragging, id, title, label, components }: any) {
-
+function CustomGroup(
+  { dnd, shape, setDragging, id, title, label, components }: any,
+) {
   const makeComponent = ({ id, label, title }: any) => {
     const itemId = getItemId('components', id);
     const disabled = Grids.getShapeItem(shape, itemId) !== undefined;
     return (
-      <DragSource key={id} dnd={dnd}
+      <DragSource
+        key={id}
+        dnd={dnd}
         disabled={disabled}
         overlay={disabled ? undefined : DRAGOVERLAY}
-        onStart={() => setDragging(itemId)} >
-        <Item icon='COMPONENT' disabled={disabled} label={label} title={title} />
+        onStart={() => setDragging(itemId)}
+      >
+        <Item
+          icon="COMPONENT"
+          disabled={disabled}
+          label={label}
+          title={title}
+        />
       </DragSource>
     );
   };
@@ -496,22 +555,23 @@ function CustomGroup({ dnd, shape, setDragging, id, title, label, components }:
 // --- Customization Panel
 // --------------------------------------------------------------------------
 
-function CustomizePanel({ dnd, settings, library, shape, setShape, setDragging }: any) {
-
+function CustomizePanel(
+  { dnd, settings, library, shape, setShape, setDragging }: any,
+) {
   Dome.useUpdate('labview.library');
-  const items = library.items;
+  const { items } = library;
   const views = getItems(items, 'views');
   const groups = getItems(items, 'groups');
   const components = getItems(items, 'components');
-  const settingFolds = settings && settings + '.folds';
-  const settingViews = settings && settings + '.views';
+  const settingFolds = settings && `${settings}.folds`;
+  const settingViews = settings && `${settings}.views`;
   const contents: any = {};
 
   groups.unshift({ id: 'nogroup', label: 'Components' });
-  groups.forEach((g) => contents[g.id] = []);
+  groups.forEach((g) => (contents[g.id] = []));
 
   components.forEach((c) => {
-    const gid = c.group ? 'groups.' + c.group : 'nogroup';
+    const gid = c.group ? `groups.${c.group}` : 'nogroup';
     let content = contents[gid];
     if (content === undefined) content = contents.nogroup;
     content.push(c);
@@ -520,17 +580,23 @@ function CustomizePanel({ dnd, settings, library, shape, setShape, setDragging }
   return (
     <SideBar settings={settingFolds}>
       <CustomViews
-        key='views'
+        key="views"
         settings={settingViews}
         shape={shape}
         setShape={setShape}
-        views={views} />
+        views={views}
+      />
       {groups.map((g) => (
         <CustomGroup
-          key={g.id} id={g.id}
-          label={g.label} title={g.title}
-          dnd={dnd} setDragging={setDragging} shape={shape}
-          components={contents[g.id]} />
+          key={g.id}
+          id={g.id}
+          label={g.label}
+          title={g.title}
+          dnd={dnd}
+          setDragging={setDragging}
+          shape={shape}
+          components={contents[g.id]}
+        />
       ))}
     </SideBar>
   );
@@ -541,7 +607,6 @@ function CustomizePanel({ dnd, settings, library, shape, setShape, setDragging }
 // --------------------------------------------------------------------------
 
 /**
-   @class
    @summary Reconfigurable Container (React Component)
    @property {boolean} [customize] - show components panel (false by default)
    @property {string} [settings] - window settings to make views persistent
@@ -549,17 +614,17 @@ function CustomizePanel({ dnd, settings, library, shape, setShape, setDragging }
    @description
    This container displays its content into a reconfigurable view.
 
-   The entire content is rendered, but elements must be packed into `<Component/>`
-   containers, otherwise, they would remain invisible.
-   Content may also contains `<View/>` and `<Group/>` definitions, and the content
-   can be defined through any kind of React components.
+   The entire content is rendered, but elements must be packed into
+   `<Component/>` containers, otherwise, they would remain invisible.
+   Content may also contains `<View/>` and `<Group/>` definitions, and the
+   content can be defined through any kind of React components.
 */
 export function LabView(props: any) {
   // Parameters
   const { settings, customize = false, children } = props;
-  const settingSplit = settings && settings + '.split';
-  const settingShape = settings && settings + '.shape';
-  const settingPanel = settings && settings + '.panel';
+  const settingSplit = settings && `${settings}.split`;
+  const settingShape = settings && `${settings}.shape`;
+  const settingPanel = settings && `${settings}.panel`;
   // Hooks & State
   Dome.useUpdate('labview.library', 'dome.defaults');
   const dnd = React.useMemo(() => new DnD(), []);
@@ -567,36 +632,41 @@ export function LabView(props: any) {
   const [shape, setShape] = Dome.useState(settingShape);
   const [dragging, setDragging] = React.useState();
   // Preparation
-  const onClose = (id: string) => setShape(Grids.removeShapeItem(shape, id));
-  const components = _.filter(lib.collection, (item: any) => isItemId('components', item.id));
-  const gridItems = components.map(makeGridItem(customize, onClose));
-  const holding = dragging ? gridItems.find((elt) => elt.props.id === dragging) : undefined;
+  const onClose =
+    (id: string) => setShape(Grids.removeShapeItem(shape, id));
+  const components =
+    _.filter(lib.collection, (item: any) => isItemId('components', item.id));
+  const gridItems =
+    components.map(makeGridItem(customize, onClose));
+  const holding =
+    dragging ? gridItems.find((elt) => elt.props.id === dragging) : undefined;
   // Make view
   return (
-    <React.Fragment>
+    <>
       <UseLibrary library={lib}>
         {children}
       </UseLibrary>
-      <Splitter settings={settingSplit} unfold={customize} dir='RIGHT'>
+      <Splitter settings={settingSplit} unfold={customize} dir="RIGHT">
         <GridLayout
           dnd={dnd}
           padding={2}
-          className='labview-container'
+          className="labview-container"
           items={gridItems}
           shape={shape}
           onReshape={setShape}
-          holding={holding} />
+          holding={holding}
+        />
         <CustomizePanel
           dnd={dnd}
           settings={settingPanel}
           shape={shape}
           setShape={setShape}
           setDragging={setDragging}
-          library={lib} />
+          library={lib}
+        />
       </Splitter>
-    </React.Fragment>
+    </>
   );
-
 }
 
 // --------------------------------------------------------------------------
diff --git a/ivette/src/frama-c/server.ts b/ivette/src/frama-c/server.ts
index cfb83941ed95b28ed0843b65e77dd66bccd8c253..84bf3f2d20d74dd6c5e413b5ef17b6d6ac81711c 100644
--- a/ivette/src/frama-c/server.ts
+++ b/ivette/src/frama-c/server.ts
@@ -7,12 +7,12 @@
  *  @description Manage the current Frama-C server/client interface
  */
 
-import _ from 'lodash'
-import React from 'react'
-import Dome from 'dome'
-import System from 'dome/system'
-import { Buffer } from 'dome/text/buffers'
-import { Request } from 'zeromq'
+import _ from 'lodash';
+import React from 'react';
+import Dome from 'dome';
+import System from 'dome/system';
+import { RichTextBuffer } from 'dome/text/buffers';
+import { Request } from 'zeromq';
 
 // --------------------------------------------------------------------------
 // --- Events
@@ -102,25 +102,24 @@ export enum StatusCode {
 // --------------------------------------------------------------------------
 
 let status = StatusCode.OFF;
-let error: string | undefined;     // process error
-let rqid: number;                  // Request ID
-let pending: any;                  // Pending promise callbacks
-let queueCmd: any;                 // Queue of server commands to be sent
-let queueIds: any;                 // Waiting request ids to be sent
-let polling: any;                  // Timeout Polling timer
-let flushing: any;                 // Immediate Flushing timer
+let error: string | undefined; // process error
+let rqid: number; // Request ID
+let pending: any; // Pending promise callbacks
+let queueCmd: any; // Queue of server commands to be sent
+let queueIds: any; // Waiting request ids to be sent
+let polling: any; // Timeout Polling timer
+let flushing: any; // Immediate Flushing timer
 let config: ServerConfiguration;
-let process: any;                  // Server process
-let socket: any;                   // ZMQ (REQ) socket
-let busy: boolean;                 // ZMQ socket is busy
-let killing: any;                  // killing timeout
+let process: any; // Server process
+let socket: any; // ZMQ (REQ) socket
+let busy: boolean; // ZMQ socket is busy
+let killing: any; // killing timeout
 
 // --------------------------------------------------------------------------
 // --- Server Console
 // --------------------------------------------------------------------------
 
-export const buffer = new Buffer({ maxlines: 200 });
-export const feedback = '';
+const buffer = new RichTextBuffer({ maxlines: 200 });
 
 // --------------------------------------------------------------------------
 // --- Server Status
@@ -132,7 +131,7 @@ export const feedback = '';
  *  @description
  *  See [STATUS](module-frama-c_server.html#~STATUS) code definitions.
  */
-export function getStatus(): StatusCode { return status }
+function getStatus(): StatusCode { return status; }
 
 /**
  *  @summary Hook on current server (Custom React Hook).
@@ -140,47 +139,47 @@ export function getStatus(): StatusCode { return status }
  *  @description
  *  See [STATUS](module-frama-c_server.html#~STATUS) code definitions.
  */
-export function useStatus(): StatusCode {
+function useStatus(): StatusCode {
   Dome.useUpdate(STATUS);
   return status;
 }
 
 /** Return `FAILED` status message. */
-export function getError() { return error; }
+function getError() { return error; }
 
 /**
  *  @summary Frama-C Server is running and ready to handle requests.
  *  @return {boolean} status is `RUNNING`.
  */
-export function isRunning(): boolean { return status === StatusCode.RUNNING }
+function isRunning(): boolean { return status === StatusCode.RUNNING; }
 
 /**
  *  @summary Number of requests still pending.
  *  @return {number} pending requests
  */
-export function getPending(): number {
-  return _.reduce(pending, (_, n) => n + 1, 0)
+function getPending(): number {
+  return _.reduce(pending, (_, n) => n + 1, 0);
 }
 
 /**
  *  @summary Register callback on READY event.
  *  @param {function} callback - invoked when the server enters RUNNING status
  */
-export function onReady(callback: any) { Dome.on(READY, callback) }
+function onReady(callback: any) { Dome.on(READY, callback); }
 
 /**
  *  @summary Register callback on SHUTDOWN event.
  *  @param {function} callback - invoked when the server enters SHUTDOWN status
  */
-export function onShutdown(callback: any) { Dome.on(SHUTDOWN, callback) }
+function onShutdown(callback: any) { Dome.on(SHUTDOWN, callback); }
 
 /**
  *  @summary Register callback on Signal ACTIVITY event.
  *  @*param {string} id - the signal event to listen to
  *  @*param {function} callback - invoked with `callback(signal,active)`
  */
-export function onActivity(signal: string, callback: any) {
-  Dome.on(ACTIVITY + signal, callback)
+function onActivity(signal: string, callback: any) {
+  Dome.on(ACTIVITY + signal, callback);
 }
 
 // --------------------------------------------------------------------------
@@ -188,7 +187,9 @@ export function onActivity(signal: string, callback: any) {
 // --------------------------------------------------------------------------
 
 function _status(newStatus: StatusCode, err?: string) {
-  if (Dome.DEVEL && err) console.error('[Server]', err);
+  if (Dome.DEVEL && err) {
+    console.error('[Server]', err);
+  }
   if (newStatus !== status || err) {
     const oldStatus = status;
     status = newStatus;
@@ -210,7 +211,7 @@ function _status(newStatus: StatusCode, err?: string) {
  *  If the server is being shutdown, it will reboot.
  *  Otherwise, the Frama-C Server is spawned.
  */
-export function start() {
+function start() {
   switch (status) {
     case StatusCode.OFF:
     case StatusCode.FAILED:
@@ -242,7 +243,7 @@ export function start() {
  *  When the server is shutting down, restart is canceled.
  *  Otherwise, this is a no-op.
  */
-export function stop() {
+function stop() {
   switch (status) {
     case StatusCode.STARTED:
       _kill();
@@ -274,9 +275,10 @@ export function stop() {
  *  it is hard killed and restart is canceled.
  *  Otherwize, this is no-op.
  *
- *  This function is automatically called when the `module` emits the `KILL` signal.
+ *  This function is automatically called when the `module` emits the `KILL`
+ *  signal.
  */
-export function kill() {
+function kill() {
   switch (status) {
     case StatusCode.STARTED:
     case StatusCode.RUNNING:
@@ -303,7 +305,7 @@ export function kill() {
  *  When running, try to gracefully shutdown the Server,
  *  and finally schedule a reboot on exit.
  */
-export function restart() {
+function restart() {
   switch (status) {
     case StatusCode.OFF:
     case StatusCode.FAILED:
@@ -333,7 +335,7 @@ export function restart() {
  *  When not running, clear the console and reset any error flag.
  *  Otherwised, do nothing.
  */
-export function clear() {
+function clear() {
   switch (status) {
     case StatusCode.FAILED:
       _status(StatusCode.OFF);
@@ -354,22 +356,22 @@ export function clear() {
 // --------------------------------------------------------------------------
 
 export interface ServerConfiguration {
-  env?: any;            // Process environment variables (default: `undefined`)
-  cwd?: string;        // Working directory (default: current)
-  command?: string;    // Server command (default: `frama-c`)
-  params: string[];    // Additional server arguments (default: empty)
-  sockaddr?: string;   // Server socket (default: `ipc:///.frama-c.<pid>.io`)
-  timeout?: number;    // Shutdown timeout before server is hard killed, in milliseconds (default: 300ms)
-  polling?: number;    // Server polling period, in milliseconds (default: 50ms)
-  logout?: string;     // Process stdout log file (default: `undefined`)
-  logerr?: string;     // Process stderr log file (default: `undefined`)
+  env?: any; // Process environment variables (default: `undefined`)
+  cwd?: string; // Working directory (default: current)
+  command?: string; // Server command (default: `frama-c`)
+  params: string[]; // Additional server arguments (default: empty)
+  sockaddr?: string; // Server socket (default: `ipc:///.frama-c.<pid>.io`)
+  timeout?: number; // Shutdown timeout before server is hard killed, in milliseconds (default: 300ms)
+  polling?: number; // Server polling period, in milliseconds (default: 50ms)
+  logout?: string; // Process stdout log file (default: `undefined`)
+  logerr?: string; // Process stderr log file (default: `undefined`)
 }
 
 /**
  *  @summary Configure the Server.
  *  @param {ServerConfiguration} sc - Server Configuration
  */
-export function configure(sc: ServerConfiguration) {
+function configure(sc: ServerConfiguration) {
   config = sc || {};
 }
 
@@ -379,7 +381,7 @@ export function configure(sc: ServerConfiguration) {
  *  @description
  *  See `configure()` method.
  */
-export function getConfig(): ServerConfiguration {
+function getConfig(): ServerConfiguration {
   return config;
 }
 
@@ -389,28 +391,41 @@ export function getConfig(): ServerConfiguration {
 
 async function _launch() {
   _reset();
-  if (!config) throw ('Frama-C Server not configured');
-  let { env, cwd, command = 'frama-c', params = [], sockaddr, logout, logerr } = config;
+  if (!config) {
+    throw new Error('Frama-C Server not configured');
+  }
+  let {
+    env,
+    cwd,
+    command = 'frama-c',
+    params = [],
+    sockaddr,
+    logout,
+    logerr,
+  } = config;
 
   buffer.clear();
   buffer.append('$', command);
   const size = params.reduce((n: any, p: any) => n + p.length, 0);
-  if (size < 40)
+  if (size < 40) {
     buffer.append('', ...params);
-  else
+  } else {
     params.forEach((argv: string) => {
-      if (argv.startsWith('-') || argv.endsWith('.c') || argv.endsWith('.i') || argv.endsWith('.h'))
+      if (argv.startsWith('-') || argv.endsWith('.c')
+        || argv.endsWith('.i') || argv.endsWith('.h')) {
         buffer.append('\n    ');
+      }
       buffer.append(' ');
       buffer.append(argv);
     });
+  }
   buffer.append('\n');
 
   if (!cwd) cwd = System.getWorkingDir();
   if (!sockaddr) {
-    const socketfile = System.join(cwd, '.frama-c.' + System.getPID() + '.io');
+    const socketfile = System.join(cwd, `.frama-c.${System.getPID()}.io`);
     System.atExit(() => System.remove(socketfile));
-    sockaddr = 'ipc://' + socketfile;
+    sockaddr = `ipc://${socketfile}`;
   }
   logout = logout && System.join(cwd, logout);
   logerr = logerr && System.join(cwd, logerr);
@@ -419,14 +434,15 @@ async function _launch() {
     cwd,
     stdout: { path: logout, pipe: true },
     stderr: { path: logerr, pipe: true },
-    env
+    env,
   };
   // Launch Process
   const process = await System.spawn(command, params, options);
   const logger = (text: string | string[]) => {
     buffer.append(text);
-    if (0 <= text.indexOf('\n'))
+    if (text.indexOf('\n') >= 0) {
       buffer.scroll(undefined, undefined);
+    }
   };
   process.stdout.on('data', logger);
   process.stderr.on('data', logger);
@@ -435,8 +451,8 @@ async function _launch() {
     _close(err);
   });
   process.on('exit', (status: StatusCode, signal: string) => {
-    signal && buffer.log('Signal:', signal);
-    status && buffer.log('Exit:', status);
+    if (signal) buffer.log('Signal:', signal);
+    if (status) buffer.log('Exit:', status);
     _close(signal || status);
   });
   // Connect to Server
@@ -561,28 +577,31 @@ class Signal {
       }
     }
   }
-
 }
 
-//--- Memo
+// --- Memo
 
 const signals: any[] = [];
 function _signal(id: any) {
   let s = signals[id];
-  if (!s) s = signals[id] = new Signal(id);
+  if (!s) {
+    signals[id] = new Signal(id);
+    s = signals[id];
+  }
   return s;
 }
 
-//--- External API
+// --- External API
 
 /**
  *  @summary Register a Signal callback.
  *  @param {string} id - the signal event to listen to
  *  @param {function} callback - the callback to call on received signal
  *  @description
- *  If the server is not yet listening to this signal, a `SIGON` command is sent.
+ *  If the server is not yet listening to this signal, a `SIGON` command is
+ *  sent.
  */
-export function onSignal(id: string, callback: any) {
+function onSignal(id: string, callback: any) {
   _signal(id).on(callback);
 }
 
@@ -594,7 +613,7 @@ export function onSignal(id: string, callback: any) {
  *  When no more callbacks are listening to this signal for a while,
  *  the server will be notified with a `SIGOFF` command.
  */
-export function offSignal(id: string, callback: any) {
+function offSignal(id: string, callback: any) {
   _signal(id).off(callback);
 }
 
@@ -603,14 +622,14 @@ export function offSignal(id: string, callback: any) {
  *  @param {string} id - the signal event to listen to
  *  @param {function} callback - the callback to be called on signal
  */
-export function useSignal(id: string, callback: any) {
+function useSignal(id: string, callback: any) {
   React.useEffect(() => {
     onSignal(id, callback);
     return () => { offSignal(id, callback); };
-  })
+  });
 }
 
-//--- Server Synchro
+// --- Server Synchro
 
 Dome.on(READY, () => {
   _.forEach(signals, (s) => s.sigon());
@@ -628,14 +647,14 @@ Dome.on(SHUTDOWN, () => {
  *  @typedef RqKind
  *  @summary Request kind.
  *  @description
- *   - `GET` Used to read data from the server 
+ *   - `GET` Used to read data from the server
  *   - `SET` Used to write data into the server
  *   - `EXEC` Used to make the server execute a task
  */
 export enum RqKind {
-  GET = "GET",
-  SET = "SET",
-  EXEC = "EXEC"
+  GET = 'GET',
+  SET = 'SET',
+  EXEC = 'EXEC'
 }
 
 /**
@@ -648,10 +667,11 @@ export enum RqKind {
  *  You may _kill_ the request before its normal termination by
  *  invoking `kill()` on the returned promised.
  */
-export function send(kind: RqKind, rq: string, params: any) {
+function send(kind: RqKind, rq: string, params: any) {
   if (!isRunning()) return Promise.reject('Server not running');
   if (!rq) return Promise.reject('Undefined request');
-  const rid = 'RQ.' + rqid++;
+  const rid = `RQ.${rqid}`;
+  rqid += 1;
   const data = JSON.stringify(params);
   const promise: any = new Promise((resolve, reject) => {
     pending[rid] = { resolve, reject };
@@ -731,7 +751,7 @@ function _send() {
           .catch(() => _cancel(ids))
           .finally(() => { busy = false; Dome.emit(STATUS); });
       } else {
-        _cancel(ids)
+        _cancel(ids);
       }
     } else {
       // No pending command nor pending response
@@ -743,9 +763,13 @@ function _send() {
 
 function _receive(resp: any) {
   try {
-    let rid, data, err, cmd;
+    let rid;
+    let data;
+    let err;
+    let cmd;
     const shift = () => resp.shift().toString();
-    while (resp.length) {
+    let unknownResponse = false;
+    while (resp.length && !unknownResponse) {
       cmd = shift();
       switch (cmd) {
         case 'NONE':
@@ -778,15 +802,13 @@ function _receive(resp: any) {
           break;
         default:
           console.error('[Frama-C Server] Unknown Response:', cmd);
-          resp.length = 0;
+          unknownResponse = true;
           break;
       }
     }
   } finally {
-    if (queueCmd.length)
-      _flush();
-    else
-      _poll();
+    if (queueCmd.length) _flush();
+    else _poll();
   }
 }
 
@@ -795,14 +817,30 @@ function _receive(resp: any) {
 // --------------------------------------------------------------------------
 
 export default {
-  configure, getConfig,
-  getStatus, useStatus, buffer,
-  getError, getPending, isRunning,
-  start, stop, kill, restart, clear,
+  configure,
+  getConfig,
+  getStatus,
+  useStatus,
+  buffer,
+  getError,
+  getPending,
+  isRunning,
+  start,
+  stop,
+  kill,
+  restart,
+  clear,
   send,
-  onReady, onShutdown, onActivity,
-  onSignal, offSignal, useSignal,
-  STATUS, READY, SHUTDOWN, StatusCode
+  onReady,
+  onShutdown,
+  onActivity,
+  onSignal,
+  offSignal,
+  useSignal,
+  STATUS,
+  READY,
+  SHUTDOWN,
+  StatusCode,
 };
 
 // --------------------------------------------------------------------------
diff --git a/ivette/src/frama-c/states.ts b/ivette/src/frama-c/states.ts
index 8ae36c2358bff6e91804a92eee4a29b46a0ebe6d..9e63255e1b4f38a36da1c7323e98823b1763df15 100644
--- a/ivette/src/frama-c/states.ts
+++ b/ivette/src/frama-c/states.ts
@@ -143,10 +143,12 @@ export function useState(id: string) {
  *  The request is send asynchronously and cached until any change in
  *  `rq`, `params`, current project or server activity.
  *
- *  Default values for various situations can be defined in the options parameter,
- *  which is `undefined` unless specified, or `null` to keep the current value.
- *  For instance `{ pending: null }` will return `undefined` when off-line and in case of errors,
- *  but will keep the last received value until a new one is actually received.
+ *  Default values for various situations can be defined in the options
+ *  parameter, which is `undefined` unless specified, or `null` to keep the
+ *  current value.
+ *  For instance `{ pending: null }` will return `undefined` when off-line and
+ *  in case of errors, but will keep the last received value until a new one is
+ *  actually received.
  */
 export function useRequest(rq: string, params: any, options: any = {}) {
   const project = useProject();
@@ -159,7 +161,7 @@ export function useRequest(rq: string, params: any, options: any = {}) {
         .then(setValue)
         .catch((err: string) => {
           if (Dome.DEVEL) console.warn(`[Server] use request '${rq}':`, err);
-          const error = options.error;
+          const { error } = options;
           if (error !== null) setValue(error);
         });
     } else {
@@ -179,26 +181,38 @@ export function useRequest(rq: string, params: any, options: any = {}) {
  *  @param {string} rq - GET request name
  *  @param {any} [params] - GET request parameter (default `'null'`)
  *  @param {object} [options] - Dictionary options
- *  @param {boolean} [options.key] - The property to index an item (default `'name'`)
- *  @param {boolean} [options.offline] - Keep the dictionary when offline (default `true`)
- *  @param {boolean} [options.pending] - Keep the dictionary when pending (default `true`)
- *  @param {boolean} [options.error] - Keep the dictionary on error (default `false`)
- *  @param {function} [options.filter] - Only index items satisfying the filter (default `undefined`)
+ *  @param {boolean} [options.key] - The property to index an item
+ *         (default `'name'`)
+ *  @param {boolean} [options.offline] - Keep the dictionary when offline
+ *         (default `true`)
+ *  @param {boolean} [options.pending] - Keep the dictionary when pending
+ *         (default `true`)
+ *  @param {boolean} [options.error] - Keep the dictionary on error
+ *         (default `false`)
+ *  @param {function} [options.filter] - Only index items satisfying the filter
+ *         (default `undefined`)
  *  @return {object} [result] GET request response indexed by key
  *  @description
- *  Sends the specified GET request and returns its returned collection indexed by the provided key.
+ *  Sends the specified GET request and returns its returned collection indexed
+ *  by the provided key.
  *  Items in the collection that do have the key are not indexed.
  */
-export function useDictionary(rq: string, params: any = null, options: any = {}) {
-  const { offline = true, pending = true, error = false, key = 'name', filter } = options;
+function useDictionary(rq: string, params: any = null, options: any = {}) {
+  const {
+    offline = true,
+    pending = true,
+    error = false,
+    key = 'name',
+    filter,
+  } = options;
   const tags = useRequest(rq, params, {
     offline: offline ? null : undefined,
     pending: pending ? null : undefined,
-    error: error ? null : undefined
+    error: error ? null : undefined,
   });
   const dict = React.useMemo(() => {
     const d: any = {};
-    _.forEach(tags, tg => {
+    _.forEach(tags, (tg) => {
       const k: any = tg[key];
       if (k && (!filter || filter(tg))) d[k] = tg;
     });
@@ -225,9 +239,9 @@ class SyncState {
   constructor(id: any) {
     this.id = id;
     this.UPDATE = STATE + id;
-    this.signal = id + '.sig';
-    this.getRq = id + '.get';
-    this.setRq = id + '.set';
+    this.signal = `${id}.sig`;
+    this.getRq = `${id}.get`;
+    this.setRq = `${id}.set`;
     this.insync = false;
     this.value = undefined;
     this.update = this.update.bind(this);
@@ -237,8 +251,9 @@ class SyncState {
   }
 
   getValue() {
-    if (!this.insync && Server.isRunning())
+    if (!this.insync && Server.isRunning()) {
       this.update();
+    }
     return this.value;
   }
 
@@ -256,7 +271,6 @@ class SyncState {
       Dome.emit(this.UPDATE);
     });
   }
-
 }
 
 // --------------------------------------------------------------------------
@@ -267,11 +281,14 @@ let syncStates: any = {};
 
 function getSyncState(id: any) {
   let s: any = syncStates[id];
-  if (!s) s = syncStates[id] = new SyncState(id);
+  if (!s) {
+    syncStates[id] = new SyncState(id);
+    s = syncStates[id];
+  }
   return s;
 }
 
-Server.onShutdown(() => syncStates = {});
+Server.onShutdown(() => (syncStates = {}));
 
 // --------------------------------------------------------------------------
 // --- Synchronized State Hooks
@@ -287,7 +304,7 @@ Server.onShutdown(() => syncStates = {});
  *  - sends a `<id>.set` request to update the value of the state;
  *  - listens to `<id>.sig` signal to stay in sync with server updates.
  */
-export function useSyncState(id: string) {
+function useSyncState(id: string) {
   const s = getSyncState(id);
   Dome.useUpdate(PROJECT, s.UPDATE);
   Server.useSignal(s.signal, s.update);
@@ -303,7 +320,7 @@ export function useSyncState(id: string) {
  *  - sends a `<id>.get` request to obtain the current value of the state;
  *  - listens to `<id>.sig` signal to stay in sync with server updates.
  */
-export function useSyncValue(id: string) {
+function useSyncValue(id: string) {
   const s = getSyncState(id);
   Dome.useUpdate(s.update);
   Server.useSignal(s.signal, s.update);
@@ -325,9 +342,9 @@ class SyncArray {
 
   constructor(id: string) {
     this.UPDATE = STATE + id;
-    this.signal = id + '.sig';
-    this.fetchRq = id + '.fetch';
-    this.reloadRq = id + '.reload';
+    this.signal = `${id}.sig`;
+    this.fetchRq = `${id}.fetch`;
+    this.reloadRq = `${id}.reload`;
     this.index = {};
     this.insync = false;
     this.fetch = this.fetch.bind(this);
@@ -346,9 +363,7 @@ class SyncArray {
   fetch() {
     this.insync = true;
     Server.send(RqKind.GET, this.fetchRq, 50)
-      .then(({
-        reload = false, removed = [], updated = [], pending = 0
-      }) => {
+      .then(({ reload = false, removed = [], updated = [], pending = 0 }) => {
         let reloaded = false;
         if (reload) {
           reloaded = this.isEmpty();
@@ -361,7 +376,7 @@ class SyncArray {
           this.index[item.key] = item;
         });
         if (reloaded || removed.length || updated.length) {
-          this.index = Object.assign({}, this.index);
+          this.index = { ...this.index };
           Dome.emit(this.UPDATE);
         }
         if (pending > 0) {
@@ -376,7 +391,6 @@ class SyncArray {
     this.insync = false;
     Dome.emit(this.UPDATE);
   }
-
 }
 
 // --------------------------------------------------------------------------
@@ -395,7 +409,7 @@ function getSyncArray(id: string) {
   return a;
 }
 
-Server.onShutdown(() => syncArrays = {});
+Server.onShutdown(() => (syncArrays = {}));
 
 // --------------------------------------------------------------------------
 // --- Synchronized Array Hooks
@@ -440,12 +454,12 @@ setStateDefault(SELECTION, {});
  *  @return {array} `[selection,update]` for the current selection
  *  @description
  *  The selection is an object with many independant fields.
- *  You update it by providing only some fields, the other ones being kept unchanged,
- *  like the `setState()` behaviour of React components.
+ *  You update it by providing only some fields, the other ones being kept
+ *  unchanged, like the `setState()` behaviour of React components.
  */
 export function useSelection() {
   const [state, setState] = useState(SELECTION);
-  return [state, (upd: any) => setState(Object.assign({}, state, upd))];
+  return [state, (upd: any) => setState({ ...state, ...upd })];
 }
 
 // --------------------------------------------------------------------------
@@ -462,7 +476,8 @@ export default {
   useRequest,
   useDictionary,
   useSelection,
-  PROJECT, STATE
+  PROJECT,
+  STATE,
 };
 
 // --------------------------------------------------------------------------
diff --git a/ivette/src/renderer/ASTview.tsx b/ivette/src/renderer/ASTview.tsx
index a66f4d0d82e06eb37568a31e7cc7b97bd6998b3c..1fd9d1befb4abe282da2f0684d4d61fcbf8bb33e 100644
--- a/ivette/src/renderer/ASTview.tsx
+++ b/ivette/src/renderer/ASTview.tsx
@@ -7,11 +7,11 @@ import Server, { RqKind } from 'frama-c/server';
 import States from 'frama-c/states';
 
 import { Vfill } from 'dome/layout/boxes';
-import { Buffer } from 'dome/text/buffers';
+import { RichTextBuffer } from 'dome/text/buffers';
 import { Text } from 'dome/text/editors';
 import { Component } from 'frama-c/LabViews';
 
-import 'codemirror/mode/clike/clike.js';
+import 'codemirror/mode/clike/clike';
 import 'codemirror/theme/ambiance.css';
 
 // --------------------------------------------------------------------------
@@ -21,13 +21,16 @@ import 'codemirror/theme/ambiance.css';
 const print = (buffer: any, text: string) => {
   if (Array.isArray(text)) {
     const tag = text.shift();
-    if (tag !== '')
+    if (tag !== '') {
       buffer.openTextMarker({ id: tag });
-    text.forEach(txt => print(buffer, txt));
-    if (tag !== '')
+    }
+    text.forEach((txt) => print(buffer, txt));
+    if (tag !== '') {
       buffer.closeTextMarker();
-  } else if (typeof (text) === 'string')
+    }
+  } else if (typeof (text) === 'string') {
     buffer.append(text);
+  }
 };
 
 // --------------------------------------------------------------------------
@@ -35,9 +38,8 @@ const print = (buffer: any, text: string) => {
 // --------------------------------------------------------------------------
 
 const ASTview = () => {
-
   // Hooks
-  const buffer = React.useMemo(() => new Buffer(), []);
+  const buffer = React.useMemo(() => new RichTextBuffer(), []);
   const [select, setSelect] = States.useSelection();
   const theFunction = select && select.function;
   const theMarker = select && select.marker;
@@ -47,11 +49,12 @@ const ASTview = () => {
     buffer.clear();
     if (theFunction) {
       buffer.log('// Loading', theFunction, '…');
-      Server.send(RqKind.GET, "kernel.ast.printFunction", theFunction)
+      Server.send(RqKind.GET, 'kernel.ast.printFunction', theFunction)
         .then((data: string) => {
           buffer.clear();
-          if (!data)
+          if (!data) {
             buffer.log('// No code for function ', theFunction);
+          }
           print(buffer, data);
           if (theMarker) buffer.scroll(theMarker, undefined);
         });
@@ -69,12 +72,14 @@ const ASTview = () => {
   // Component
   return (
     <Vfill>
-      <Text buffer={buffer}
-        mode='text/x-csrc'
-        theme='ambiance'
+      <Text
+        buffer={buffer}
+        mode="text/x-csrc"
+        theme="ambiance"
         selection={theMarker}
         onSelection={onSelection}
-        readOnly />
+        readOnly
+      />
     </Vfill>
   );
 };
@@ -84,9 +89,10 @@ const ASTview = () => {
 // --------------------------------------------------------------------------
 
 export default () => (
-  <Component id='frama-c.astview'
-    label='AST'
-    title='Normalized source code representation.'
+  <Component
+    id="frama-c.astview"
+    label="AST"
+    title="Normalized source code representation."
   >
     <ASTview />
   </Component>
diff --git a/ivette/src/renderer/Application.tsx b/ivette/src/renderer/Application.tsx
index e5528cd1c5b824d6b49c07cc9cd4288b9b6f1545..e93e3d07bf67ce5b2af512769f26031922e6deb0 100644
--- a/ivette/src/renderer/Application.tsx
+++ b/ivette/src/renderer/Application.tsx
@@ -21,39 +21,46 @@ import ASTview from './ASTview';
 // --- Main View
 // --------------------------------------------------------------------------
 
-export default (function () {
-
-  const [sidebar, flipSidebar] = Dome.useSwitch('frama-c.sidebar.unfold', false);
-  const [viewbar, flipViewbar] = Dome.useSwitch('frama-c.viewbar.unfold', false);
+export default (() => {
+  const [sidebar, flipSidebar] = Dome.useSwitch(
+    'frama-c.sidebar.unfold',
+    false,
+  );
+  const [viewbar, flipViewbar] = Dome.useSwitch(
+    'frama-c.viewbar.unfold',
+    false,
+  );
 
   return (
     <Vfill>
       <Toolbar.ToolBar>
         <Toolbar.Button
-          icon='SIDEBAR' title='Show/Hide side bar'
+          icon="SIDEBAR"
+          title="Show/Hide side bar"
           selected={sidebar}
           onClick={flipSidebar}
         />
         <Controller.Control />
         <Toolbar.Filler />
         <Toolbar.Button
-          icon='ITEMS.GRID'
-          title='Customize Main View'
+          icon="ITEMS.GRID"
+          title="Customize Main View"
           selected={viewbar}
-          onClick={flipViewbar} />
+          onClick={flipViewbar}
+        />
       </Toolbar.ToolBar>
-      <Splitter dir='LEFT' settings='frame-c.sidebar.position' unfold={sidebar}>
+      <Splitter dir="LEFT" settings="frame-c.sidebar.position" unfold={sidebar}>
         <Sidebar.SideBar>
           <div>(Empty)</div>
         </Sidebar.SideBar>
         <LabView
           customize={viewbar}
-          settings='frama-c.labview'
+          settings="frama-c.labview"
         >
-          <View id='dashboard' label='Dashboard' defaultView>
-            <GridItem id='frama-c.console' />
+          <View id="dashboard" label="Dashboard" defaultView>
+            <GridItem id="frama-c.console" />
           </View>
-          <Group id='frama-c' label='Frama-C' title='Frama-C Kernel Components'>
+          <Group id="frama-c" label="Frama-C" title="Frama-C Kernel Components">
             <Controller.Console />
             <Properties />
             <ASTview />
@@ -67,7 +74,6 @@ export default (function () {
       </Toolbar.ToolBar>
     </Vfill>
   );
-
 });
 
 // --------------------------------------------------------------------------
diff --git a/ivette/src/renderer/Controller.tsx b/ivette/src/renderer/Controller.tsx
index d0ca7436fd7c6915e9fc50c1feb272632c1d4f0d..0e46c90baef4e127529e2a1a3758ced1d6722583 100644
--- a/ivette/src/renderer/Controller.tsx
+++ b/ivette/src/renderer/Controller.tsx
@@ -8,7 +8,7 @@ import Dome from 'dome';
 import { Button as ToolButton, ButtonGroup, Space } from 'dome/layout/toolbars';
 import { LED, IconButton } from 'dome/controls/buttons';
 import { Label, Code } from 'dome/controls/labels';
-import { Buffer } from 'dome/text/buffers';
+import { RichTextBuffer } from 'dome/text/buffers';
 import { Text } from 'dome/text/editors';
 
 import Server, { StatusCode, ServerConfiguration } from 'frama-c/server';
@@ -21,7 +21,7 @@ import 'codemirror/theme/ambiance.css';
 // --------------------------------------------------------------------------
 
 let cmdConfig: ServerConfiguration;
-const cmdLine = new Buffer();
+const cmdLine = new RichTextBuffer();
 
 function dumpCmdLine(sc: ServerConfiguration): void {
   const { cwd, command, sockaddr, params } = sc;
@@ -29,16 +29,19 @@ function dumpCmdLine(sc: ServerConfiguration): void {
   if (cwd) cmdLine.log('--cwd', cwd);
   if (command) cmdLine.log('--command', command);
   if (sockaddr) cmdLine.log('--socket', sockaddr);
-  if (params) params.forEach((v: string, i: number) => {
-    if (i > 0) {
-      if (v.startsWith('-') || v.endsWith('.c')
-        || v.endsWith('.h') || v.endsWith('.i'))
-        cmdLine.append('\n');
-      else
-        cmdLine.append(' ');
-    }
-    cmdLine.append(v);
-  });
+  if (params) {
+    params.forEach((v: string, i: number) => {
+      if (i > 0) {
+        if (v.startsWith('-') || v.endsWith('.c')
+          || v.endsWith('.h') || v.endsWith('.i')) {
+          cmdLine.append('\n');
+        } else {
+          cmdLine.append(' ');
+        }
+      }
+      cmdLine.append(v);
+    });
+  }
   cmdLine.append('\n');
 }
 
@@ -51,19 +54,27 @@ function buildServerConfiguration(argv: string[], cwd?: string) {
     const v = argv[k];
     switch (v) {
       case '--cwd':
-        cwdir = argv[++k];
+        k += 1;
+        cwdir = argv[k];
         break;
       case '--command':
-        command = argv[++k];
+        k += 1;
+        command = argv[k];
         break;
       case '--socket':
-        sockaddr = argv[++k];
+        k += 1;
+        sockaddr = argv[k];
         break;
       default:
         params.push(v);
     }
   }
-  return { cwd: cwdir, command, sockaddr, params };
+  return {
+    cwd: cwdir,
+    command,
+    sockaddr,
+    params,
+  };
 }
 
 Dome.onCommand((argv: string[], cwd: string) => {
@@ -79,9 +90,14 @@ Dome.onCommand((argv: string[], cwd: string) => {
 
 export const Control = () => {
   const status = Server.useStatus();
-  let play: { enabled: boolean; onClick: any } = { enabled: false, onClick: null };
-  let stop: { enabled: boolean; onClick: any } = { enabled: false, onClick: null };
-  let reload: { enabled: boolean; onClick: any } = { enabled: false, onClick: null };
+
+  let play: { enabled: boolean; onClick: any } =
+    { enabled: false, onClick: null };
+  let stop: { enabled: boolean; onClick: any } =
+    { enabled: false, onClick: null };
+  let reload: { enabled: boolean; onClick: any } =
+    { enabled: false, onClick: null };
+
   switch (status) {
     case StatusCode.OFF:
     case StatusCode.FAILED:
@@ -91,15 +107,29 @@ export const Control = () => {
       stop = { enabled: true, onClick: Server.stop };
       reload = { enabled: true, onClick: Server.restart };
       break;
+    default:
+      break;
   }
   return (
     <ButtonGroup>
-      <ToolButton icon='MEDIA.PLAY' {...play}
-        title='Start the server' />
-      <ToolButton icon='RELOAD' {...reload}
-        title='Re-start the server' />
-      <ToolButton icon='MEDIA.STOP' {...stop}
-        title='Shut down the server' />
+      <ToolButton
+        icon="MEDIA.PLAY"
+        enabled={play.enabled}
+        onClick={play.onClick}
+        title="Start the server"
+      />
+      <ToolButton
+        icon="RELOAD"
+        enabled={reload.enabled}
+        onClick={reload.onClick}
+        title="Re-start the server"
+      />
+      <ToolButton
+        icon="MEDIA.STOP"
+        enabled={stop.enabled}
+        onClick={stop.onClick}
+        title="Shut down the server"
+      />
     </ButtonGroup>
   );
 };
@@ -121,10 +151,12 @@ function execCmdLine(cmd: string) {
 
 const RenderConsole = () => {
   const [cmd, switchCmd] = Dome.useSwitch();
-  const { current, next, prev, index, length, update, insert, clear }: any = Dome.useHistory('frama-c.command.history');
+  const { current, next, prev, index, length, update, insert, clear }: any =
+    Dome.useHistory('frama-c.command.history');
+
   const doExec = () => {
     const cmd = getCmdLine();
-    if (cmd != current) insert(cmd);
+    if (cmd !== current) insert(cmd);
     execCmdLine(cmd);
     switchCmd();
   };
@@ -136,34 +168,77 @@ const RenderConsole = () => {
     cmdLine.getDoc().setValue(update(undefined) || '');
   };
   return (
-    <React.Fragment>
+    <>
       <TitleBar label={cmd ? 'Command Line' : 'Console'}>
-        <Label className='dimmed' display={cmd && length > 0}>
+        <Label className="dimmed" display={cmd && length > 0}>
           {1 + index}/{length}
         </Label>
         <Space />
-        <IconButton icon='TRASH' display={cmd && clear} disabled={!clear} onClick={clear} title='Clear History' />
-        <IconButton icon='CROSS' display={cmd && clear} disabled={!current} onClick={doDrop} title='Remove Command' />
+        <IconButton
+          icon="TRASH"
+          display={cmd && clear}
+          disabled={!clear}
+          onClick={clear}
+          title="Clear History"
+        />
+        <IconButton
+          icon="CROSS"
+          display={cmd && clear}
+          disabled={!current}
+          onClick={doDrop}
+          title="Remove Command"
+        />
         <Space />
-        <IconButton icon='MEDIA.PREV' display={cmd} disabled={!prev} onClick={doPrev} title='Previous Command' />
-        <IconButton icon='RELOAD' display={cmd} onClick={doReload} title='Reset Command Line' />
-        <IconButton icon='MEDIA.NEXT' display={cmd} disabled={!next} onClick={doNext} title='Previous Command' />
+        <IconButton
+          icon="MEDIA.PREV"
+          display={cmd}
+          disabled={!prev}
+          onClick={doPrev}
+          title="Previous Command"
+        />
+        <IconButton
+          icon="RELOAD"
+          display={cmd}
+          onClick={doReload}
+          title="Reset Command Line"
+        />
+        <IconButton
+          icon="MEDIA.NEXT"
+          display={cmd}
+          disabled={!next}
+          onClick={doNext}
+          title="Previous Command"
+        />
         <Space />
-        <IconButton icon='MEDIA.PLAY' display={cmd} onClick={doExec} title='Execute Command Line' />
-        <IconButton icon='EDIT' selected={cmd} onClick={switchCmd} title='Edit Command Line' />
+        <IconButton
+          icon="MEDIA.PLAY"
+          display={cmd}
+          onClick={doExec}
+          title="Execute Command Line"
+        />
+        <IconButton
+          icon="EDIT"
+          selected={cmd}
+          onClick={switchCmd}
+          title="Edit Command Line"
+        />
       </TitleBar>
-      <Text buffer={cmd ? cmdLine : Server.buffer}
-        mode='text'
+      <Text
+        buffer={cmd ? cmdLine : Server.buffer}
+        mode="text"
         readOnly={!cmd}
-        theme='ambiance' />
-    </React.Fragment>
+        theme="ambiance"
+      />
+    </>
   );
 };
 
 export const Console = () => (
-  <Component id='frama-c.console'
-    label='Console'
-    title='Frama-C Server Output & Command Line'>
+  <Component
+    id="frama-c.console"
+    label="Console"
+    title="Frama-C Server Output & Command Line"
+  >
     <RenderConsole />
   </Component>
 );
@@ -176,7 +251,9 @@ export const Status = () => {
   Dome.useUpdate(Server.STATUS);
   const s = Server.getStatus();
   const n = Server.getPending();
-  let led, blink, error;
+  let led;
+  let blink;
+  let error;
   switch (s) {
     case StatusCode.OFF:
       led = 'inactive';
@@ -201,13 +278,15 @@ export const Status = () => {
       blink = false;
       error = Server.getError();
       break;
+    default:
+      break;
   }
   return (
-    <React.Fragment>
+    <>
       <LED status={led} blink={blink} />
       <Code label={s} />
-      {error && <Label icon='WARNING' label={error} />}
-    </React.Fragment>
+      {error && <Label icon="WARNING" label={error} />}
+    </>
   );
 };
 
@@ -225,6 +304,11 @@ export const Stats = () => {
 // --- Controller Exports
 // --------------------------------------------------------------------------
 
-export default { Control, Console, Status, Stats };
+export default {
+  Control,
+  Console,
+  Status,
+  Stats,
+};
 
 // --------------------------------------------------------------------------
diff --git a/ivette/src/renderer/Properties.tsx b/ivette/src/renderer/Properties.tsx
index 06aa58ca1966635f35df53ab6eace464da027a05..f8a7b51e758616366c239bbbcdf2a066f32aea30 100644
--- a/ivette/src/renderer/Properties.tsx
+++ b/ivette/src/renderer/Properties.tsx
@@ -19,8 +19,9 @@ const ColumnCode: any =
 
 const ColumnTag: any =
   DefineColumn({
-    renderValue: (l: { label: string; descr: string }) =>
-      (<Label label={l.label} title={l.descr} />)
+    renderValue: (l: { label: string; descr: string }) => (
+      <Label label={l.label} title={l.descr} />
+    ),
   });
 
 // --------------------------------------------------------------------------
@@ -28,7 +29,6 @@ const ColumnTag: any =
 // -------------------------------------------------------------------------
 
 const RenderTable = () => {
-
   // Hooks
   const model = React.useMemo(() => new ArrayModel(), []);
   const items = States.useSyncArray('kernel.properties');
@@ -43,24 +43,30 @@ const RenderTable = () => {
   const selection = select ? items[select.marker] : undefined;
   const onSelection = (item: any) => item && setSelect({
     marker: item.key,
-    function: item.function
+    function: item.function,
   });
 
   // Rendering
   return (
-    <React.Fragment>
-      <Table model={model}
+    <>
+      <Table
+        model={model}
         selection={selection}
         onSelection={onSelection}
         scrollToItem={selection}
       >
-        <ColumnCode id='function' label='Function' width={120} />
-        <ColumnCode id='descr' label='Description' fill />
-        <ColumnTag id='status' label='Status'
-          fixed width={80} align='center'
-          getValue={getStatus} />
+        <ColumnCode id="function" label="Function" width={120} />
+        <ColumnCode id="descr" label="Description" fill />
+        <ColumnTag
+          id="status"
+          label="Status"
+          fixed
+          width={80}
+          align="center"
+          getValue={getStatus}
+        />
       </Table>
-    </React.Fragment>
+    </>
   );
 };
 
@@ -69,9 +75,11 @@ const RenderTable = () => {
 // -------------------------------------------------------------------------
 
 export default () => (
-  <Component id='frama-c.properties'
-    label='Properties'
-    title='Registered ACSL properties status' >
+  <Component
+    id="frama-c.properties"
+    label="Properties"
+    title="Registered ACSL properties status"
+  >
     <RenderTable />
   </Component>
 );
diff --git a/ivette/yarn.lock b/ivette/yarn.lock
index 5193f6c861badfe00ed74e63092fef8450f68a8a..92759d49f5d57ca41a516fde994c7b0d52d7b4ca 100644
--- a/ivette/yarn.lock
+++ b/ivette/yarn.lock
@@ -876,7 +876,7 @@
     core-js-pure "^3.0.0"
     regenerator-runtime "^0.13.4"
 
-"@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.4.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
   version "7.9.2"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06"
   integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==
@@ -1171,6 +1171,26 @@
     eslint-scope "^5.0.0"
     eslint-utils "^2.0.0"
 
+"@typescript-eslint/experimental-utils@2.29.0":
+  version "2.29.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.29.0.tgz#3cb8060de9265ba131625a96bbfec31ba6d4a0fe"
+  integrity sha512-H/6VJr6eWYstyqjWXBP2Nn1hQJyvJoFdDtsHxGiD+lEP7piGnGpb/ZQd+z1ZSB1F7dN+WsxUDh8+S4LwI+f3jw==
+  dependencies:
+    "@types/json-schema" "^7.0.3"
+    "@typescript-eslint/typescript-estree" "2.29.0"
+    eslint-scope "^5.0.0"
+    eslint-utils "^2.0.0"
+
+"@typescript-eslint/parser@^2.24.0":
+  version "2.29.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.29.0.tgz#6e3c4e21ed6393dc05b9d8b47f0b7e731ef21c9c"
+  integrity sha512-H78M+jcu5Tf6m/5N8iiFblUUv+HJDguMSdFfzwa6vSg9lKR8Mk9BsgeSjO8l2EshKnJKcbv0e8IDDOvSNjl0EA==
+  dependencies:
+    "@types/eslint-visitor-keys" "^1.0.0"
+    "@typescript-eslint/experimental-utils" "2.29.0"
+    "@typescript-eslint/typescript-estree" "2.29.0"
+    eslint-visitor-keys "^1.1.0"
+
 "@typescript-eslint/parser@^2.28.0":
   version "2.28.0"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.28.0.tgz#bb761286efd2b0714761cab9d0ee5847cf080385"
@@ -1194,6 +1214,19 @@
     semver "^6.3.0"
     tsutils "^3.17.1"
 
+"@typescript-eslint/typescript-estree@2.29.0":
+  version "2.29.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.29.0.tgz#1be6612bb02fc37ac9f466521c1459a4744e8d3a"
+  integrity sha512-3YGbtnWy4az16Egy5Fj5CckkVlpIh0MADtAQza+jiMADRSKkjdpzZp/5WuvwK/Qib3Z0HtzrDFeWanS99dNhnA==
+  dependencies:
+    debug "^4.1.1"
+    eslint-visitor-keys "^1.1.0"
+    glob "^7.1.6"
+    is-glob "^4.0.1"
+    lodash "^4.17.15"
+    semver "^6.3.0"
+    tsutils "^3.17.1"
+
 "@webassemblyjs/ast@1.9.0":
   version "1.9.0"
   resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
@@ -1522,6 +1555,14 @@ argparse@^1.0.7:
   dependencies:
     sprintf-js "~1.0.2"
 
+aria-query@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc"
+  integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=
+  dependencies:
+    ast-types-flow "0.0.7"
+    commander "^2.11.0"
+
 arr-diff@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@@ -1573,6 +1614,14 @@ array-unique@^0.3.2:
   resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
   integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
 
+array.prototype.flat@^1.2.1:
+  version "1.2.3"
+  resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b"
+  integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==
+  dependencies:
+    define-properties "^1.1.3"
+    es-abstract "^1.17.0-next.1"
+
 asn1.js@^4.0.0:
   version "4.10.1"
   resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
@@ -1595,6 +1644,11 @@ assign-symbols@^1.0.0:
   resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
   integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
 
+ast-types-flow@0.0.7, ast-types-flow@^0.0.7:
+  version "0.0.7"
+  resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
+  integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
+
 astral-regex@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
@@ -1644,6 +1698,11 @@ autoprefixer@^6.3.1:
     postcss "^5.2.16"
     postcss-value-parser "^3.2.3"
 
+axobject-query@^2.0.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799"
+  integrity sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ==
+
 babel-loader@^8.0.6, babel-loader@^8.1.0:
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3"
@@ -2365,7 +2424,7 @@ colors@~1.1.2:
   resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
   integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM=
 
-commander@^2.19.0, commander@^2.20.0:
+commander@^2.11.0, commander@^2.19.0, commander@^2.20.0:
   version "2.20.3"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -2440,6 +2499,11 @@ configstore@^5.0.1:
     write-file-atomic "^3.0.0"
     xdg-basedir "^4.0.0"
 
+confusing-browser-globals@^1.0.9:
+  version "1.0.9"
+  resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd"
+  integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==
+
 connect-history-api-fallback@^1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
@@ -2455,6 +2519,11 @@ constants-browserify@^1.0.0:
   resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
   integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
 
+contains-path@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
+  integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=
+
 content-disposition@0.5.3:
   version "0.5.3"
   resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
@@ -2756,6 +2825,11 @@ cyclist@^1.0.1:
   resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
   integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
 
+damerau-levenshtein@^1.0.4:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791"
+  integrity sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==
+
 debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
   version "2.6.9"
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -2946,6 +3020,14 @@ dns-txt@^2.0.2:
   dependencies:
     buffer-indexof "^1.0.0"
 
+doctrine@1.5.0:
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
+  integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=
+  dependencies:
+    esutils "^2.0.2"
+    isarray "^1.0.0"
+
 doctrine@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
@@ -3209,7 +3291,7 @@ elliptic@^6.0.0:
     minimalistic-assert "^1.0.0"
     minimalistic-crypto-utils "^1.0.0"
 
-emoji-regex@^7.0.1:
+emoji-regex@^7.0.1, emoji-regex@^7.0.2:
   version "7.0.3"
   resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
   integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
@@ -3281,6 +3363,13 @@ errno@^0.1.3, errno@~0.1.7:
   dependencies:
     prr "~1.0.1"
 
+error-ex@^1.2.0:
+  version "1.3.2"
+  resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
+  integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
+  dependencies:
+    is-arrayish "^0.2.1"
+
 es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5:
   version "1.17.5"
   resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9"
@@ -3332,6 +3421,82 @@ escape-string-regexp@^2.0.0:
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
   integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
 
+eslint-config-airbnb-base@^14.1.0:
+  version "14.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.1.0.tgz#2ba4592dd6843258221d9bff2b6831bd77c874e4"
+  integrity sha512-+XCcfGyCnbzOnktDVhwsCAx+9DmrzEmuwxyHUJpw+kqBVT744OUBrB09khgFKlK1lshVww6qXGsYPZpavoNjJw==
+  dependencies:
+    confusing-browser-globals "^1.0.9"
+    object.assign "^4.1.0"
+    object.entries "^1.1.1"
+
+eslint-config-airbnb-typescript@^7.2.1:
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-7.2.1.tgz#bce3f02fa894d1ec2f31ac527992e03761a9b7d4"
+  integrity sha512-D3elVKUbdsCfkOVstSyWuiu+KGCVTrYxJPoenPIqZtL6Li/R4xBeVTXjZIui8B8D17bDN3Pz5dSr7jRLY5HqIg==
+  dependencies:
+    "@typescript-eslint/parser" "^2.24.0"
+    eslint-config-airbnb "^18.1.0"
+    eslint-config-airbnb-base "^14.1.0"
+
+eslint-config-airbnb@^18.1.0:
+  version "18.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.1.0.tgz#724d7e93dadd2169492ff5363c5aaa779e01257d"
+  integrity sha512-kZFuQC/MPnH7KJp6v95xsLBf63G/w7YqdPfQ0MUanxQ7zcKUNG8j+sSY860g3NwCBOa62apw16J6pRN+AOgXzw==
+  dependencies:
+    eslint-config-airbnb-base "^14.1.0"
+    object.assign "^4.1.0"
+    object.entries "^1.1.1"
+
+eslint-import-resolver-node@^0.3.2:
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404"
+  integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==
+  dependencies:
+    debug "^2.6.9"
+    resolve "^1.13.1"
+
+eslint-module-utils@^2.4.1:
+  version "2.6.0"
+  resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6"
+  integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==
+  dependencies:
+    debug "^2.6.9"
+    pkg-dir "^2.0.0"
+
+eslint-plugin-import@^2.20.2:
+  version "2.20.2"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d"
+  integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg==
+  dependencies:
+    array-includes "^3.0.3"
+    array.prototype.flat "^1.2.1"
+    contains-path "^0.1.0"
+    debug "^2.6.9"
+    doctrine "1.5.0"
+    eslint-import-resolver-node "^0.3.2"
+    eslint-module-utils "^2.4.1"
+    has "^1.0.3"
+    minimatch "^3.0.4"
+    object.values "^1.1.0"
+    read-pkg-up "^2.0.0"
+    resolve "^1.12.0"
+
+eslint-plugin-jsx-a11y@^6.2.3:
+  version "6.2.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz#b872a09d5de51af70a97db1eea7dc933043708aa"
+  integrity sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==
+  dependencies:
+    "@babel/runtime" "^7.4.5"
+    aria-query "^3.0.0"
+    array-includes "^3.0.3"
+    ast-types-flow "^0.0.7"
+    axobject-query "^2.0.2"
+    damerau-levenshtein "^1.0.4"
+    emoji-regex "^7.0.2"
+    has "^1.0.3"
+    jsx-ast-utils "^2.2.1"
+
 eslint-plugin-react-hooks@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-3.0.0.tgz#9e80c71846eb68dd29c3b21d832728aa66e5bd35"
@@ -3737,7 +3902,7 @@ find-cache-dir@^3.2.0:
     make-dir "^3.0.2"
     pkg-dir "^4.1.0"
 
-find-up@^2.1.0:
+find-up@^2.0.0, find-up@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
   integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
@@ -4597,6 +4762,11 @@ is-arguments@^1.0.4:
   resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3"
   integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==
 
+is-arrayish@^0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+  integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
+
 is-binary-path@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
@@ -4981,7 +5151,7 @@ jsonfile@^6.0.1:
   optionalDependencies:
     graceful-fs "^4.1.6"
 
-jsx-ast-utils@^2.2.3:
+jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3:
   version "2.2.3"
   resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f"
   integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA==
@@ -5078,6 +5248,16 @@ linkify-it@^2.0.0:
   dependencies:
     uc.micro "^1.0.1"
 
+load-json-file@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
+  integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=
+  dependencies:
+    graceful-fs "^4.1.2"
+    parse-json "^2.2.0"
+    pify "^2.0.0"
+    strip-bom "^3.0.0"
+
 loader-runner@^2.4.0:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
@@ -5621,7 +5801,7 @@ node-releases@^1.1.53:
   resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4"
   integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==
 
-normalize-package-data@^2.5.0:
+normalize-package-data@^2.3.2, normalize-package-data@^2.5.0:
   version "2.5.0"
   resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
   integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
@@ -5997,6 +6177,13 @@ parse-asn1@^5.0.0:
     pbkdf2 "^3.0.3"
     safe-buffer "^5.1.1"
 
+parse-json@^2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
+  integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=
+  dependencies:
+    error-ex "^1.2.0"
+
 parse-passwd@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
@@ -6070,6 +6257,13 @@ path-to-regexp@0.1.7:
   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
   integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
 
+path-type@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
+  integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=
+  dependencies:
+    pify "^2.0.0"
+
 pbkdf2@^3.0.3:
   version "3.0.17"
   resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
@@ -6113,6 +6307,13 @@ pinkie@^2.0.0:
   resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
   integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
 
+pkg-dir@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
+  integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=
+  dependencies:
+    find-up "^2.1.0"
+
 pkg-dir@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3"
@@ -6759,6 +6960,23 @@ read-config-file@~4.0.1:
     json5 "^2.1.0"
     lazy-val "^1.0.4"
 
+read-pkg-up@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
+  integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=
+  dependencies:
+    find-up "^2.0.0"
+    read-pkg "^2.0.0"
+
+read-pkg@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
+  integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=
+  dependencies:
+    load-json-file "^2.0.0"
+    normalize-package-data "^2.3.2"
+    path-type "^2.0.0"
+
 "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
   version "2.3.7"
   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
@@ -6995,6 +7213,13 @@ resolve@^1.10.0, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.8.1:
   dependencies:
     path-parse "^1.0.6"
 
+resolve@^1.12.0, resolve@^1.13.1:
+  version "1.17.0"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
+  integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
+  dependencies:
+    path-parse "^1.0.6"
+
 responselike@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
@@ -7687,6 +7912,11 @@ strip-ansi@^6.0.0:
   dependencies:
     ansi-regex "^5.0.0"
 
+strip-bom@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+  integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
+
 strip-eof@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"