text:
import {
  AmpStoryInteractive,
  InteractiveType,
} from './amp-story-interactive-abstract';
import {CSS} from '../../../build/amp-story-interactive-img-quiz-0.1.css';
import {CSS as ImgCSS} from '../../../build/amp-story-interactive-img-0.1.css';
import {LocalizedStringId} from '#service/localization/strings';
import {buildImgTemplate} from './utils';
import {dev} from '../../../src/log';
import {
  getRGBFromCssColorValue,
  getTextColorForRGB,
} from '../../amp-story/1.0/utils';
import {htmlFor} from '#core/dom/static-template';
import {computedStyle, setImportantStyles} from '#core/dom/style';
import objstr from 'obj-str';

/**
 * Generates the template for each option.
 *
 * @param {!Element} option
 * @return {!Element}
 */
const buildOptionTemplate = (option) => {
  const html = htmlFor(option);
  return html`
    <button
      class="i-amphtml-story-interactive-img-option i-amphtml-story-interactive-option"
      aria-live="polite"
    >

    </button>
  `;
};

export class AmpStoryInteractiveImgQuiz extends AmpStoryInteractive {
  /**
   * @param {!AmpElement} element
   */
  constructor(element) {
    super(element, InteractiveType.QUIZ);

    /** @private {!Array<string>} */
    this.localizedAnswerChoices_ = [];
  }

  /** @override */
  buildCallback() {
    return super.buildCallback(CSS + ImgCSS);
  }

  /** @override */
  buildComponent() {
    this.rootEl_ = buildImgTemplate(this.element);
    this.attachContent_(this.rootEl_);
    return this.rootEl_;
  }

  /** @override */
  layoutCallback() {
    this.setBubbleTextColor_(dev().assertElement(this.rootEl_));
    return super.layoutCallback();
  }

  /**
   * Finds the prompt and options content
   * and adds it to the quiz element.
   *
   * @private
   * @param {Element} root
   */
  attachContent_(root) {
    this.attachPrompt_(root);

    // Localize the answer choice options
    this.localizedAnswerChoices_ = [
      LocalizedStringId.AMP_STORY_INTERACTIVE_QUIZ_ANSWER_CHOICE_A,
      LocalizedStringId.AMP_STORY_INTERACTIVE_QUIZ_ANSWER_CHOICE_B,
      LocalizedStringId.AMP_STORY_INTERACTIVE_QUIZ_ANSWER_CHOICE_C,
      LocalizedStringId.AMP_STORY_INTERACTIVE_QUIZ_ANSWER_CHOICE_D,
    ].map((choice) => this.localizationService.getLocalizedString(choice));
    const optionContainer = this.rootEl_.querySelector(
      '.i-amphtml-story-interactive-img-option-container'
    );
    this.options_.forEach((option, index) =>
      optionContainer.appendChild(this.configureOption_(option, index))
    );
  }

  /**
   * Creates and returns an option container with option content,
   * adds styling and answer choices.
   *
   * @param {!./amp-story-interactive-abstract.OptionConfigType} option
   * @param {number} index
   * @return {!Element}
   * @private
   */
  configureOption_(option, index) {
    const convertedOption = buildOptionTemplate(this.element);

    // Fill in the answer choice and set the option ID
    const answerChoiceEl = convertedOption.querySelector(
      '.i-amphtml-story-interactive-img-quiz-answer-choice'
    );
    answerChoiceEl.textContent = this.localizedAnswerChoices_[index];
    convertedOption.optionIndex_ = option['optionIndex'];

    // Extract and structure the option information
    setImportantStyles(
      convertedOption.querySelector(
        '.i-amphtml-story-interactive-img-option-img'
      ),
      {'background-image': 'url(' + option['image'] + ')'}
    );

    convertedOption.setAttribute('aria-label', option['imagealt']);

    if ('correct' in option) {
      convertedOption.setAttribute('correct', 'correct');
    }

    return convertedOption;
  }

  /**
   * @override
   */
  displayOptionsData(optionsData) {
    if (!optionsData) {
      return;
    }

    const percentages = this.preprocessPercentages_(optionsData);

    this.getOptionElements().forEach((el, index) => {
      // Update the aria-label so they read "selected" and "correct" or "incorrect"
      const ariaDescription = objstr({
        selected: optionsData[index].selected,
        correct: el.hasAttribute('correct'),
        incorrect: !el.hasAttribute('correct'),
      });
      el.setAttribute(
        'aria-label',
        ariaDescription + ' ' + this.options_[index]['imagealt']
      );
      // Update percentage text
      el.querySelector(
        '.i-amphtml-story-interactive-img-option-percentage-text'
      ).textContent = `${percentages[index]}%`;
      setImportantStyles(el, {'--option-percentage': percentages[index] / 100});
    });
  }

  /**
   * Set the text color of the answer choice bubble to be readable and
   * accessible according to the background color.
   *
   * @param {!Element} root
   * @private
   */
  setBubbleTextColor_(root) {
    // Only retrieves first bubble, but styles all bubbles accordingly
    const answerChoiceEl = root.querySelector(
      '.i-amphtml-story-interactive-img-quiz-answer-choice'
    );
    const {backgroundColor} = computedStyle(this.win, answerChoiceEl);
    const rgb = getRGBFromCssColorValue(backgroundColor);
    const contrastColor = getTextColorForRGB(rgb);
    setImportantStyles(root, {
      '--i-amphtml-interactive-option-answer-choice-color': contrastColor,
    });
  }
}


text:
Custom API is useful when one would like to abstract from a specific protocol and be able to replace transports while maintaining the same API.

For example, let's assume we want to use superagent API for our pipeline.

_superagent.js_
```js
module.exports = function (pipe) {
    pipe.set('superagent', function factory(pipe) {
        return new Superagent(pipe);
    });
};

class Superagent {
    constructor(pipe) {
        this.pipe = pipe;
        this.options = {
            method: 'GET'
        };
    }

    request(options) {
        this.options = options;
        return this;
    }

    post(body) {
        this.options.method = 'POST';
        this.options.body = body;
        return this;
    }

    get(path) {
        this.options.path = path;
        return this;
    }

    end(callback) {
        // here we should initiate an actual flow
        this.pipe.create().request(this.options, callback);
    }
}

```

_superagent-use.js_
```js
// Now let's use it
const pipe = require('trooba')
    .use(require('./superagent'))
    .use(function mockTransport(pipe) {
        pipe.on('request', request => {
            pipe.respond({
                statusCode: 200,
                body: {
                    greeting: 'Hello World'
                }
            })
        });
    })
    .build();

const agent = pipe.create('superagent');
agent.get('path/to/resource').end((err, response) => {
    console.log(response.body);
});
```

redpajama_set_name: RedPajamaGithub


text:
package com.google.gapid.views;

import static com.google.gapid.models.Follower.nullPrefetcher;
import static com.google.gapid.util.GeoUtils.center;
import static com.google.gapid.util.Loadable.MessageType.Error;
import static com.google.gapid.util.Loadable.MessageType.Info;
import static com.google.gapid.widgets.Widgets.createTreeForViewer;
import static com.google.gapid.widgets.Widgets.createTreeViewer;
import static java.util.Arrays.stream;
import static java.util.logging.Level.WARNING;
import static java.util.stream.Collectors.toList;

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.gapid.models.ApiState;
import com.google.gapid.models.AtomStream;
import com.google.gapid.models.AtomStream.AtomIndex;
import com.google.gapid.models.Capture;
import com.google.gapid.models.ConstantSets;
import com.google.gapid.models.Follower;
import com.google.gapid.models.Models;
import com.google.gapid.proto.service.Service;
import com.google.gapid.proto.service.path.Path;
import com.google.gapid.rpc.Rpc;
import com.google.gapid.rpc.RpcException;
import com.google.gapid.rpc.UiCallback;
import com.google.gapid.server.Client;
import com.google.gapid.util.Loadable;
import com.google.gapid.util.Messages;
import com.google.gapid.util.MouseAdapter;
import com.google.gapid.util.Paths;
import com.google.gapid.util.SelectionHandler;
import com.google.gapid.views.Formatter.StylingString;
import com.google.gapid.widgets.CopySources;
import com.google.gapid.widgets.LoadablePanel;
import com.google.gapid.widgets.MeasuringViewLabelProvider;
import com.google.gapid.widgets.TextViewer;
import com.google.gapid.widgets.Theme;
import com.google.gapid.widgets.Widgets;

import org.eclipse.jface.viewers.ILazyTreeContentProvider;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * View that displays the API state as a tree.
 */
public class StateView extends Composite
    implements Tab, Capture.Listener, AtomStream.Listener, ApiState.Listener {
  private static final Logger LOG = Logger.getLogger(StateView.class.getName());

  private final Models models;
  private final LoadablePanel<Tree> loading;
  protected final TreeViewer viewer;
  private final SelectionHandler<Tree> selectionHandler;
  protected List<Path.Any> scheduledExpandedPaths;
  protected Point scheduledScrollPos;

  public StateView(Composite parent, Client client, Models models, Widgets widgets) {
    super(parent, SWT.NONE);
    this.models = models;

    setLayout(new FillLayout(SWT.VERTICAL));

    loading = LoadablePanel.create(this, widgets,
        panel -> createTreeForViewer(panel, SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL | SWT.MULTI));
    Tree tree = loading.getContents();
    viewer = createTreeViewer(tree);
    viewer.setContentProvider(new StateContentProvider(models.state, viewer));
    ViewLabelProvider labelProvider =
        new ViewLabelProvider(viewer, models.constants, widgets.theme);
    viewer.setLabelProvider(labelProvider);

    models.capture.addListener(this);
    models.atoms.addListener(this);
    models.state.addListener(this);
    addListener(SWT.Dispose, e -> {
      models.capture.removeListener(this);
      models.atoms.removeListener(this);
      models.state.removeListener(this);
    });

    selectionHandler = new SelectionHandler<Tree>(LOG, tree) {
      @Override
      protected void updateModel(Event e) {
        Object selection = (tree.getSelectionCount() > 0) ? tree.getSelection()[0].getData() : null;
        if (selection instanceof ApiState.Node) {
          Service.StateTreeNode node = ((ApiState.Node)selection).getData();
          if (node != null) {
            models.state.selectPath(node.getValuePath(), false);
          }
        }
      }
    };

    Widgets.Refresher treeRefresher = Widgets.withAsyncRefresh(viewer);
    MouseAdapter mouseHandler = new MouseAdapter() {
      // TODO - dedupe with code in AtomTree.
      private TreeItem lastHovered;
      private Follower.Prefetcher<Void> lastPrefetcher = nullPrefetcher();

      @Override
      public void mouseMove(MouseEvent e) {
        updateHover(e.x, e.y);
      }

      @Override
      public void mouseScrolled(MouseEvent e) {
        updateHover(e.x, e.y);
      }

      @Override
      public void widgetSelected(SelectionEvent e) {
        // Scrollbar was moved / mouse wheel caused scrolling. This is required for systems with
        // a touchpad with scrolling inertia, where the view keeps scrolling long after the mouse
        // wheel event has been processed.
        Display disp = getDisplay();
        Point mouse = disp.map(null, tree, disp.getCursorLocation());
        updateHover(mouse.x, mouse.y);
      }

      @Override
      public void mouseDown(MouseEvent e) {
        Point location = new Point(e.x, e.y);
        Path.Any follow = (Path.Any)labelProvider.getFollow(location);
        if (follow != null) {
          models.follower.onFollow(follow);
        }
      }

      @Override
      public void mouseExit(MouseEvent e) {
        hoverItem(null);
      }

      private void updateHover(int x, int y) {
        TreeItem item = tree.getItem(new Point(x, y));
        // When hovering over the far left of deep items, getItem returns null. Let's check a few
        // more places to the right.
        if (item == null) {
          for (int testX = x + 20; item == null && testX < 300; testX += 20) {
            item = tree.getItem(new Point(testX, y));
          }
        }

        if (item != null && (item.getData() instanceof ApiState.Node)) {
          hoverItem(item);
          Path.Any follow = (Path.Any)labelProvider.getFollow(new Point(x, y));
          setCursor((follow == null) ? null : getDisplay().getSystemCursor(SWT.CURSOR_HAND));
        } else {
          hoverItem(null);
        }
      }

      private void hoverItem(TreeItem item) {
        if (item != lastHovered) {
          lastHovered = item;
          lastPrefetcher.cancel();

          ApiState.Node node = (item == null) ? null : (ApiState.Node)item.getData();
          // TODO: if still loading, once loaded should update the hover data.
          if (node == null || node.getData() == null || !node.getData().hasValuePath()) {
            lastPrefetcher = nullPrefetcher();
          } else {
            lastPrefetcher = models.follower.prepare(node.getData().getValuePath(),
                () -> Widgets.scheduleIfNotDisposed(tree, treeRefresher::refresh));
          }

          labelProvider.setHoveredItem(lastHovered, lastPrefetcher);
          treeRefresher.refresh();
        }
      }
    };
    tree.addMouseListener(mouseHandler);
    tree.addMouseTrackListener(mouseHandler);
    tree.addMouseMoveListener(mouseHandler);
    tree.addMouseWheelListener(mouseHandler);
    tree.getVerticalBar().addSelectionListener(mouseHandler);

    Menu popup = new Menu(tree);
    Widgets.createMenuItem(popup, "&View Details", SWT.MOD1 + 'D', e -> {
      TreeItem item = (tree.getSelectionCount() > 0) ? tree.getSelection()[0] : null;
      if (item != null && (item.getData() instanceof ApiState.Node)) {
        Service.StateTreeNode data = ((ApiState.Node)item.getData()).getData();

        if (data == null) {
          // Data not loaded yet, this shouldn't happen (see MenuDetect handler). Ignore.
          LOG.log(Level.WARNING, "Impossible popup requested and ignored.");
          return;
        } else if (!data.hasPreview()) {
          // No value at this node, this shouldn't happen, either. Ignore.
          LOG.log(Level.WARNING, "Value-less popup requested and ignored: {0}", data);
          return;
        }

        TextViewer.showViewTextPopup(getShell(), widgets, data.getName() + ":",
            Futures.transform(client.get(data.getValuePath()),
                v -> Formatter.toString(
                    v.getBox(),  models.constants.getConstants(data.getConstants()), false)));
      }
    });
    tree.setMenu(popup);
    tree.addListener(SWT.MenuDetect, e -> {
      if (!canShowPopup(tree.getItem(tree.toControl(e.x, e.y)))) {
        e.doit = false;
      }
    });

    CopySources.registerTreeAsCopySource(widgets.copypaste, viewer, object -> {
      if (object instanceof ApiState.Node) {
        Service.StateTreeNode node = ((ApiState.Node)object).getData();
        if (node == null) {
          // Copy before loaded. Not ideal, but this is unlikely.
          return new String[] { "Loading..." };
        } else if (!node.hasPreview()) {
          return new String[] { node.getName() };
        }

        String text = Formatter.toString(node.getPreview(),
            models.constants.getConstants(node.getConstants()), node.getPreviewIsValue());
        return new String[] { node.getName(), text };
      }

      return new String[] { String.valueOf(object) };
    }, true);
  }

  @Override
  public Control getControl() {
    return this;
  }

  @Override
  public void reinitialize() {
    onCaptureLoadingStart(false);
    if (models.capture.isLoaded() && models.atoms.isLoaded()) {
      onAtomsLoaded();
      if (models.atoms.getSelectedAtoms() != null) {
        onStateLoadingStart();
        if (models.state.isLoaded()) {
          onStateLoaded(null);
        }
      }
    }
  }

  @Override
  public void onCaptureLoadingStart(boolean maintainState) {
    loading.showMessage(Info, Messages.LOADING_CAPTURE);
  }

  @Override
  public void onCaptureLoaded(Loadable.Message error) {
    if (error != null) {
      loading.showMessage(Error, Messages.CAPTURE_LOAD_FAILURE);
    }
  }

  @Override
  public void onAtomsLoaded() {
    if (!models.atoms.isLoaded()) {
      loading.showMessage(Error, Messages.CAPTURE_LOAD_FAILURE);
    } else if (models.atoms.getSelectedAtoms() == null) {
      loading.showMessage(Info, Messages.SELECT_ATOM);
    }
  }

  @Override
  public void onAtomsSelected(AtomIndex path) {
    if (path == null) {
      loading.showMessage(Info, Messages.SELECT_ATOM);
    }
  }

  @Override
  public void onStateLoadingStart() {
    loading.startLoading();
  }

  @Override
  public void onStateLoaded(Loadable.Message error) {
    if (error != null) {
      loading.showMessage(error);
      return;
    }

    loading.stopLoading();
    if (scheduledExpandedPaths == null) {
      scheduledExpandedPaths = getExpandedPaths();
      TreeItem topItem = viewer.getTree().getTopItem();
      scheduledScrollPos = (topItem == null) ? null : center(topItem.getBounds());
    }
    viewer.setInput(models.state.getData());
    updateExpansionState(scheduledExpandedPaths, scheduledExpandedPaths.size());

    Path.Any selection = models.state.getSelectedPath();
    if (selection == null) {
      viewer.setSelection(
          new TreeSelection(new TreePath(new Object[] { viewer.getInput() })), true);
    } else {
      updateSelectionState(false);
    }
  }

  @Override
  public void onStateSelected(Path.Any path) {
    if (!models.state.isLoaded()) {
      return; // Once loaded, we'll call ourselves again.
    }
    updateSelectionState(true);
  }

  private void updateSelectionState(boolean show) {
    ApiState.Node root = models.state.getData();
    selectionHandler.updateSelectionFromModel(
        () -> Futures.transformAsync(
            models.state.getResolvedSelectedPath(), nodePath -> getTreePath(root, nodePath)).get(),
        selection -> {
          viewer.refresh();
          viewer.setSelection(new TreeSelection(selection), show);
          if (show) {
            viewer.setExpandedState(selection, true);
          }
        });
  }

  private List<Path.Any> getExpandedPaths() {
    return stream(viewer.getExpandedElements())
        .map(element -> ((ApiState.Node)element).getData())
        .filter(data -> data != null)
        .map(data -> data.getValuePath())
        .collect(toList());
  }

  protected void updateExpansionState(List<Path.Any> paths, int retry) {
    Path.State state = Paths.stateAfter(models.state.getSource().getStateTree().getAfter());
    ApiState.Node root = models.state.getData();
    List<ListenableFuture<TreePath>> futures = Lists.newArrayList();
    for (Path.Any path : paths) {
      Path.Any reparented = Paths.reparent(path, state);
      if (reparented == null) {
        LOG.log(WARNING, "Unable to reparent path {0}", path);
        continue;
      }
      futures.add(Futures.transformAsync(models.state.resolve(reparented),
          nodePath -> getTreePath(root, nodePath)));
    }

    Rpc.listen(Futures.allAsList(futures),
        new UiCallback<List<TreePath>, TreePath[]>(viewer.getTree(), LOG) {
      @Override
      protected TreePath[] onRpcThread(Rpc.Result<List<TreePath>> result)
          throws RpcException, ExecutionException {
        List<TreePath> list = result.get();
        return list.toArray(new TreePath[list.size()]);
      }

      @Override
      protected void onUiThread(TreePath[] treePaths) {
        setExpanded(treePaths, paths, retry);
      }
    });
  }

  protected void setExpanded(TreePath[] treePaths, List<Path.Any> paths, int retry) {
    viewer.refresh();
    for (TreePath path : treePaths) {
      viewer.setExpandedState(path, true);
      if (!viewer.getExpandedState(path)) {
        if (retry > 0) {
          updateExpansionState(paths, retry - 1);
          return;
        }
      }
    }

    if (scheduledScrollPos != null) {
      TreeItem topItem = viewer.getTree().getItem(scheduledScrollPos);
      if (topItem != null) {
        viewer.getTree().setTopItem(topItem);
      }
    }

    scheduledExpandedPaths = null;
    scheduledScrollPos = null;
  }

  private ListenableFuture<TreePath> getTreePath(ApiState.Node root, Path.StateTreeNode nodePath) {
    return getTreePath(root, Lists.newArrayList(), nodePath.getIndicesList().iterator());
  }

  private ListenableFuture<TreePath> getTreePath(
      ApiState.Node node, List<Object> path, Iterator<Long> indices) {
    ListenableFuture<ApiState.Node> load = models.state.load(node);
    if (!indices.hasNext()) {
      TreePath result = new TreePath(path.toArray());
      // Ensure the last node in the path is loaded.
      return (load == null) ? Futures.immediateFuture(result) :
          Futures.transform(load, ignored -> result);
    }
    return (load == null) ? getTreePathForLoadedNode(node, path, indices) :
        Futures.transformAsync(load, loaded -> getTreePathForLoadedNode(loaded, path, indices));
  }

  private ListenableFuture<TreePath> getTreePathForLoadedNode(
      ApiState.Node node, List<Object> path, Iterator<Long> indices) {
    ApiState.Node child = node.getChild(indices.next().intValue());
    path.add(child);
    return getTreePath(child, path, indices);
  }

  private static boolean canShowPopup(TreeItem item) {
    if (item == null || !(item.getData() instanceof ApiState.Node)) {
      return false;
    }
    Service.StateTreeNode data = ((ApiState.Node)item.getData()).getData();
    return data != null && data.hasPreview();
  }

  /**
   * Content provider for the state tree.
   */
  private static class StateContentProvider implements ILazyTreeContentProvider {
    private final ApiState state;
    private final TreeViewer viewer;
    private final Widgets.Refresher refresher;

    public StateContentProvider(ApiState state, TreeViewer viewer) {
      this.state = state;
      this.viewer = viewer;
      this.refresher = Widgets.withAsyncRefresh(viewer);
    }

    @Override
    public void updateChildCount(Object element, int currentChildCount) {
      viewer.setChildCount(element, ((ApiState.Node)element).getChildCount());
    }

    @Override
    public void updateElement(Object parent, int index) {
      ApiState.Node child = ((ApiState.Node)parent).getChild(index);
      state.load(child, refresher::refresh);
      viewer.replace(parent, index, child);
      viewer.setHasChildren(child, child.getChildCount() > 0);
    }

    @Override
    public Object getParent(Object element) {
      return ((ApiState.Node)element).getParent();
    }
  }

  /**
   * Label provider for the state tree.
   */
  private static class ViewLabelProvider extends MeasuringViewLabelProvider {
    private final ConstantSets constants;
    private TreeItem hoveredItem;
    private Follower.Prefetcher<Void> follower;

    public ViewLabelProvider(TreeViewer viewer, ConstantSets constants, Theme theme) {
      super(viewer, theme);
      this.constants = constants;
    }

    public void setHoveredItem(TreeItem hoveredItem, Follower.Prefetcher<Void> follower) {
      this.hoveredItem = hoveredItem;
      this.follower = follower;
    }

    @Override
    protected <S extends StylingString> S format(Widget item, Object element, S string) {
      Service.StateTreeNode data = ((ApiState.Node)element).getData();
      if (data == null) {
        string.append("Loading...", string.structureStyle());
      } else {
        string.append(data.getName(), string.defaultStyle());
        if (data.hasPreview()) {
         string.append(": ", string.structureStyle());
         Path.Any follow = getFollower(item).canFollow(null);
         string.startLink(follow);
         Formatter.format(data.getPreview(), constants.getConstants(data.getConstants()),
             data.getPreviewIsValue(), string,
             (follow == null) ? string.defaultStyle() : string.linkStyle());
         string.endLink();
        }
      }
      return string;
    }

    private Follower.Prefetcher<Void> getFollower(Widget item) {
      return (item == hoveredItem) ? follower : nullPrefetcher();
    }

    @Override
    protected boolean isFollowable(Object element) {
      ApiState.Node node = (ApiState.Node)element;
      return node.getData() != null && node.getData().hasValuePath();
    }
  }
}


text:
#include "xrdp.h"

/*****************************************************************************/
/* returns error */
int APP_CC
read_preamble_packet(struct xrdp_process* self)
{
    // Using the session stream
    int ns_len = 0;
    int idx;
    int len;
    // cache a pointer to client_info
    struct xrdp_client_info *client_info = self->session->client_info;

    struct stream* s;
    make_stream(s);
    init_stream(s, 10000);

    DEBUG(("in read_preamble_packet"));

    // 5 bytes should include the colon
    if (trans_force_read_s(self->server_trans, s, 5) == 0)
    {
        idx = g_pos(s->data, ":") + 1; // skip colon
        ns_len = g_atoi(s->data);
        DEBUG(("Preamble length %i", ns_len));
        len = ns_len - 5 + idx + 1; // trailing comma as well
        DEBUG(("Preamble to read %i", len));
        if (trans_force_read_s(self->server_trans, s, len) == 0)
        {
            DEBUG(("Preamble body %s", s->data));
            // this will be used as a processing buffer when data required
            // so do not assume will exist in this state later on.
            client_info->osirium_preamble_buffer = (char*)g_malloc(ns_len+1, 1);
            in_uint8s(s, idx);    // skip netstring header
            in_uint8a(s,
                    client_info->osirium_preamble_buffer,
                    ns_len);
            DEBUG(("Preamble %s", client_info->osirium_preamble_buffer));
            free_stream(s);
            return 0;
        }
    }
    free_stream(s);
    DEBUG(("out read_preamble_packet"));
    return 0;
}

int APP_CC
process_preamble_packet(struct xrdp_wm *self)
{
    char* line_end;
    char* t;
    char* q;
    char* r;
    DEBUG(("Preamble %s", self->session->client_info->osirium_preamble_buffer))
    line_end = g_strchr(self->session->client_info->osirium_preamble_buffer, '\n');
    while (line_end != 0)
    {
        q = line_end+1;
        // locate start of name
        while ( isspace(*q) )
        {
            q++;
        }
        DEBUG(("Preamble still needing processing %s", q));
        // locate separator
        t = r = g_strchr(q,'=');
        if ( r == 0 ) break;  // handle broken preamble by assuming at end of pre
        *r = 0; // ensure name terminated

        // strip possible trailing spaces from name
        while ( isspace(*--t) )
        {
            *t = 0; // nulls to terminate name
        };
        // locate start of value
        while ( isspace(*++r) )
        {
          // pre increment
        }

        line_end = g_strchr(r, '\n'); //locate end of value
        if (line_end)   // may be last value in preamble and have no LF at end.
        {
            *line_end = 0; // null terminate value
        }
        DEBUG(("Name '%s' Value '%s'", q, r));
        list_add_item(self->mm->login_names, (long)g_strdup(q));
        list_add_item(self->mm->login_values, (long)g_strdup(r));
    }
    g_free(self->session->client_info->osirium_preamble_buffer);
    self->session->client_info->osirium_preamble_buffer = 0;
    xrdp_wm_set_login_mode(self, 2);
}


text:
package org.apache.hadoop.hdfs.server.datanode;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.apache.commons.logging.Log;
import org.apache.hadoop.fs.FSDataNodeReadProfilingData;

import org.apache.hadoop.hdfs.protocol.Block;
import org.apache.hadoop.hdfs.protocol.DataTransferProtocol;
import org.apache.hadoop.hdfs.protocol.FSConstants;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.net.SocketOutputStream;
import org.apache.hadoop.util.DataChecksum;
import org.apache.hadoop.util.DataTransferThrottler;
import org.apache.hadoop.util.Progressable;

/**
 * Reads a block from the disk and sends it to a recipient.
 */
public class BlockSender implements java.io.Closeable, FSConstants {
  public static final Log LOG = DataNode.LOG;
  static final Log ClientTraceLog = DataNode.ClientTraceLog;

  private DataChecksum checksum; // checksum stream
  private long offset; // starting position to read
  private long endOffset; // ending position
  private long blockLength;
  private int bytesPerChecksum; // chunk size
  private int checksumSize; // checksum size
  private boolean chunkOffsetOK; // if need to send chunk offset
  private long seqno; // sequence number of packet

  private boolean transferToAllowed = true;
  private boolean pktIncludeVersion = false;
  private int packetVersion;
  // set once entire requested byte range has been sent to the client
  private boolean sentEntireByteRange;
  private boolean verifyChecksum; //if true, check is verified while reading
  private DataTransferThrottler throttler;
  private String clientTraceFmt; // format of client trace log message
  private DatanodeBlockReader blockReader;

  private BlockCrcUpdater crcUpdater = null;

  final ReplicaToRead replicaToRead;

  /**
   * Minimum buffer used while sending data to clients. Used only if
   * transferTo() is enabled. 64KB is not that large. It could be larger, but
   * not sure if there will be much more improvement.
   */
  private static final int MIN_BUFFER_WITH_TRANSFERTO = 64*1024;

  BlockSender(int namespaceId, Block block, long startOffset, long length,
              boolean corruptChecksumOk, boolean chunkOffsetOK,
              boolean verifyChecksum, DataNode datanode) throws IOException {
    this(namespaceId, block, startOffset, length, false, corruptChecksumOk,
        chunkOffsetOK, verifyChecksum, false, true, datanode, null);
  }

  BlockSender(int namespaceId, Block block, long startOffset, long length,
      boolean ignoreChecksum, boolean corruptChecksumOk, boolean chunkOffsetOK,
      boolean verifyChecksum, boolean pktIncludeVersion, boolean forceOldPktVersion, DataNode datanode,
      String clientTraceFmt) throws IOException {

    replicaToRead = datanode.data.getReplicaToRead(namespaceId, block);
    if (replicaToRead == null) {
      throw new IOException("Can't find block " + block + " in volumeMap");
    }

    long blockLength = replicaToRead.getBytesVisible();
    boolean transferToAllowed = datanode.transferToAllowed;

    DatanodeBlockReader.BlockInputStreamFactory streamFactory =
      new DatanodeBlockReader.BlockInputStreamFactory(
        namespaceId, block, replicaToRead, datanode, datanode.data, ignoreChecksum,
        verifyChecksum, corruptChecksumOk);
    blockReader = streamFactory.getBlockReader();

    initialize(namespaceId, block, blockLength, startOffset, length,
        corruptChecksumOk, chunkOffsetOK, verifyChecksum, transferToAllowed,
        datanode.updateBlockCrcWhenRead, pktIncludeVersion, forceOldPktVersion,
        streamFactory, clientTraceFmt);
  }

  public BlockSender(int namespaceId, Block block, long blockLength, long startOffset, long length,
              boolean corruptChecksumOk, boolean chunkOffsetOK,
              boolean verifyChecksum, boolean transferToAllowed, boolean pktIncludeVersion,
              BlockWithChecksumFileReader.InputStreamWithChecksumFactory streamFactory
              ) throws IOException {

    replicaToRead = null;
    blockReader = new BlockWithChecksumFileReader(namespaceId, block, true,
        false, verifyChecksum, corruptChecksumOk, streamFactory);

    initialize(namespaceId, block, blockLength, startOffset, length,
        corruptChecksumOk, chunkOffsetOK, verifyChecksum, transferToAllowed,
        false, pktIncludeVersion, true, streamFactory, null);
  }

  private void initialize(int namespaceId, Block block, long blockLength,
      long startOffset, long length, boolean corruptChecksumOk,
      boolean chunkOffsetOK, boolean verifyChecksum, boolean transferToAllowed,
      boolean allowUpdateBlocrCrc, boolean pktIncludeVersion, boolean forceOldPktVersion,
      BlockWithChecksumFileReader.InputStreamWithChecksumFactory streamFactory,
      String clientTraceFmt) throws IOException {
    try {
      this.chunkOffsetOK = chunkOffsetOK;
      this.verifyChecksum = verifyChecksum;
      this.blockLength = blockLength;
      this.transferToAllowed = transferToAllowed;
      this.clientTraceFmt = clientTraceFmt;
      this.pktIncludeVersion = pktIncludeVersion;

      if (this.pktIncludeVersion && ! forceOldPktVersion) {
        this.packetVersion = blockReader.getPreferredPacketVersion();
      } else {
        this.packetVersion = DataTransferProtocol.PACKET_VERSION_CHECKSUM_FIRST;
      }

      checksum = blockReader.getChecksumToSend(blockLength);

      bytesPerChecksum = blockReader.getBytesPerChecksum();
      checksumSize = blockReader.getChecksumSize();

      if (length < 0) {
        length = blockLength;
      }

      endOffset = blockLength;
      if (startOffset < 0 || startOffset > endOffset
          || (length + startOffset) > endOffset) {
        String msg = " Offset " + startOffset + " and length " + length
        + " don't match block " + block + " ( blockLen " + endOffset + " )";
        LOG.warn("sendBlock() : " + msg);
        throw new IOException(msg);
      }

      offset = (startOffset - (startOffset % bytesPerChecksum));
      if (length >= 0) {
        // Make sure endOffset points to end of a checksumed chunk.
        long tmpLen = startOffset + length;
        if (tmpLen % bytesPerChecksum != 0) {
          tmpLen += (bytesPerChecksum - tmpLen % bytesPerChecksum);
        }
        if (tmpLen < endOffset) {
          endOffset = tmpLen;
        }
      }

      // Recalculate block CRC if:
      // 1. it is configured to be allowed;
      // 2. the block is finalized
      // 3. the full block is to be read
      // 4. there is no Block CRC already cached
      // 5. the block format is CRC32 and checksum size is 4
      if (allowUpdateBlocrCrc &&
          (!transferToAllowed || verifyChecksum)
          && startOffset == 0
          && length >= blockLength
          && replicaToRead != null
          && !replicaToRead.hasBlockCrcInfo()
          && replicaToRead.isFinalized()
          && replicaToRead instanceof DatanodeBlockInfo
          && checksumSize == DataChecksum.DEFAULT_CHECKSUM_SIZE
          && checksum != null
          && (checksum.getChecksumType() == DataChecksum.CHECKSUM_CRC32 || checksum
              .getChecksumType() == DataChecksum.CHECKSUM_CRC32C)) {
        // Needs to recalculate block CRC
        crcUpdater = new BlockCrcUpdater(bytesPerChecksum, true);
      }

      seqno = 0;

      blockReader.initialize(offset, blockLength);
    } catch (IOException ioe) {
      IOUtils.closeStream(this);
      throw ioe;
    }
  }

  public void fadviseStream(int advise, long offset, long len)
      throws IOException {
    blockReader.fadviseStream(advise, offset, len);
  }

  public ReplicaToRead getReplicaToRead() {
    return replicaToRead;
  }

  /**
   * close opened files.
   */
  public void close() throws IOException {
    if (blockReader != null) {
      blockReader.close();
    }
  }

  /**
   * Converts an IOExcpetion (not subclasses) to SocketException.
   * This is typically done to indicate to upper layers that the error
   * was a socket error rather than often more serious exceptions like
   * disk errors.
   */
  static IOException ioeToSocketException(IOException ioe) {
    if (ioe.getClass().equals(IOException.class)) {
      // "se" could be a new class in stead of SocketException.
      IOException se = new SocketException("Original Exception : " + ioe);
      se.initCause(ioe);
      /* Change the stacktrace so that original trace is not truncated
       * when printed.*/
      se.setStackTrace(ioe.getStackTrace());
      return se;
    }
    // otherwise just return the same exception.
    return ioe;
  }

  public void enableReadProfiling(FSDataNodeReadProfilingData dnData) {
    blockReader.enableReadProfiling(dnData);
  }

  /**
   * Sends upto maxChunks chunks of data.
   *
   * When blockInPosition is >= 0, assumes 'out' is a
   * {@link SocketOutputStream} and tries
   * {@link SocketOutputStream#transferToFully(FileChannel, long, int)} to
   * send data (and updates blockInPosition).
   */
  private int sendChunks(ByteBuffer pkt, int maxChunks, OutputStream out)
                         throws IOException {
    // Sends multiple chunks in one packet with a single write().

    int len = (int) Math.min(endOffset - offset,
                            (((long) bytesPerChecksum) * ((long) maxChunks)));

    // truncate len so that any partial chunks will be sent as a final packet.
    // this is not necessary for correctness, but partial chunks are
    // ones that may be recomputed and sent via buffer copy, so try to minimize
    // those bytes
    if (len > bytesPerChecksum && len % bytesPerChecksum != 0) {
      len -= len % bytesPerChecksum;
    }

    if (len == 0) {
      return 0;
    }

    int numChunks = (len + bytesPerChecksum - 1)/bytesPerChecksum;
    int packetLen = len + numChunks*checksumSize + 4;
    pkt.clear();

    // The packet format is documented in DFSOuputStream.Packet.getBuffer().
    // Here we need to use the exact packet format since it can be received
    // by both of DFSClient, or BlockReceiver in the case of replication, which
    // uses the same piece of codes as receiving data from DFSOutputStream.
    //

    // write packet header
    pkt.putInt(packetLen);
    if (pktIncludeVersion) {
      pkt.putInt(packetVersion);
    }
    pkt.putLong(offset);
    pkt.putLong(seqno);
    pkt.put((byte)((offset + len >= endOffset) ? 1 : 0));
               //why no ByteBuf.putBoolean()?
    pkt.putInt(len);

    int checksumOff = pkt.position();
    byte[] buf = pkt.array();

    blockReader.sendChunks(out, buf, offset, checksumOff,
        numChunks, len, crcUpdater, packetVersion);

    if (throttler != null) { // rebalancing so throttle
      throttler.throttle(packetLen);
    }

    return len;
  }

  private int getPacketHeaderLen() {
    return DataNode.getPacketHeaderLen(pktIncludeVersion);
  }

  /**
   * sendBlock() is used to read block and its metadata and stream the data to
   * either a client or to another datanode.
   *
   * @param out  stream to which the block is written to
   * @param baseStream optional. if non-null, out is assumed to
   *        be a wrapper over this stream. This enables optimizations for
   *        sending the data, e.g.
   *        {@link SocketOutputStream#transferToFully(FileChannel,
   *        long, int)}.
   * @param throttler for sending data.
   * @return total bytes reads, including crc.
   */
  public long sendBlock(DataOutputStream out, OutputStream baseStream,
                 DataTransferThrottler throttler) throws IOException {
    return sendBlock(out, baseStream, throttler, null);
  }

  /**
   * sendBlock() is used to read block and its metadata and stream the data to
   * either a client or to another datanode.
   *
   * @param out  stream to which the block is written to
   * @param baseStream optional. if non-null, out is assumed to
   *        be a wrapper over this stream. This enables optimizations for
   *        sending the data, e.g.
   *        {@link SocketOutputStream#transferToFully(FileChannel,
   *        long, int)}.
   * @param throttler for sending data.
   * @param progress for signalling progress.
   * @return total bytes reads, including crc.
   */
  public long sendBlock(DataOutputStream out, OutputStream baseStream,
       DataTransferThrottler throttler, Progressable progress) throws IOException {
    if( out == null ) {
      throw new IOException( "out stream is null" );
    }
    this.throttler = throttler;

    long initialOffset = offset;
    long totalRead = 0;
    OutputStream streamForSendChunks = out;

    final long startTime = ClientTraceLog.isInfoEnabled() ? System.nanoTime() : 0;
    try {
      try {
        checksum.writeHeader(out);
        if ( chunkOffsetOK ) {
          out.writeLong( offset );
        }
        out.flush();
      } catch (IOException e) { //socket error
        throw ioeToSocketException(e);
      }

      int maxChunksPerPacket;
      int pktSize = SIZE_OF_INTEGER + getPacketHeaderLen();

      if (transferToAllowed && !verifyChecksum &&
          baseStream instanceof SocketOutputStream &&
          blockReader.prepareTransferTo()) {
        streamForSendChunks = baseStream;

        // assure a mininum buffer size.
        maxChunksPerPacket = (Math.max(BUFFER_SIZE,
                                       MIN_BUFFER_WITH_TRANSFERTO)
                              + bytesPerChecksum - 1)/bytesPerChecksum;

        // packet buffer has to be able to do a normal transfer in the case
        // of recomputing checksum
        pktSize += (bytesPerChecksum + checksumSize) * maxChunksPerPacket;
      } else {
        maxChunksPerPacket = Math.max(1,
                 (BUFFER_SIZE + bytesPerChecksum - 1)/bytesPerChecksum);
        pktSize += (bytesPerChecksum + checksumSize) * maxChunksPerPacket;
      }

      ByteBuffer pktBuf = ByteBuffer.allocate(pktSize);

      while (endOffset > offset) {
        long len = sendChunks(pktBuf, maxChunksPerPacket,
                              streamForSendChunks);
        if (progress != null) {
          progress.progress();
        }
        offset += len;
        totalRead += len + ((len + bytesPerChecksum - 1)/bytesPerChecksum*
                            checksumSize);
        seqno++;
      }
      try {
        out.writeInt(0); // mark the end of block
        out.flush();
      } catch (IOException e) { //socket error
        throw ioeToSocketException(e);
      }

      sentEntireByteRange = true;
    }
    catch (RuntimeException e) {
      LOG.error("unexpected exception sending block", e);

      throw new IOException("unexpected runtime exception", e);
    }
    finally {
      if (clientTraceFmt != null) {
        final long endTime = System.nanoTime();
        ClientTraceLog.info(String.format(clientTraceFmt, totalRead, initialOffset, endTime - startTime));
      }
      close();
    }

    if (crcUpdater != null && crcUpdater.isCrcValid(offset)
        && !replicaToRead.hasBlockCrcInfo()) {
      int blockCrcOffset = crcUpdater.getBlockCrcOffset();
      int blockCrc = crcUpdater.getBlockCrc();
      if (DataNode.LOG.isDebugEnabled()) {
        DataNode.LOG.debug("Setting block CRC " + replicaToRead + " offset "
            + blockCrcOffset + " CRC " + blockCrc);
      }
      ((DatanodeBlockInfo) replicaToRead).setBlockCrc(blockCrcOffset, blockCrc);
    }

    return totalRead;
  }

  boolean didSendEntireByteRange() {
    return sentEntireByteRange;
  }

  public static interface InputStreamFactory {
    public BlockDataFile.Reader getBlockDataFileReader() throws IOException;
  }
}


text:
package com.mgmtp.perfload.core.common.util;

import static com.google.common.base.Preconditions.checkArgument;

/**
 * This exception must be thrown in cases that should lead to an abortion of the complete load test.
 *
 * @author rnaegele
 */
public final class AbortionException extends RuntimeException {
	private static final long serialVersionUID = 1L;

	private final LtStatus status;

	/**
	 * Constructs a new {@link AbortionException} with the specified status, detail message and
	 * cause.
	 *
	 * @param status
	 *            the status (allowed values are {@link LtStatus#ERROR} and
	 *            {@link LtStatus#INTERRUPTED})
	 * @param message
	 *            the detail message (which is saved for later retrieval by the
	 *            {@link #getMessage()} method).
	 *
	 * @param cause
	 *            cause the cause (which is saved for later retrieval by the {@link #getCause()}
	 *            method). (A <tt>null</tt> value is permitted, and indicates that the cause is
	 *            nonexistent or unknown.)
	 */
	public AbortionException(final LtStatus status, final String message, final Throwable cause) {
		super(message, cause);
		checkArgument(status != LtStatus.SUCCESSFUL, "Exception status cannot be " + LtStatus.SUCCESSFUL);
		this.status = status;
	}

	/**
	 * Constructs a new {@link AbortionException} with the specified status.
	 *
	 * @param status
	 *            the status (allowed values are {@link LtStatus#ERROR} and
	 *            {@link LtStatus#INTERRUPTED})
	 */
	public AbortionException(final LtStatus status) {
		this(status, null);
	}

	/**
	 * Constructs a new {@link AbortionException} with the specified status and detail message.
	 *
	 * @param status
	 *            the status (allowed values are {@link LtStatus#ERROR} and
	 *            {@link LtStatus#INTERRUPTED})
	 * @param message
	 *            the detail message (which is saved for later retrieval by the
	 *            {@link #getMessage()} method).
	 */
	public AbortionException(final LtStatus status, final String message) {
		this(status, message, null);
	}

	/**
	 * @return the status
	 */
	public LtStatus getStatus() {
		return status;
	}
}


text:
Brooks's Catalog
=============================

[Books](https://github.com/bmershon/fieldnotes/wiki/Nonfiction-Books), [essays](https://github.com/bmershon/fieldnotes/wiki/Essays), [films](https://github.com/bmershon/fieldnotes/wiki/Film) and [other resources](https://github.com/bmershon/fieldnotes/wiki/Technical-Writing) I have found to be particularly great or enriching.

Entries are usually ordered by appending new materials as I encounter them to an continually growing list on each particular page of this wiki. I especially like to keep track of those materials which do not reside on my bookshelf, so that I may read/watch/listen again, recommend these resources to a friend, and recall where I have been.

I started faithfully recording toward the end of my undergraduate studies, so high school canon and a good deal of other materials have not made it to the list.

This is my garden that I find great pleasure in cultivating.

I've organized this material into the [wiki pages for this respository](https://github.com/bmershon/Fieldnotes/wiki).


text:
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProfileAccessTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create(\PR::getConfig()['tables']['access'], function(Blueprint $table)
		{
			$table->increments('id');

			$table->integer(\PR::getConfig()['tables']['profiles'] . '_id')->unsigned();
			$table->foreign(\PR::getConfig()['tables']['profiles'] . '_id')->references('id')->on(\PR::getConfig()['tables']['profiles'])->onDelete('cascade');

			$table->string('route_action');
			$table->string('route_name');
			$table->string('route_path');

			$table->timestamps();
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::dropIfExists('restaurant_roles');
	}

}


text:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WX.Model;
using WX.Model.ApiRequests;
using WX.Model.ApiResponses;
using Xunit;

namespace FrameworkCoreTest.Merchant
{
    public class MerchantGetTest : MockPostApiBaseTest<MerchantGetRequest, MerchantGetResponse>
    {
        [Fact]
        public void MockGetSuccessTest()
        {
            MockSetup(false);
            var response = mock_client.Object.Execute(Request);
            Assert.Equal("test product 1", response.ProductInfo.ProductBase.Name);
            Assert.Equal("123456789", response.ProductInfo.ProductID);

        }

        protected override MerchantGetRequest InitRequestObject()
        {
            return new MerchantGetRequest
            {
                AccessToken = "123",
                ProductID = "123456789"
            };
        }

        protected override string GetReturnResult(bool errResult)
        {
            if (errResult) return s_errmsg;
            var result = JsonConvert.SerializeObject(new { errcode = 0, errmsg = "success", product_info = GetProduct() });
            Console.WriteLine(result);
            return result;
        }

        private ProductInfo GetProduct()
        {
            var product = new Product
            {

                Name = "test product 1",
                OriPrice = 999,
                MainImage = "http://image1.product1.jpg",
                BuyLimit = 1,
                Categories = new string[] { "530707078" },
                Properties = new List<ProductProperty> {
                    new ProductProperty{ VID = "107979797", ID = "121321"}
                },
                Detail = new List<ProductDetail> {
                    new ProductDetail{ Text = "hello world"}
                },
                Images = new string[] { "http://img2.product1.jgp" },
                SkuInfos = new List<SkuInfo>
                {
                    new SkuInfo{ ID = "107575757", VID = new string[]{"2222", "3333"}}
                }
            };

            var skulist = new List<Sku>{
                new Sku{
                    SkuID = "1075741873:1079742386",
                    Price = 30,
                    IconUrl = "http://sku1icon.jpg",
                    ProductCode = "testing",
                    OriPrice = 90000,
                    Quantity = 10
                }
            };

            var attrext = new Attrext
            {
                IsPostFree = false,
                IsHasReceipt = true,
                IsSupportReplace = false,
                IsUnderGuaranty = false,
                Location = new Location
                {
                    Country = "中国",
                    City = "上海市",
                    Province = "上海市",
                    Address = "重庆南路"
                }
            };

            var delivery = new Delivery
            {
                DeliveryType = 1,
                TemplateID = 1
            };

            var productInfo = new ProductInfo
            {
                ProductBase = product,
                SkuList = skulist,
                Attrext = attrext,
                DeliveryInfo = delivery,
                ProductID = "123456789"
            };

            return productInfo;
        }
    }
}


text:
import React,{Component} from 'react';
import {connect} from 'react-redux';
import {viewPost} from '../actions';

import Loading from "../components/loading";
import PostDetail from "../containers/postdetail";

class ViewPost extends Component{
	componentWillMount() {
		const {id} = this.props.match.params;
		this.props.viewPost(id);
	}
	render(){
		const {isFetching,isFetched} = this.props.post;
		return(
			<div className="container">
				{isFetching?<Loading/>:(isFetched?<PostDetail data={this.props}/>:<Loading/>)}
			</div>
		)
	}
}

function mapStateToProps(state){
	return{
		post:state.post
	}
}

export default connect(mapStateToProps,{viewPost})(ViewPost);


text:
namespace Ren.CMS.Persistence.Domain
{
    using System;
    using System.Collections.Generic;
    using System.Text;

    public class Link
    {
        #region Properties

        public virtual string HoverStateClass
        {
            get; set;
        }

        public virtual int Id
        {
            get; set;
        }

        public virtual string LinkAction
        {
            get; set;
        }

        public virtual string LinkController
        {
            get; set;
        }

        public virtual string LinkHref
        {
            get; set;
        }

        public virtual string LinkIsActive
        {
            get; set;
        }

        public virtual string LinkRelationship
        {
            get; set;
        }

        public virtual string LinkText
        {
            get; set;
        }

        public virtual string LinkType
        {
            get; set;
        }

        public virtual string NormalStateClass
        {
            get; set;
        }

        public virtual string SublinkAction
        {
            get; set;
        }

        public virtual string SublinkController
        {
            get; set;
        }

        public virtual System.Nullable<int> SublinkFrom
        {
            get; set;
        }

        #endregion Properties
    }
}


text:
SELECT MifElapsed, MifElapsed / NormalElapsed as "MifToNorm", NormalElapsed, NormalElapsed / MifElapsed as "NormToMif"
FROM
MifSummary