Today the world recalls the passion and death of Jesus. There is sadness and mourning in the air. This year our family has decided to spend the three hours from noon to 3 at church, attending the Seven Last Words and then Stations of the Cross, and then the Celebration of the Lord's Passion. My sons, ages 12 and 8, feel up to the challenge.
As we enter in the final moments of Jesus' life, I thought I'd share a little thought about this day.
Good Friday for 2016 falls on March 25, the same date as the Solemnity of the Annunciation. The Church recognizes the importance of both of these feasts and so transfers the Annunciation to the first day after the Octave of Easter on April 4 to give the solemnity the full honor it deserves….


Size: 2.8" x 6.0" x 0.35"
The Canon Checkbook III "Money Manager" continued the idea of an Account Manager introduced already in with the Checkbook and continued with the beautiful Checkbook II.
It is very similar to the Texas Instruments TI-2200 II Checkwriter.
Dismantling this Checkbook calculator manufactured in Thailand reveals a very solid construction centered around a NEC uPD1833G singlechip calculator circuit.
In 2003 this Checkbook III was still available in the stores.


'Madonna 66' is the complete collection of 66 lost and found Polaroid photographs, shot by Richard Corman in June 1983.
A limited edition publication of 1,500 copies. 164 pages, housed in a flesh pink hard back cover, bound by a 50mm thick removable black rubber band, symbolic of Madonna's bracelets. Signed by Richard Corman and encased in a protective outer flesh pink travel box.
A new limited edition print, Polaroid #49, from Madonna 66 Collection will be released soon exclusively via Madonna66.com, see the Shop Now link below.


text:
Hà Nội announces two COVID-19 patients
Update: December, 06/2020 - 09:03
National Hospital for Tropical Diseases 2 where both patients are being treated. —VNA/VNS Photo
HÀ NỘI — Hà Nội authorities on Saturday announced two coronavirus-positive patients, who were both quarantined at home at the time of detection.
One is a Libyan diplomat and the other a man who was treated for the virus after being repatriated from France but has since tested positive again during his home quarantine.
He is a 55-year-old from Đống Đa District. Samples have been taken from both his daughter and a taxi driver who he came into contact with.
The man was discharged from hospital on December 1 and was quarantined at home. His sample was taken for test for the first time on December 3 and the result on December 4 confirmed he was positive again. The patient is currently being treated at National Hospital for Tropical Diseases 2.
The other positive case is a 54-year-old Libyan man who lives and works in Việt Nam. On November 12, he flew to Turkey and stayed there until November 19 to bring his wife and four children, to Việt Nam on Flight QR976, which transited in Doha (Qatar) and landed at Nội Bài airport on November 19.
As he is a diplomat, he and his family were quarantined at their residence in Bắc Từ Liêm District. On November 19, the district Medical Centre took samples for tests and the results confirmed all of them negative.
The patient, who has underlying high blood pressure and cardiovascular diseases, felt tired on November 30 and was brought to Đức Giang General Hospital for treatment in a specialised vehicle. He was brought back to his home on December 1, and the result of his sample test on December 3 was positive. He then was moved to National Hospital for Tropical Diseases 2 for treatment and quarantine. His wife and children have all tested negative. — VNS
Russia to resume flights to Hà Nội (January, 17 2021)

redpajama_set_name: RedPajamaCommonCrawl


Diamond Engagement Semi Mounts,Semi-Mountings,Engagement Ring Settings at JewelryVortex.com.
Sorry, there are no products available with your selected filters. Please remove one or more filters by clicking [x] to broaden your selection.
Designed to compliment your choice of diamond or stone center. Select settings can accommodate round or princess cut stones with several prongs to secure your precious center stone.


text:
/**
 * @fileoverview The class representing one block.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

goog.provide('Blockly.Block');

goog.require('Blockly.BlockSvg');
goog.require('Blockly.Comment');
goog.require('Blockly.Connection');
goog.require('Blockly.ErrorIcon');
goog.require('Blockly.Input');
goog.require('Blockly.Language');
goog.require('Blockly.Mutator');
goog.require('Blockly.ContextMenu');
goog.require('Blockly.Warning');
goog.require('Blockly.Workspace');
goog.require('Blockly.Xml');
goog.require('goog.Timer');

/**
 * Unique ID counter for created blocks.
 * @private
 */
Blockly.uidCounter_ = 0;

/**
 * Class for one block.
 * @param {!Blockly.Workspace} workspace The new block's workspace.
 * @param {?string} prototypeName Name of the language object containing
 *     type-specific functions for this block.
 * @constructor
 */
Blockly.Block = function(workspace, prototypeName) {
  this.id = ++Blockly.uidCounter_;
  this.outputConnection = null;
  this.nextConnection = null;
  this.previousConnection = null;
  this.inputList = [];
  this.inputsInline = false;
  this.rendered = false;
  this.collapsed = false;
  this.disabled = false;
  this.editable = workspace.editable;
  this.deletable = workspace.editable;
  this.tooltip = '';
  this.contextMenu = true;

  this.parentBlock_ = null;
  this.childBlocks_ = [];

  this.isInFlyout = false;
  this.workspace = workspace;

  workspace.addTopBlock(this);

  // Copy the type-specific functions and data from the prototype.
  if (prototypeName) {
    this.type = prototypeName;
    var prototype = Blockly.Language[prototypeName];
    if (!prototype) {
      throw 'Error: "' + prototypeName + '" is an unknown language block.';
    }
    goog.mixin(this, prototype);
  }
  // Call an initialization function, if it exists.
  if (goog.isFunction(this.init)) {
    this.init();
  }
  // Bind an onchange function, if it exists.
  if (this.editable && goog.isFunction(this.onchange)) {
    Blockly.bindEvent_(workspace.getCanvas(), 'blocklyWorkspaceChange', this,
                       this.onchange);
  }
};

/**
 * Pointer to SVG representation of the block.
 * @type {Blockly.BlockSvg}
 * @private
 */
Blockly.Block.prototype.svg_ = null;

/**
 * Block's mutator icon (if any).
 * @type {Blockly.Mutator}
 */
Blockly.Block.prototype.mutator = null;

/**
 * Block's comment icon (if any).
 * @type {Blockly.Comment}
 */
Blockly.Block.prototype.comment = null;

/**
 * Block's warning icon (if any).
 * @type {Blockly.Warning}
 */
Blockly.Block.prototype.warning = null;

/**
 * Block's error icon (if any).
 * @type {Blockly.ErrorIcon}
 */
Blockly.Block.prototype.errorIcon = null;

/**
 * Create and initialize the SVG representation of the block.
 */
Blockly.Block.prototype.initSvg = function() {
  this.svg_ = new Blockly.BlockSvg(this);
  this.svg_.init();
  Blockly.bindEvent_(this.svg_.getRootElement(), 'mousedown', this,
                     this.onMouseDown_);
  this.workspace.getCanvas().appendChild(this.svg_.getRootElement());
};

/**
 * Return the root node of the SVG or null if none exists.
 * @return {Element} The root SVG node (probably a group).
 */
Blockly.Block.prototype.getSvgRoot = function() {
  return this.svg_ && this.svg_.getRootElement();
};

/**
 * Is the mouse dragging a block?
 * 0 - No drag operation.
 * 1 - Still inside the sticky DRAG_RADIUS.
 * 2 - Freely draggable.
 * @private
 */
Blockly.Block.dragMode_ = 0;

/**
 * Wrapper function called when a mouseUp occurs during a drag operation.
 * @type {Array.<!Array>}
 * @private
 */
Blockly.Block.onMouseUpWrapper_ = null;

/**
 * Wrapper function called when a mouseMove occurs during a drag operation.
 * @type {Array.<!Array>}
 * @private
 */
Blockly.Block.onMouseMoveWrapper_ = null;

/**
 * Stop binding to the global mouseup and mousemove events.
 * @private
 */
Blockly.Block.terminateDrag_ = function() {
  if (Blockly.Block.onMouseUpWrapper_) {
    Blockly.unbindEvent_(Blockly.Block.onMouseUpWrapper_);
    Blockly.Block.onMouseUpWrapper_ = null;
  }
  if (Blockly.Block.onMouseMoveWrapper_) {
    Blockly.unbindEvent_(Blockly.Block.onMouseMoveWrapper_);
    Blockly.Block.onMouseMoveWrapper_ = null;
  }
  var selected = Blockly.selected;
  if (Blockly.Block.dragMode_ == 2) {
    // Terminate a drag operation.
    if (selected) {
      // Update the connection locations.
      var xy = selected.getRelativeToSurfaceXY();
      var dx = xy.x - selected.startDragX;
      var dy = xy.y - selected.startDragY;
      selected.moveConnections_(dx, dy);
      delete selected.draggedBubbles_;
      selected.setDragging_(false);
      selected.render();
      goog.Timer.callOnce(
          selected.bumpNeighbours_, Blockly.BUMP_DELAY, selected);
      // Fire an event to allow scrollbars to resize.
      Blockly.fireUiEvent(window, 'resize');
    }
  }
  if (selected) {
    selected.workspace.fireChangeEvent();
  }
  Blockly.Block.dragMode_ = 0;
};

/**
 * Select this block.  Highlight it visually.
 */
Blockly.Block.prototype.select = function() {
  if (!this.svg_) {
    throw 'Block is not rendered.'
  }
  if (Blockly.selected) {
    // Unselect any previously selected block.
    Blockly.selected.unselect();
  }
  Blockly.selected = this;
  this.svg_.addSelect();
  Blockly.fireUiEvent(this.workspace.getCanvas(), 'blocklySelectChange');
};

/**
 * Unselect this block.  Remove its highlighting.
 */
Blockly.Block.prototype.unselect = function() {
  if (!this.svg_) {
    throw 'Block is not rendered.'
  }
  Blockly.selected = null;
  this.svg_.removeSelect();
  Blockly.fireUiEvent(this.workspace.getCanvas(), 'blocklySelectChange');
};

/**
 * Dispose of this block.
 * @param {boolean} healStack If true, then try to heal any gap by connecting
 *     the next statement with the previous statement.  Otherwise, dispose of
 *     all children of this block.
 * @param {boolean} animate If true, show a disposal animation and sound.
 */
Blockly.Block.prototype.dispose = function(healStack, animate) {
  this.unplug(healStack);

  if (animate && this.svg_) {
    this.svg_.disposeUiEffect();
  }

  //This block is now at the top of the workspace.
  // Remove this block from the workspace's list of top-most blocks.
  if (this.workspace) {
    this.workspace.removeTopBlock(this);
    this.workspace = null;
  }

  // Just deleting this block from the DOM would result in a memory leak as
  // well as corruption of the connection database.  Therefore we must
  // methodically step through the blocks and carefully disassemble them.

  // Switch off rerendering.
  this.rendered = false;

  if (Blockly.selected == this) {
    Blockly.selected = null;
    // If there's a drag in-progress, unlink the mouse events.
    Blockly.Block.terminateDrag_();
  }

  // First, dispose of all my children.
  for (var x = this.childBlocks_.length - 1; x >= 0; x--) {
    this.childBlocks_[x].dispose(false);
  }
  // Then dispose of myself.
  if (this.mutator) {
    this.mutator.dispose();
  }
  if (this.comment) {
    this.comment.dispose();
  }
  if (this.warning) {
    this.warning.dispose();
  }
  if (this.errorIcon) {
    this.errorIcon.dispose();
  }

  // Dispose of all inputs and their titles.
  for (var x = 0, input; input = this.inputList[x]; x++) {
    input.dispose();
  }
  this.inputList = [];
  // Dispose of any remaining connections (next/previous/output).
  var connections = this.getConnections_(true);
  for (var x = 0; x < connections.length; x++) {
    var connection = connections[x];
    if (connection.targetConnection) {
      connection.disconnect();
    }
    connections[x].dispose();
  }
  // Dispose of the SVG and break circular references.
  if (this.svg_) {
    this.svg_.dispose();
    this.svg_ = null;
  }
};

/**
 * Unplug this block from its superior block.  If this block is a statement,
 * optionally reconnect the block underneath with the block on top.
 * @param {boolean} healStack Disconnect child statement and reconnect stack.
 * @param {boolean} bump Move the unplugged block sideways a short distance.
 */
Blockly.Block.prototype.unplug = function(healStack, bump) {
  bump = bump && !!this.getParent();
  if (this.outputConnection) {
    if (this.outputConnection.targetConnection) {
      // Disconnect from any superior block.
      this.setParent(null);
    }
  } else {
    var previousTarget = null;
    if (this.previousConnection && this.previousConnection.targetConnection) {
      // Remember the connection that any next statements need to connect to.
      previousTarget = this.previousConnection.targetConnection;
      // Detach this block from the parent's tree.
      this.setParent(null);
    }
    if (healStack && this.nextConnection &&
        this.nextConnection.targetConnection) {
      // Disconnect the next statement.
      var nextTarget = this.nextConnection.targetConnection;
      var nextBlock = this.nextConnection.targetBlock();
      this.nextConnection.disconnect();
      nextBlock.setParent(null);
      if (previousTarget) {
        // Attach the next statement to the previous statement.
        previousTarget.connect(nextTarget);
      }
    }
  }
  if (bump) {
    // Bump the block sideways.
    var dx = Blockly.SNAP_RADIUS * (Blockly.RTL ? -1 : 1);
    var dy = Blockly.SNAP_RADIUS * 2;
    this.moveBy(dx, dy);
  }
};

/**
 * Return the coordinates of the top-left corner of this block relative to the
 * drawing surface's origin (0,0).
 * @return {!Object} Object with .x and .y properties.
 */
Blockly.Block.prototype.getRelativeToSurfaceXY = function() {
  var x = 0;
  var y = 0;
  if (this.svg_) {
    var element = this.svg_.getRootElement();
    do {
      // Loop through this block and every parent.
      var xy = Blockly.getRelativeXY_(element);
      x += xy.x;
      y += xy.y;
      element = element.parentElement;
    } while (element && element != this.workspace.getCanvas());
  }
  return {x: x, y: y};
};

/**
 * Move a block by a relative offset.
 * @param {number} dx Horizontal offset.
 * @param {number} dy Vertical offset.
 */
Blockly.Block.prototype.moveBy = function(dx, dy) {
  var xy = this.getRelativeToSurfaceXY();
  this.svg_.getRootElement().setAttribute('transform',
      'translate(' + (xy.x + dx) + ', ' + (xy.y + dy) + ')');
  this.moveConnections_(dx, dy);
};

/**
 * Handle a mouse-down on an SVG block.
 * @param {!Event} e Mouse down event.
 * @private
 */
Blockly.Block.prototype.onMouseDown_ = function(e) {
  if (this.isInFlyout) {
    return;
  }
  // Update Blockly's knowledge of its own location.
  Blockly.svgResize();
  Blockly.Block.terminateDrag_();
  this.select();
  Blockly.hideChaff();
  if (Blockly.isRightButton(e)) {
    // Right-click.
    if (Blockly.ContextMenu) {
      this.showContextMenu_(e.clientX, e.clientY);
    }
  } else if (!this.editable) {
    // Allow uneditable blocks to be selected and context menued, but not
    // dragged.  Let this event bubble up to document, so the workspace may be
    // dragged instead.
    return;
  } else {
    // Left-click (or middle click)
    Blockly.removeAllRanges();
    Blockly.setCursorHand_(true);
    // Look up the current translation and record it.
    var xy = this.getRelativeToSurfaceXY();
    this.startDragX = xy.x;
    this.startDragY = xy.y;
    // Record the current mouse position.
    this.startDragMouseX = e.clientX;
    this.startDragMouseY = e.clientY;
    Blockly.Block.dragMode_ = 1;
    Blockly.Block.onMouseUpWrapper_ = Blockly.bindEvent_(document,
        'mouseup', this, this.onMouseUp_);
    Blockly.Block.onMouseMoveWrapper_ = Blockly.bindEvent_(document,
        'mousemove', this, this.onMouseMove_);
    // Build a list of comments that need to be moved and where they started.
    this.draggedBubbles_ = [];
    var descendants = this.getDescendants();
    for (var x = 0, descendant; descendant = descendants[x]; x++) {
      if (descendant.mutator) {
        var data = descendant.mutator.getIconLocation();
        data.bubble = descendant.mutator;
        this.draggedBubbles_.push(data);
      }
      if (descendant.comment) {
        var data = descendant.comment.getIconLocation();
        data.bubble = descendant.comment;
        this.draggedBubbles_.push(data);
      }
      if (descendant.warning) {
        var data = descendant.warning.getIconLocation();
        data.bubble = descendant.warning;
        this.draggedBubbles_.push(data);
      }
      if (descendant.errorIcon) {
        var data = descendant.errorIcon.getIconLocation();
        data.bubble = descendant.errorIcon;
        this.draggedBubbles_.push(data);
      }
    }
  }
  // This event has been handled.  No need to bubble up to the document.
  e.stopPropagation();
};

/**
 * Handle a mouse-up anywhere in the SVG pane.  Is only registered when a
 * block is clicked.  We can't use mouseUp on the block since a fast-moving
 * cursor can briefly escape the block before it catches up.
 * @param {!Event} e Mouse up event.
 * @private
 */
Blockly.Block.prototype.onMouseUp_ = function(e) {
  Blockly.resetWorkspaceArrangements();
  Blockly.Block.terminateDrag_();
  if (Blockly.selected && Blockly.highlightedConnection_) {
    // Connect two blocks together.
    Blockly.localConnection_.connect(Blockly.highlightedConnection_);
    if (this.svg_) {
      // Trigger a connection animation.
      // Determine which connection is inferior (lower in the source stack).
      var inferiorConnection;
      if (Blockly.localConnection_.isSuperior()) {
        inferiorConnection = Blockly.highlightedConnection_;
      } else {
        inferiorConnection = Blockly.localConnection_;
      }
      inferiorConnection.sourceBlock_.svg_.connectionUiEffect();
    }
    if (this.workspace.trashcan && this.workspace.trashcan.isOpen) {
      // Don't throw an object in the trash can if it just got connected.
      this.workspace.trashcan.close();
    }
  } else if (this.workspace.trashcan && this.workspace.trashcan.isOpen) {
    var trashcan = this.workspace.trashcan;
    goog.Timer.callOnce(trashcan.close, 100, trashcan);
    Blockly.selected.dispose(false, true);
    // Dropping a block on the trash can will usually cause the workspace to
    // resize to contain the newly positioned block.  Force a second resize now
    // that the block has been deleted.
    Blockly.fireUiEvent(window, 'resize');
  }
  if (Blockly.highlightedConnection_) {
    Blockly.highlightedConnection_.unhighlight();
    Blockly.highlightedConnection_ = null;
  }
};

/**
 * Load the block's help page in a new window.
 * @private
 */
Blockly.Block.prototype.showHelp_ = function() {
  var url = goog.isFunction(this.helpUrl) ? this.helpUrl() : this.helpUrl;
  if (url) {
    window.open(url);
  }
};

/**
 * Duplicate this block and its children.
 * @return {!Blockly.Block} The duplicate.
 * @private
 */
Blockly.Block.prototype.duplicate_ = function() {
  // Create a duplicate via XML.
  var xmlBlock = Blockly.Xml.blockToDom_(this);
  Blockly.Xml.deleteNext(xmlBlock);
  var newBlock = Blockly.Xml.domToBlock_(
      /** @type {!Blockly.Workspace} */ (this.workspace), xmlBlock);
  // Move the duplicate next to the old block.
  var xy = this.getRelativeToSurfaceXY();
  if (Blockly.RTL) {
    xy.x -= Blockly.SNAP_RADIUS;
  } else {
    xy.x += Blockly.SNAP_RADIUS;
  }
  xy.y += Blockly.SNAP_RADIUS * 2;
  newBlock.moveBy(xy.x, xy.y);
  return newBlock;
};

/**
 * Show the context menu for this block.
 * @param {number} x X-coordinate of mouse click.
 * @param {number} y Y-coordinate of mouse click.
 * @private
 */
Blockly.Block.prototype.showContextMenu_ = function(x, y) {
  if (!this.contextMenu) {
    return;
  }
  // Save the current block in a variable for use in closures.
  var block = this;
  var options = [];

  if (this.deletable) {
    // Option to duplicate this block.
    var duplicateOption = {
      text: Blockly.MSG_DUPLICATE_BLOCK,
      enabled: true,
      callback: function() {
        block.duplicate_();
      }
    };
    if (this.getDescendants().length > this.workspace.remainingCapacity()) {
      duplicateOption.enabled = false;
    }
    options.push(duplicateOption);

    if (Blockly.Comment && !this.collapsed) {
      // Option to add/remove a comment.
      var commentOption = {enabled: true};
      if (this.comment) {
        commentOption.text = Blockly.MSG_REMOVE_COMMENT;
        commentOption.callback = function() {
          block.setCommentText(null);
        };
      } else {
        commentOption.text = Blockly.MSG_ADD_COMMENT;
        commentOption.callback = function() {
          block.setCommentText('');
        };
      }
      options.push(commentOption);
    }

    // Option to make block inline.
    if (!this.collapsed) {
      for (var i = 0; i < this.inputList.length; i++) {
        if (this.inputList[i].type == Blockly.INPUT_VALUE) {
          // Only display this option if there is a value input on the block.
          var inlineOption = {enabled: true};
          inlineOption.text = this.inputsInline ? Blockly.MSG_EXTERNAL_INPUTS :
                                                  Blockly.MSG_INLINE_INPUTS;
          inlineOption.callback = function() {
            block.setInputsInline(!block.inputsInline);
          };
          options.push(inlineOption);
          break;
        }
      }
    }

    if (Blockly.collapse) {
      // Option to collapse/expand block.
      if (this.collapsed) {
        var expandOption = {enabled: true};
        expandOption.text = Blockly.MSG_EXPAND_BLOCK;
        expandOption.callback = function() {
          block.setCollapsed(false);
        };
        options.push(expandOption);
      } else {
        var collapseOption = {enabled: true};
        collapseOption.text = Blockly.MSG_COLLAPSE_BLOCK;
        collapseOption.callback = function() {
          block.setCollapsed(true);
        };
        options.push(collapseOption);
      }
    }

    // Option to disable/enable block.
    var disableOption = {
      text: this.disabled ?
          Blockly.MSG_ENABLE_BLOCK : Blockly.MSG_DISABLE_BLOCK,
      enabled: !this.getInheritedDisabled(),
      callback: function() {
        block.setDisabled(!block.disabled);
      }
    };
    options.push(disableOption);

    // Option to delete this block.
    // Count the number of blocks that are nested in this block.
    var descendantCount = this.getDescendants().length;
    if (block.nextConnection && block.nextConnection.targetConnection) {
      // Blocks in the current stack would survive this block's deletion.
      descendantCount -= this.nextConnection.targetBlock().
          getDescendants().length;
    }
    var deleteOption = {
      text: descendantCount == 1 ? Blockly.MSG_DELETE_BLOCK :
          Blockly.MSG_DELETE_X_BLOCKS.replace('%1', descendantCount),
      enabled: true,
      callback: function() {
        block.dispose(true, true);
      }
    };
    options.push(deleteOption);
  }

  // Option to get help.
  var url = goog.isFunction(this.helpUrl) ? this.helpUrl() : this.helpUrl;
  var helpOption = {enabled: !!url};
  helpOption.text = Blockly.MSG_HELP;
  helpOption.callback = function() {
    block.showHelp_();
  };
  options.push(helpOption);

  // Allow the block to add or modify options.
  if (this.customContextMenu) {
    this.customContextMenu(options);
  }

  Blockly.ContextMenu.show(x, y, options);
};

/**
 * Returns all connections originating from this block.
 * @param {boolean} all If true, return all connections even hidden ones.
 *     Otherwise return those that are visible.
 * @return {!Array.<!Blockly.Connection>} Array of connections.
 * @private
 */
Blockly.Block.prototype.getConnections_ = function(all) {
  var myConnections = [];
  if (all || this.rendered) {
    if (this.outputConnection) {
      myConnections.push(this.outputConnection);
    }
    if (this.nextConnection) {
      myConnections.push(this.nextConnection);
    }
    if (this.previousConnection) {
      myConnections.push(this.previousConnection);
    }
    if (all || !this.collapsed) {
      for (var x = 0, input; input = this.inputList[x]; x++) {
        if (input.connection) {
          myConnections.push(input.connection);
        }
      }
    }
  }
  return myConnections;
};

/**
 * Move the connections for this block and all blocks attached under it.
 * Also update any attached bubbles.
 * @param {number} dx Horizontal offset from current location.
 * @param {number} dy Vertical offset from current location.
 * @private
 */
Blockly.Block.prototype.moveConnections_ = function(dx, dy) {
  if (!this.rendered) {
    // Rendering is required to lay out the blocks.
    // This is probably an invisible block attached to a collapsed block.
    return;
  }
  var myConnections = this.getConnections_(false);
  for (var x = 0; x < myConnections.length; x++) {
    myConnections[x].moveBy(dx, dy);
  }
  if (this.mutator) {
    this.mutator.computeIconLocation();
  }
  if (this.comment) {
    this.comment.computeIconLocation();
  }
  if (this.warning) {
    this.warning.computeIconLocation();
  }
  if (this.errorIcon) {
    this.errorIcon.computeIconLocation();
  }

  // Recurse through all blocks attached under this one.
  for (var x = 0; x < this.childBlocks_.length; x++) {
    this.childBlocks_[x].moveConnections_(dx, dy);
  }
};

/**
 * Recursively adds or removes the dragging class to this node and its children.
 * @param {boolean} adding True if adding, false if removing.
 * @private
 */
Blockly.Block.prototype.setDragging_ = function(adding) {
  if (adding) {
    this.svg_.addDragging();
  } else {
    this.svg_.removeDragging();
  }
  // Recurse through all blocks attached under this one.
  for (var x = 0; x < this.childBlocks_.length; x++) {
    this.childBlocks_[x].setDragging_(adding);
  }
};

/**
 * Drag this block to follow the mouse.
 * @param {!Event} e Mouse move event.
 * @private
 */
Blockly.Block.prototype.onMouseMove_ = function(e) {
  if (e.type == 'mousemove' && e.x == 1 && e.y == 0 && e.button == 0) {
    /* HACK:
     The current versions of Chrome for Android (18.0) has a bug where finger-
     swipes trigger a rogue 'mousemove' event with invalid x/y coordinates.
     Ignore events with this signature.  This may result in a one-pixel blind
     spot in other browsers, but this shouldn't be noticable.
    */
    e.stopPropagation();
    return;
  }
  Blockly.removeAllRanges();
  var dx = e.clientX - this.startDragMouseX;
  var dy = e.clientY - this.startDragMouseY;
  if (Blockly.Block.dragMode_ == 1) {
    // Still dragging within the sticky DRAG_RADIUS.
    var dr = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
    if (dr > Blockly.DRAG_RADIUS) {
      // Switch to unrestricted dragging.
      Blockly.Block.dragMode_ = 2;
      // Push this block to the very top of the stack.
      this.setParent(null);
      this.setDragging_(true);
    }
  }
  if (Blockly.Block.dragMode_ == 2) {
    // Unrestricted dragging.
    var x = this.startDragX + dx;
    var y = this.startDragY + dy;
    this.svg_.getRootElement().setAttribute('transform',
        'translate(' + x + ', ' + y + ')');
    // Drag all the nested bubbles.
    for (var i = 0; i < this.draggedBubbles_.length; i++) {
      var commentData = this.draggedBubbles_[i];
      commentData.bubble.setIconLocation(commentData.x + dx,
                                         commentData.y + dy);
    }

    // Check to see if any of this block's connections are within range of
    // another block's connection.
    var myConnections = this.getConnections_(false);
    var closestConnection = null;
    var localConnection = null;
    var radiusConnection = Blockly.SNAP_RADIUS;
    for (var i = 0; i < myConnections.length; i++) {
      var myConnection = myConnections[i];
      var neighbour = myConnection.closest(radiusConnection, dx, dy);
      if (neighbour.connection) {
        closestConnection = neighbour.connection;
        localConnection = myConnection;
        radiusConnection = neighbour.radius;
      }
    }

    // Remove connection highlighting if needed.
    if (Blockly.highlightedConnection_ &&
        Blockly.highlightedConnection_ != closestConnection) {
      Blockly.highlightedConnection_.unhighlight();
      Blockly.highlightedConnection_ = null;
      Blockly.localConnection_ = null;
    }
    // Add connection highlighting if needed.
    if (closestConnection &&
        closestConnection != Blockly.highlightedConnection_) {
      closestConnection.highlight();
      Blockly.highlightedConnection_ = closestConnection;
      Blockly.localConnection_ = localConnection;
    }
    // Flip the trash can lid if needed.
    if (this.workspace.trashcan && this.deletable) {
      this.workspace.trashcan.onMouseMove(e);
    }
  }
  // This event has been handled.  No need to bubble up to the document.
  e.stopPropagation();
};

/**
 * Bump unconnected blocks out of alignment.  Two blocks which aren't actually
 * connected should not coincidentally line up on screen.
 * @private
 */
Blockly.Block.prototype.bumpNeighbours_ = function() {
  var rootBlock = this.getRootBlock();
  // Loop though every connection on this block.
  var myConnections = this.getConnections_(false);
  for (var x = 0; x < myConnections.length; x++) {
    var connection = myConnections[x];
    // Spider down from this block bumping all sub-blocks.
    if (connection.targetConnection && connection.isSuperior()) {
      connection.targetBlock().bumpNeighbours_();
    }

    var neighbours = connection.neighbours_(Blockly.SNAP_RADIUS);
    for (var y = 0; y < neighbours.length; y++) {
      var otherConnection = neighbours[y];
      // If both connections are connected, that's probably fine.  But if
      // either one of them is unconnected, then there could be confusion.
      if (!connection.targetConnection || !otherConnection.targetConnection) {
        // Only bump blocks if they are from different tree structures.
        if (otherConnection.sourceBlock_.getRootBlock() != rootBlock) {
          // Always bump the inferior block.
          if (connection.isSuperior()) {
            otherConnection.bumpAwayFrom_(connection);
          } else {
            connection.bumpAwayFrom_(otherConnection);
          }
        }
      }
    }
  }
};

/**
 * Return the parent block or null if this block is at the top level.
 * @return {Blockly.Block} The block that holds the current block.
 */
Blockly.Block.prototype.getParent = function() {
  // Look at the DOM to see if we are nested in another block.
  return this.parentBlock_;
};

/**
 * Return the parent block that surrounds the current block, or null if this
 * block has no surrounding block.  A parent block might just be the previous
 * statement, whereas the surrounding block is an if statement, while loop, etc.
 * @return {Blockly.Block} The block that surrounds the current block.
 */
Blockly.Block.prototype.getSurroundParent = function() {
  var block = this;
  while (true) {
    do {
      var prevBlock = block;
      block = block.getParent();
      if (!block) {
        // Ran off the top.
        return null;
      }
    } while (block.nextConnection &&
             block.nextConnection.targetBlock() == prevBlock);
    // This block is an enclosing parent, not just a statement in a stack.
    return block;
  }
};

/**
 * Return the top-most block in this block's tree.
 * This will return itself if this block is at the top level.
 * @return {!Blockly.Block} The root block.
 */
Blockly.Block.prototype.getRootBlock = function() {
  var rootBlock;
  var block = this;
  do {
    rootBlock = block;
    block = rootBlock.parentBlock_;
  } while (block);
  return rootBlock;
};

/**
 * Find all the blocks that are directly nested inside this one.
 * Includes value and block inputs, as well as any following statement.
 * Excludes any connection on an output tab or any preceding statement.
 * @return {!Array.<!Blockly.Block>} Array of blocks.
 */
Blockly.Block.prototype.getChildren = function() {
  return this.childBlocks_;
};

/**
 * Set parent of this block to be a new block or null.
 * @param {Blockly.Block} newParent New parent block.
 */
Blockly.Block.prototype.setParent = function(newParent) {
  if (this.parentBlock_) {
    // Remove this block from the old parent's child list.
    var children = this.parentBlock_.childBlocks_;
    for (var child, x = 0; child = children[x]; x++) {
      if (child == this) {
        children.splice(x, 1);
        break;
      }
    }
    // Move this block up the DOM.  Keep track of x/y translations.
    var xy = this.getRelativeToSurfaceXY();
    this.workspace.getCanvas().appendChild(this.svg_.getRootElement());
    this.svg_.getRootElement().setAttribute('transform',
        'translate(' + xy.x + ', ' + xy.y + ')');

    // Disconnect from superior blocks.
    this.parentBlock_ = null;
    if (this.previousConnection && this.previousConnection.targetConnection) {
      this.previousConnection.disconnect();
    }
    if (this.outputConnection && this.outputConnection.targetConnection) {
      this.outputConnection.disconnect();
    }
    // This block hasn't actually moved on-screen, so there's no need to update
    // its connection locations.
  } else {
    // Remove this block from the workspace's list of top-most blocks.
    this.workspace.removeTopBlock(this);
  }

  this.parentBlock_ = newParent;
  if (newParent) {
    // Add this block to the new parent's child list.
    newParent.childBlocks_.push(this);

    var oldXY = this.getRelativeToSurfaceXY();
    if (newParent.svg_ && this.svg_) {
      newParent.svg_.getRootElement().appendChild(this.svg_.getRootElement());
    }
    var newXY = this.getRelativeToSurfaceXY();
    // Move the connections to match the child's new position.
    this.moveConnections_(newXY.x - oldXY.x, newXY.y - oldXY.y);
  } else {
    this.workspace.addTopBlock(this);
  }
};

/**
 * Find all the blocks that are directly or indirectly nested inside this one.
 * Includes this block in the list.
 * Includes value and block inputs, as well as any following statements.
 * Excludes any connection on an output tab or any preceding statements.
 * @return {!Array.<!Blockly.Block>} Flattened array of blocks.
 */
Blockly.Block.prototype.getDescendants = function() {
  var blocks = [this];
  for (var child, x = 0; child = this.childBlocks_[x]; x++) {
    blocks = blocks.concat(child.getDescendants());
  }
  return blocks;
};

/**
 * Get the colour of a block.
 * @return {number|Array} HSV hue value or RGB Array.
 */
Blockly.Block.prototype.getColour = function() {
  return (this.rgbArray_ == null ? this.colourHue_ : this.rgbArray_);
};

/**
 * Change the colour of a block.
 * @param {number|Array} hueOrRGBArray HSV hue value or array of RGB values.
 */
Blockly.Block.prototype.setColour = function(hueOrRGBArray) {
  if(Array.isArray(hueOrRGBArray)) {
    this.rgbArray_ = hueOrRGBArray;
    this.colourHue_ = null;
  } else {
    this.colourHue_ = hueOrRGBArray;
    this.rgbArray_ = null;
  }
  this.updateColour();
};

/**
 * Update the colour of a block.
 */
Blockly.Block.prototype.updateColour = function() {
  if (this.svg_) {
    this.svg_.updateColour();
  }
  if (this.mutator) {
    this.mutator.updateColour();
  }
  if (this.comment) {
    this.comment.updateColour();
  }
  if (this.warning) {
    this.warning.updateColour();
  }
  if (this.errorIcon) {
    this.errorIcon.updateColour();
  }
  if (this.rendered) {
    // Bump every dropdown to change its colour.
    for (var x = 0, input; input = this.inputList[x]; x++) {
      for (var y = 0, title; title = input.titleRow[y]; y++) {
        title.setText(null);
      }
    }
    this.render();
  }
};

/**
 * Returns the named title from a block.
 * @param {string} name The name of the title.
 * @return {*} Named title, or null if title does not exist.
 * @private
 */
Blockly.Block.prototype.getTitle_ = function(name) {
  for (var x = 0, input; input = this.inputList[x]; x++) {
    for (var y = 0, title; title = input.titleRow[y]; y++) {
      if (title.name === name) {
        return title;
      }
    }
  }
  return null;
};

/**
 * Returns the language-neutral value from the title of a block.
 * @param {string} name The name of the title.
 * @return {?string} Value from the title or null if title does not exist.
 */
Blockly.Block.prototype.getTitleValue = function(name) {
  var title = this.getTitle_(name);
  if (title) {
    return title.getValue();
  }
  return null;
};

/**
 * Change the title value for a block (e.g. 'CHOOSE' or 'REMOVE').
 * @param {string} newValue Value to be the new title.
 * @param {string} name The name of the title.
 */
Blockly.Block.prototype.setTitleValue = function(newValue, name) {
  var title = this.getTitle_(name);
  if (title) {
    title.setValue(newValue);
  } else {
    throw 'Title "' + name + '" not found.';
  }
};

/**
 * Change the tooltip text for a block.
 * @param {string|!Element} newTip Text for tooltip or a parent element to
 *     link to for its tooltip.
 */
Blockly.Block.prototype.setTooltip = function(newTip) {
  this.tooltip = newTip;
};

/**
 * Set whether this block can chain onto the bottom of another block.
 * @param {boolean} newBoolean True if there can be a previous statement.
 * @param {string|Array.<string>|null} opt_check Statement type or list of
 *     statement types.  Null or undefined if any type could be connected.
 */
Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) {
  if (this.previousConnection) {
    if (this.previousConnection.targetConnection) {
      throw 'Must disconnect previous statement before removing connection.';
    }
    this.previousConnection.dispose();
    this.previousConnection = null;
  }
  if (newBoolean) {
    if (this.outputConnection) {
      throw 'Remove output connection prior to adding previous connection.';
    }
    if (opt_check === undefined) {
      opt_check = null;
    }
    this.previousConnection =
        new Blockly.Connection(this, Blockly.PREVIOUS_STATEMENT);
    this.previousConnection.setCheck(opt_check);
  }
  if (this.rendered) {
    this.render();
    this.bumpNeighbours_();
  }
};

/**
 * Set whether another block can chain onto the bottom of this block.
 * @param {boolean} newBoolean True if there can be a next statement.
 * @param {string|Array.<string>|null} opt_check Statement type or list of
 *     statement types.  Null or undefined if any type could be connected.
 */
Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) {
  if (this.nextConnection) {
    if (this.nextConnection.targetConnection) {
      throw 'Must disconnect next statement before removing connection.';
    }
    this.nextConnection.dispose();
    this.nextConnection = null;
  }
  if (newBoolean) {
    if (opt_check === undefined) {
      opt_check = null;
    }
    this.nextConnection =
        new Blockly.Connection(this, Blockly.NEXT_STATEMENT);
    this.nextConnection.setCheck(opt_check);
  }
  if (this.rendered) {
    this.render();
    this.bumpNeighbours_();
  }
};

/**
 * Set whether this block returns a value.
 * @param {boolean} newBoolean True if there is an output.
 * @param {string|Array.<string>|null} opt_check Returned type or list of
 *     returned types.  Null or undefined if any type could be returned
 *     (e.g. variable get).
 */
Blockly.Block.prototype.setOutput = function(newBoolean, opt_check) {
  if (this.outputConnection) {
    if (this.outputConnection.targetConnection) {
      throw 'Must disconnect output value before removing connection.';
    }
    this.outputConnection.dispose();
    this.outputConnection = null;
  }
  if (newBoolean) {
    if (this.previousConnection) {
      throw 'Remove previous connection prior to adding output connection.';
    }
    if (opt_check === undefined) {
      opt_check = null;
    }
    this.outputConnection =
        new Blockly.Connection(this, Blockly.OUTPUT_VALUE);
    this.outputConnection.setCheck(opt_check);
  }
  if (this.rendered) {
    this.render();
    this.bumpNeighbours_();
  }
};

/**
 * Set whether value inputs are arranged horizontally or vertically.
 * @param {boolean} newBoolean True if inputs are horizontal.
 */
Blockly.Block.prototype.setInputsInline = function(newBoolean) {
  this.inputsInline = newBoolean;
  if (this.rendered) {
    this.render();
    this.bumpNeighbours_();
    this.workspace.fireChangeEvent();
  }
};

/**
 * Set whether the block is disabled or not.
 * @param {boolean} disabled True if disabled.
 */
Blockly.Block.prototype.setDisabled = function(disabled) {
  if (this.disabled == disabled) {
    return;
  }
  this.disabled = disabled;
  this.svg_.updateDisabled();
  this.workspace.fireChangeEvent();
};

/**
 * Get whether the block is disabled or not due to parents.
 * The block's own disabled property is not considered.
 * @return {boolean} True if disabled.
 */
Blockly.Block.prototype.getInheritedDisabled = function() {
  var block = this;
  while (true) {
    block = block.getSurroundParent();
    if (!block) {
      // Ran off the top.
      return false;
    } else if (block.disabled) {
      return true;
    }
  }
};

/**
 * Set whether the block is collapsed or not.
 * @param {boolean} collapsed True if collapsed.
 */
Blockly.Block.prototype.setCollapsed = function(collapsed) {
  if (this.collapsed == collapsed) {
    return;
  }
  this.collapsed = collapsed;
  //Prepare the string for collapsing if needed
  if (collapsed){
    if (this.prepareCollapsedText && goog.isFunction(this.prepareCollapsedText))
      this.prepareCollapsedText();
  }
  // Show/hide the inputs.
  var display = collapsed ? 'none' : 'block';
  var displayCollapsedTtile = collapsed ? 'block' : 'none';
  var renderList = [];
  for (var x = 0, input; input = this.inputList[x]; x++) {
    for (var y = 0, title; title = input.titleRow[y]; y++) {
      var titleElement = title.getRootElement ?
          title.getRootElement() : title;
      if (input.subtype && input.subtype === Blockly.DUMMY_COLLAPSED_INPUT)
        titleElement.style.display = displayCollapsedTtile;
      else
        titleElement.style.display = display;
    }
    if (input.connection) {
      // This is a connection.
      if (collapsed) {
        input.connection.hideAll();
      } else {
        renderList = renderList.concat(input.connection.unhideAll());
      }
      var child = input.connection.targetBlock();
      if (child) {
        child.svg_.getRootElement().style.display = display;
        if (collapsed) {
          child.rendered = false;
        }
      }
    }
  }

  if (collapsed) {
    if (this.mutator) {
      this.mutator.setVisible(false);
    }
    if (this.comment) {
      this.comment.setVisible(false);
    }
    if (this.warning) {
      this.warning.setVisible(false);
    }
    if (this.errorIcon) {
      this.errorIcon.setVisible(false);
    }
  }

  if (renderList.length == 0) {
    // No child blocks, just render this block.
    renderList[0] = this;
  }
  if (this.rendered) {
    for (var x = 0, block; block = renderList[x]; x++) {
      block.render();
    }
    this.bumpNeighbours_();
  }
};

/**
 * Shortcut for appending a value input row.
 * @param {string} name Language-neutral identifier which may used to find this
 *     input again.  Should be unique to this block.
 * @return {!Blockly.Input} The input object created.
 */
Blockly.Block.prototype.appendValueInput = function(name) {
  return this.appendInput_(Blockly.INPUT_VALUE, name);
};

/**
 * Shortcut for appending a statement input row.
 * @param {string} name Language-neutral identifier which may used to find this
 *     input again.  Should be unique to this block.
 * @return {!Blockly.Input} The input object created.
 */
Blockly.Block.prototype.appendStatementInput = function(name) {
  return this.appendInput_(Blockly.NEXT_STATEMENT, name);
};

/**
 * Shortcut for appending an inline value input row.
 * @param {string} name Language-neutral identifier which may used to find this
 *     input again.  Should be unique to this block.
 * @return {!Blockly.Input} The input object created.
 */

Blockly.Block.prototype.appendIndentedValueInput = function(name) {
    return this.appendInput_(Blockly.INDENTED_VALUE, name);
};

/**
 * Shortcut for appending a dummy input row.
 * @param {string} opt_name Language-neutral identifier which may used to find
 *     this input again.  Should be unique to this block.
 * @return {!Blockly.Input} The input object created.
 */
Blockly.Block.prototype.appendDummyInput = function(opt_name) {
  return this.appendInput_(Blockly.DUMMY_INPUT, opt_name || '');
};

/**
 * Shortcut for appending a collapsed dummy input row.
 * @param {string} opt_name Language-neutral identifier which may used to find
 *     this input again.  Should be unique to this block.
 * @return {!Blockly.Input} The input object created.
 */
Blockly.Block.prototype.appendCollapsedInput = function(opt_name) {
  return this.appendInput_(Blockly.DUMMY_COLLAPSED_INPUT, opt_name || '');
};

/**
 * Add a value input, statement input or local variable to this block.
 * @param {number} type Either Blockly.INPUT_VALUE, Blockly.NEXT_STATEMENT, Blockly.DUMMY_INPUT,
 *     or subtypes Blockly.INDENTED_VALUE, Blockly.DUMMY_COLLAPSED_INPUT.
 * @param {string} name Language-neutral identifier which may used to find this
 *     input again.  Should be unique to this block.
 * @return {!Blockly.Input} The input object created.
 * @private
 */

Blockly.Block.prototype.appendInput_ = function(type, name) {
  var connection = null;
  if (type == Blockly.INPUT_VALUE || type == Blockly.NEXT_STATEMENT || type == Blockly.INDENTED_VALUE) {
    connection = new Blockly.Connection(this, type);
  }

  var input = new Blockly.Input(type, name, this, connection);
  // Append input to list.
  this.inputList.push(input);
  if (this.rendered) {
    this.render();
    // Adding an input will cause the block to change shape.
    this.bumpNeighbours_();
  }
  return input;
};

/**
 * Move an input to a different location on this block.
 * @param {string} name The name of the input to move.
 * @param {string} refName Name of input that should be after the moved input.
 */
Blockly.Block.prototype.moveInputBefore = function(name, refName) {
  if (name == refName) {
    throw 'Can\'t move "' + name + '" to itself.';
  }
  // Find both inputs.
  var inputIndex = -1;
  var refIndex = -1;
  for (var x = 0, input; input = this.inputList[x]; x++) {
    if (input.name == name) {
      inputIndex = x;
      if (refIndex != -1) {
        break;
      }
    } else if (input.name == refName) {
      refIndex = x;
      if (inputIndex != -1) {
        break;
      }
    }
  }
  if (inputIndex == -1) {
    throw 'Named input "' + name + '" not found.';
  }
  if (refIndex == -1) {
    throw 'Reference input "' + name + '" not found.';
  }
  // Remove input.
  this.inputList.splice(inputIndex, 1);
  if (inputIndex < refIndex) {
    refIndex--;
  }
  // Reinsert input.
  this.inputList.splice(refIndex, 0, input);
  if (this.rendered) {
    this.render();
    // Moving an input will cause the block to change shape.
    this.bumpNeighbours_();
  }
};

/**
 * Remove an input from this block.
 * @param {string} name The name of the input.
 */
Blockly.Block.prototype.removeInput = function(name) {
  for (var x = 0, input; input = this.inputList[x]; x++) {
    if (input.name == name) {
      if (input.connection && input.connection.targetConnection) {
        // Disconnect any attached block.
        input.connection.targetBlock().setParent(null);
      }
      input.dispose();
      this.inputList.splice(x, 1);
      if (this.rendered) {
        this.render();
        // Removing an input will cause the block to change shape.
        this.bumpNeighbours_();
      }
      return;
    }
  }
  throw 'Input "' + name + '" not found.';
};

/**
 * Fetches the named input object.
 * @param {string} name The name of the input.
 * @return {Object} The input object, or null of the input does not exist.
 */
Blockly.Block.prototype.getInput = function(name) {
  for (var x = 0, input; input = this.inputList[x]; x++) {
    if (input.name == name) {
      return input;
    }
  }
  // This input does not exist.
  return null;
};

/**
 * Fetches the block attached to the named input.
 * @param {string} name The name of the input.
 * @return {Blockly.Block} The attached value block, or null if the input is
 *     either disconnected or if the input does not exist.
 */
Blockly.Block.prototype.getInputTargetBlock = function(name) {
  var input = this.getInput(name);
  return input && input.connection && input.connection.targetBlock();
};

/**
 * Give this block a mutator dialog.
 * @param {Blockly.Mutator} mutator A mutator dialog instance or null to remove.
 */
Blockly.Block.prototype.setMutator = function(mutator) {
  if (this.mutator && this.mutator !== mutator) {
    this.mutator.dispose();
  }
  if (mutator) {
    mutator.block_ = this;
    this.mutator = mutator;
    if (this.svg_) {
      mutator.createIcon();
    }
  }
};

/**
 * Returns the comment on this block (or '' if none).
 * @return {string} Block's comment.
 */
Blockly.Block.prototype.getCommentText = function() {
  if (this.comment) {
    var comment = this.comment.getText();
    // Trim off trailing whitespace.
    return comment.replace(/\s+$/, '').replace(/ +\n/g, '\n');
  }
  return '';
};

/**
 * Set this block's comment text.
 * @param {?string} text The text, or null to delete.
 */
Blockly.Block.prototype.setCommentText = function(text) {
  if (!Blockly.Comment) {
    throw 'Comments not supported.';
  }
  var changedState = false;
  if (goog.isString(text)) {
    if (!this.comment) {
      this.comment = new Blockly.Comment(this);
      changedState = true;
    }
    this.comment.setText(/** @type {string} */ (text));
  } else {
    if (this.comment) {
      this.comment.dispose();
      changedState = true;
    }
  }
  if (this.rendered) {
    this.render();
    if (changedState) {
      // Adding or removing a comment icon will cause the block to change shape.
      this.bumpNeighbours_();
    }
  }
};

/**
 * Set this block's warning text.
 * @param {?string} text The text, or null to delete.
 */
Blockly.Block.prototype.setWarningText = function(text) {
  if (!Blockly.Warning) {
    throw 'Warnings not supported.';
  }
  var changedState = false;
  if (goog.isString(text)) {
    if (!this.warning) {
      this.warning = new Blockly.Warning(this);
      changedState = true;
    }
    this.warning.setText(/** @type {string} */ (text));
  } else {
    if (this.warning) {
      this.warning.dispose();
      changedState = true;
    }
  }
  if (this.rendered) {
    this.render();
    if (changedState) {
      // Adding or removing a warning icon will cause the block to change shape.
      this.bumpNeighbours_();
    }
  }
};

/**
 * Set this block's warning text.
 * @param {?string} text The text, or null to delete.
 */
Blockly.Block.prototype.setErrorIconText = function(text) {
  if (!Blockly.ErrorIcon) {
    throw 'Warnings not supported.';
  }
  var changedState = false;
  if (goog.isString(text)) {
    if (!this.errorIcon) {
      this.errorIcon = new Blockly.ErrorIcon(this);
      changedState = true;
    }
    this.errorIcon.setText(/** @type {string} */ (text));
  } else {
    if (this.errorIcon) {
      this.errorIcon.dispose();
      changedState = true;
    }
  }
  if (this.rendered) {
    this.render();
    if (changedState) {
      // Adding or removing a warning icon will cause the block to change shape.
      this.bumpNeighbours_();
    }
  }
};

/**
 * Render the block.
 * Lays out and reflows a block based on its contents and settings.
 */
Blockly.Block.prototype.render = function() {
  if (!this.svg_) {
    throw 'Uninitialized block cannot be rendered.  Call block.initSvg()';
  }
  this.svg_.render();
};

redpajama_set_name: RedPajamaGithub


text:
Q: Run .exe file of C code using Eclipse I've make a very simple basic code in C language using Eclipse IDE.
Eclipse details:

*

*Eclipse IDE for C/C++ Developers

*Version: Juno Service Release 2

*Build id: 20130225-0426

Here is the code:
#include <stdio.h>

int main( int argc, char ** argv ) {
    printf("Hello, World!\n");
    return 0;
}

Runs successfully in Eclipse, it generates .exe & .o file in Project/Debug directory. I am trying to run that .exe file but it is not working.
Eclipse acts as if it ran the program very quickly and then terminates it. Window appears, but nothing happens when I run the .exe. It just looks like a flash of a dialogue box.
What should be the problem? I don't want to change the IDE and I've already tried these two things:

*

*Eclipse CDT won't run compiled exe files

*eclipse won't run my exe file

A: Windows is opening a command prompt for your program, running your print statement, and then closing the window (because your function is over).
If you want to see the result of your program, run the command prompt, navigate to the directory of your .exe file, and run it from there.

A: You should also try this:
Right click on your project name in the Project Explorer view, then go to Run As and click on Local C/C++ Application

A: run the program from the command prompt window. If you simple double click the exe file .. it just runs the program and shuts out in an instant. You won't have any time to see it.
Run it through a cmd window by navigating to the directory and doing ./yourexefile
Or a terrible way to do this with double click is to do this :
#include <stdio.h>

int main( int argc, char ** argv ) {
   int n;
   printf("Hello, World!\n");
   scanf("%d",&n); // this will force the execution window to stay open until you put in some input
   return 0;
}

You could also do:
#include <stdio.h>
#include <stdlib.h>

int main( int argc, char ** argv ) {
   printf("Hello, World!\n");
   system("pause");
   return 0;
}

Another way ( more aesthetic ):
#include <stdio.h>

int main( int argc, char ** argv ) {
   printf("Hello, World!\n");
   printf(" Press enter to exit\n");
   getchar();
   return 0;
}

redpajama_set_name: RedPajamaStackExchange


ArCADia PLUS 10 EN Reviews Recently Reviewed!
Pros: The ability to generate 3D from our 2D practice of doing our architecture drawings. Hence we were able adopt BIM quickly. Meanwhile from start practice of 2D, we are able to get more intelligence from the software. We can dimension very quickly, use of items properties, create BOM etc etc. All these are available free without need for changing the way we work.
Cons: We had some problems with speed when we will moving items. We found out later because of the number of views we had, we have to be careful to de-activate some views, otherwise it is slow in updating. We also wish that the lights that we insert can contain properties that also make it useful for rendering instead of inserting a seperate light source. We wish that we make the software in-built renderer faster with more options. Lastly, the IFC exports needs to work better with Revit and Archicad. This will be useful when we are doing software that requires Revit.
Pros: Interface similar to AutoCAD, this makes ArCADia immediately productive in your projects. Tools for projects that have a great level of detail.
Cons: Not works with DWG2019.
Overall: ArCADia PLUS 10 EN is the evolution of AutoCAD! With it the projects are done quickly, with the highest level of detailing and reliable materials list.
Pros: User friendliness and road map to BIM. Basic knowledge of drafting is more than enough to get started.
Cons: Need support for all standards and improvements required for performance issues.
Overall: Arcadia Plus 10 en is intutive and innovative software technolgy to meet customer needs with value for money. Any Enterprise who want to switch from their Existing CAD to Arcadia will be the right choice.
Pros: No learning curve. Easy to use. User friendly interface. High on Performance.
Cons: Nothing is their to dislike. It is a perfect solution.
Pros: If you ever worked in an AutoCAD environment, you should feel at home using the ArCADia PLUS 10. All the functions and shortcuts are logically positioned and if you have any CAD experience, you can start working right away. The price is a complete steal compared to other similar CAD software. A collection of different modules means you can use it in any industry.
Cons: I gave this software 5 stars, as I really can't come up with any cons.
Pros: Comprehensive suite of modules for the Architecting and Engineering Industry.
Cons: Big Download, but that is normal for this level of Desktop Software for Engineering.
Overall: Out of the Box Configuration without any support calls/emails to Help Desk.
Enabling additional modules simply with the activation of a key.
Pros: It is truly very similar to Autocad at a fraction of the cost. It is a great alternative to Autodesk Autocad for people and companies that don't have the budget to buy expensive Autodesk licenses or subscriptions.
The learning curve is very short and it can seamlessly import and export DWG and other popular files formats. It covers most of the industry-specific needs in the construction business including architectural, electrical, water and gas supply design. It's very user friendly, nice surprise!
Cons: So far I did not find anything negative.
Cons: I liked everything, I did not find any features that I would not like.
Pros: That it is still developed and new functions are added on regular basis.
Pros: Software is complete and flexible, you only purchase the module you need.
Cons: Graphics User Interface is not good enough, compare with mainstream software in the market.


A mini reader is a smaller reader that supports cards of the size of a SIM card.
It is a portable mini-reader equipped with a USB port and a SIM slot for a processor card. Thanks to the small size and compact design, the device is widely used on the constantly growing market of electronic cards. It works with units equipped with a USB 2.0 interface. CCID and EMV certified. It meets the following standards: ISO 7816, EMV 2000, Microsoft® WHQL, USB CCID, PC/SC, HBCI (Home Banking Computer Interface). It uses the PC/SC, OCF or CT-API interfaces. CCID support facilitates trouble-free installation of the device in the system.
Windows CE, 98, Me, 2000, XP, 2003, Vista, 7, Linux, MacOS, .


text:
Tagged as: AETV
New Balance Launch RunIQ
Early this morning New Balance launched their first ever wearable device, the RunIQ Smartwatch. The device was made by New Balance in collaboration with leading digital, hardwar...
Lachlan Rayner gowatch January 6, 2017 January 6, 2017 https://athleticsexclusive.com/wp-content/uploads/2017/01/maxresdefault-3-1024x576.jpg 960 540
Alana Boyd Jumps an Australian Record
Alana Boyd has shown why she is the best in the World. At a Queensland Australia Pole Vault permit meet, she cleared 4.81m, adding 4cm to her Australian Record. To top of the...
Lachlan Rayner gowatch July 3, 2016 July 3, 2016 https://athleticsexclusive.com/wp-content/uploads/2016/07/maxresdefault-1-1024x576.jpg 960 540
Unboxing the Suunto Ambit3 Vertical
The Suunto Ambit3 Vertical is the newest watch to come from Suunto. In regards to specs, the Vertical sits under the Ambit3 Peak and above the Ambit3 Sport. Though, it also comes w...
Lachlan Rayner gowatch June 23, 2016 June 23, 2016 https://athleticsexclusive.com/wp-content/uploads/2016/06/maxresdefault-26-1024x576.jpg 960 540
Jared Tallent's Medal Ceremony in Melbourne
Watch as Jared Tallent receives his 2012 London Olympics Gold Medal for the 50km Walk. Tallent was denied first position by drug cheat Sergey Kirdyapkin, who was banned last year f...
Lachlan Rayner gowatch June 17, 2016 June 23, 2016 https://athleticsexclusive.com/wp-content/uploads/2016/06/jared-tallent-olympic-gold-medal-1024x529.jpg 960 496
WATCH: Mathews takes out 1500 Win at Bislett Games
Luke Mathews has stamped his mark on the international circuit after he won his race at the Bislett Games is Oslo (NOR) this morning. The 20-year-old clocked another strong perform...
aeTVLive
Journey to Poland with Darcy Roper and Shemaiah James
Join us on the Journey to Poland with Darcy Roper and Shemaiah James. This is our first episode in the Journey to Poland series and our third ever livestream. Watch as we chat to t...
Lachlan Rayner gowatch May 31, 2016 May 31, 2016 https://athleticsexclusive.com/wp-content/uploads/2016/05/maxresdefault-1-1024x576.jpg 960 540
2016 Victorian Men's Mile Championship
Held at Melbourne University on Tuesday 23 February 2016. The 100th edition of the Victorian Men's Mile Championship. Features Luke Mathews, Sam McEntee and Brenton Rowe.
Lachlan Rayner gowatch February 26, 2016 February 26, 2016 https://athleticsexclusive.com/wp-content/uploads/2016/02/maxresdefault-18-1024x576.jpg 960 540
2016 Hunter Track Classic – Women's 400m
The Women's 400m at the 2016 Hunter Track Classic. EVENT – https://athleticsexclusive.com/event/2016-hunter-track-classic/ Follow us on our Social Networks to stay up to date...
Lachlan Rayner gowatch February 1, 2016 February 1, 2016 https://athleticsexclusive.com/wp-content/uploads/2016/02/maxresdefault-3-1024x576.jpg 960 540
2016 Hunter Track Classic – Men's A 3000m
The Men's A 3000m at the 2016 Hunter Track Classic. EVENT - https://athleticsexclusive.com/event/2016-hunter-track-classic/ Follow us on our Social Networks to stay up to dat...
Lachlan Rayner gowatch January 31, 2016 January 31, 2016 https://athleticsexclusive.com/wp-content/uploads/2016/01/maxresdefault-3-1024x576.jpg 960 540
2016 Hunter Track Classic – Men's 100m Final
The Men's 100m Final at the 2016 Hunter Track Classic. EVENT - https://athleticsexclusive.com/event/2016-hunter-track-classic/ Follow us on our Social Networks to stay up to ...


For a multidimensional approach to healing your body, there are few treatments as flexible as acupuncture. Used to treat chronic pain, inflammation, nerve pain, internal systems, and even some illnesses, acupuncture is a gentle approach to helping you live your life pain free. We promise, the needles aren't scary.
From April 1st to August 1st 2016, our Milton clinic will offer Introductory 1 hour Acupuncture Therapy appointments priced at $55 for 1st time clients. Call us at 289 878 8881 to book today!
* Promotional initial acupuncture appointments must be paid up front if not claimed under extended health benefits and/or if the patient will not be continuing treatment at this facility.
Can Cupping and Acupuncture Help Fibromyalgia?


text:
#include "asylo/identity/provisioning/sgx/internal/fake_sgx_pcs_client.h"

#include <endian.h>

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "google/protobuf/struct.pb.h"
#include "google/protobuf/timestamp.pb.h"
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/message_differencer.h>
#include "absl/base/attributes.h"
#include "absl/base/macros.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/random/distributions.h"
#include "absl/random/random.h"
#include "absl/status/status.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "absl/types/optional.h"
#include "absl/types/span.h"
#include "asylo/crypto/asn1.h"
#include "asylo/crypto/bignum_util.h"
#include "asylo/crypto/certificate.pb.h"
#include "asylo/crypto/certificate_interface.h"
#include "asylo/crypto/ecdsa_p256_sha256_signing_key.h"
#include "asylo/crypto/signing_key.h"
#include "asylo/crypto/util/bytes.h"
#include "asylo/crypto/util/trivial_object_util.h"
#include "asylo/crypto/x509_certificate.h"
#include "asylo/util/logging.h"
#include "asylo/identity/platform/sgx/internal/identity_key_management_structs.h"
#include "asylo/identity/platform/sgx/machine_configuration.pb.h"
#include "asylo/identity/provisioning/sgx/internal/fake_sgx_pki.h"
#include "asylo/identity/provisioning/sgx/internal/pck_certificate_util.h"
#include "asylo/identity/provisioning/sgx/internal/pck_certificates.pb.h"
#include "asylo/identity/provisioning/sgx/internal/platform_provisioning.h"
#include "asylo/identity/provisioning/sgx/internal/platform_provisioning.pb.h"
#include "asylo/identity/provisioning/sgx/internal/sgx_pcs_client.h"
#include "asylo/identity/provisioning/sgx/internal/sgx_pcs_client.pb.h"
#include "asylo/identity/provisioning/sgx/internal/tcb.h"
#include "asylo/identity/provisioning/sgx/internal/tcb.pb.h"
#include "asylo/util/cleansing_types.h"
#include "asylo/util/proto_enum_util.h"
#include "asylo/util/status.h"
#include "asylo/util/status_helpers.h"
#include "asylo/util/status_macros.h"
#include "asylo/util/time_conversions.h"

namespace asylo {
namespace sgx {
namespace {

// The FMSPC layout used by FakeSgxPcsClient. Used to determine the SGX CA
// corresponding to a given FMSPC.
struct FakeFmspcLayout {
  static constexpr int kCompressedSgxCaTypeBits = 2;

  // The SgxCaType that issues PCK certificates for platform instances with this
  // FMSPC.
  uint8_t ca : kCompressedSgxCaTypeBits;

  // Reserved for future use.
  uint16_t reserved : 8 * sizeof(uint16_t) - kCompressedSgxCaTypeBits;

  // The PCE ID corresponding to this FMSPC.
  uint16_t pce_id;

  // Unique identifier, allowing us to create up to 2^16 unique FMSPC values
  // for a given ca and pce_id.
  uint16_t unique_id;
} ABSL_ATTRIBUTE_PACKED;

static_assert(sizeof(FakeFmspcLayout) == kFmspcSize,
              "Invalid size for FakeFmspcLayout");
static_assert(1 << FakeFmspcLayout::kCompressedSgxCaTypeBits > SgxCaType_MAX,
              "FakeFmspcLayout::ca is too small to hold all SgxCaType values");

// The PPID layout used by FakeSgxPcsClient. Used to determine the FMSPC
// corresponding to a given PPID.
struct FakePpidLayout {
  // The FMSPC of this PPID's platform.
  FakeFmspcLayout fmspc;

  // Reserved for future use.
  UnsafeBytes<2> reserved;

  // Random bytes.
  //
  UnsafeBytes<8> random_id;
} ABSL_ATTRIBUTE_PACKED;

static_assert(sizeof(FakePpidLayout) == kPpidSize,
              "Invalid size for FakePpidLayout");

// Returns an error if |fmspc| is not valid according to ValidateFmspc() or does
// not match FakeFmspcLayout.
Status FmspcIsValidAndMatchesLayout(const Fmspc &fmspc) {
  ASYLO_RETURN_IF_ERROR(ValidateFmspc(fmspc));
  const FakeFmspcLayout *layout =
      reinterpret_cast<const FakeFmspcLayout *>(fmspc.value().data());
  if (!SgxCaType_IsValid(layout->ca) ||
      layout->ca == SgxCaType::SGX_CA_TYPE_UNKNOWN) {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid FMSPC: bad SgxCaType: ",
                     ProtoEnumValueName(static_cast<SgxCaType>(layout->ca))));
  }
  return absl::OkStatus();
}

// Returns an error if |ppid| is not valid according to ValidatePpid() or does
// not match FakePpidLayout.
Status PpidIsValidAndMatchesLayout(const Ppid &ppid) {
  ASYLO_RETURN_IF_ERROR(ValidatePpid(ppid));
  const FakePpidLayout *layout =
      reinterpret_cast<const FakePpidLayout *>(ppid.value().data());
  Fmspc fmspc;
  fmspc.set_value(ConvertTrivialObjectToBinaryString(layout->fmspc));
  return FmspcIsValidAndMatchesLayout(fmspc);
}

// Returns a non-OK status if:
//
//   * |fmspc| is not valid.
//   * |fmspc| does not match FakeFmspcLayout.
//   * |tcb_info| is not valid.
//   * |tcb_info| has a |version| other than 2.
//   * The FMSPC and PCE ID in |tcb_info| do not match |fmspc|.
Status IsValidFmspcTcbInfoPair(const Fmspc &fmspc, const TcbInfo &tcb_info) {
  ASYLO_RETURN_IF_ERROR(FmspcIsValidAndMatchesLayout(fmspc));
  ASYLO_RETURN_IF_ERROR(ValidateTcbInfo(tcb_info));
  if (!google::protobuf::util::MessageDifferencer::Equals(tcb_info.impl().fmspc(),
                                                fmspc)) {
    return absl::InvalidArgumentError(absl::StrFormat(
        "TCB info is for wrong FMSPC: expected 0x%s, found 0x%s",
        absl::BytesToHexString(fmspc.value()),
        absl::BytesToHexString(tcb_info.impl().fmspc().value())));
  }
  const FakeFmspcLayout *layout =
      reinterpret_cast<const FakeFmspcLayout *>(fmspc.value().data());
  if (tcb_info.impl().pce_id().value() != layout->pce_id) {
    return absl::InvalidArgumentError(
        absl::StrFormat("TCB info is for wrong PCE ID: expected %d, found %d",
                        layout->pce_id, tcb_info.impl().pce_id().value()));
  }
  return absl::OkStatus();
}

// Fills |buffer| with random bytes.
void Randomize(absl::Span<uint8_t> buffer) {
  for (auto &byte : buffer) {
    byte = absl::Uniform(absl::BitGen(), 0, 256);
  }
}

// Creates a PEM-encoded X.509 certificate chain from |pem_certs|.
CertificateChain CreateCertificateChainFromPemCerts(
    absl::Span<const absl::string_view> pem_certs) {
  CertificateChain chain;
  for (absl::string_view pem : pem_certs) {
    Certificate *cert = chain.add_certificates();
    cert->set_format(Certificate::X509_PEM);
    cert->set_data(pem.data(), pem.size());
  }
  return chain;
}

// Creates a CPU SVN representing the same information as |tcb| using an
// internal fake conversion. The |tcb| must be a valid Tcb message.
CpuSvn CpuSvnFromTcb(const Tcb &tcb) {
  CpuSvn cpu_svn;
  cpu_svn.set_value(tcb.components());
  return cpu_svn;
}

// Converts a google::protobuf::Timestamp to an ISO 8601 timestamp string.
//
// This is used instead of google::protobuf::util::TimeUtil::ToString() because that
// function always adds a '.' after the seconds field, even if the nanoseconds
// field is zero. This reflects a difference betwen RFC 3339 and ISO 8601.
std::string GoogleTimestampToIso8601String(
    const google::protobuf::Timestamp &timestamp) {
  return absl::FormatTime("%Y-%m-%dT%H:%M:%SZ",
                          ConvertTime<absl::Time>(timestamp).value(),
                          absl::UTCTimeZone());
}

// Converts |tcb_info| to an Intel TCB info JSON structure with no whitespace.
// The |tcb_info| must be valid according to ValidateTcbInfo() and must have a
// |version| of 2.
StatusOr<std::string> TcbInfoToJson(const TcbInfo &tcb_info) {
  google::protobuf::Value tcb_info_json;
  auto *tcb_info_fields =
      tcb_info_json.mutable_struct_value()->mutable_fields();
  const TcbInfoImpl &impl = tcb_info.impl();
  google::protobuf::Value tcb_info_element;

  tcb_info_element.set_number_value(impl.version());
  tcb_info_fields->insert({"version", tcb_info_element});
  tcb_info_element.set_string_value(
      GoogleTimestampToIso8601String(impl.issue_date()));
  tcb_info_fields->insert({"issueDate", tcb_info_element});
  tcb_info_element.set_string_value(
      GoogleTimestampToIso8601String(impl.next_update()));
  tcb_info_fields->insert({"nextUpdate", tcb_info_element});
  tcb_info_element.set_string_value(
      absl::BytesToHexString(impl.fmspc().value()));
  tcb_info_fields->insert({"fmspc", tcb_info_element});
  uint16_t pce_id_little_endian = htole16(impl.pce_id().value());
  tcb_info_element.set_string_value(
      ConvertTrivialObjectToHexString(pce_id_little_endian));
  tcb_info_fields->insert({"pceId", tcb_info_element});
  if (impl.version() == 2) {
    switch (impl.tcb_type()) {
      case TcbType::TCB_TYPE_0:
        tcb_info_element.set_number_value(0);
        break;
      default:
        return Status(absl::StatusCode::kInvalidArgument,
                      absl::StrCat("Unknown TCB type: ",
                                   ProtoEnumValueName(impl.tcb_type())));
    }
    tcb_info_fields->insert({"tcbType", tcb_info_element});
    tcb_info_element.set_number_value(impl.tcb_evaluation_data_number());
    tcb_info_fields->insert({"tcbEvaluationDataNumber", tcb_info_element});
  }
  for (const TcbLevel &tcb_level : impl.tcb_levels()) {
    auto *tcb_level_fields = tcb_info_element.mutable_list_value()
                                 ->add_values()
                                 ->mutable_struct_value()
                                 ->mutable_fields();
    google::protobuf::Value tcb_level_element;

    auto *tcb_fields =
        tcb_level_element.mutable_struct_value()->mutable_fields();
    google::protobuf::Value tcb_element;
    for (int i = 0; i < kTcbComponentsSize; ++i) {
      tcb_element.set_number_value(tcb_level.tcb().components()[i]);
      tcb_fields->insert(
          {absl::StrFormat("sgxtcbcomp%02dsvn", i + 1), tcb_element});
    }
    tcb_element.set_number_value(tcb_level.tcb().pce_svn().value());
    tcb_fields->insert({"pcesvn", tcb_element});
    tcb_level_fields->insert({"tcb", tcb_level_element});

    std::string status_string;
    ASYLO_ASSIGN_OR_RETURN(status_string,
                           TcbStatusToString(tcb_level.status()));
    tcb_level_element.set_string_value(status_string);
    tcb_level_fields->insert(
        {impl.version() == 2 ? "tcbStatus" : "status", tcb_level_element});

    if (impl.version() == 2) {
      tcb_level_element.set_string_value(
          GoogleTimestampToIso8601String(tcb_level.tcb_date()));
      tcb_level_fields->insert({"tcbDate", tcb_level_element});

      if (!tcb_level.advisory_ids().empty()) {
        for (const std::string &advisory_id : tcb_level.advisory_ids()) {
          tcb_level_element.mutable_list_value()
              ->add_values()
              ->set_string_value(advisory_id);
        }
        tcb_level_fields->insert({"advisoryIDs", tcb_level_element});
      }
    }
  }
  tcb_info_fields->insert({"tcbLevels", tcb_info_element});

  std::string json;
  ASYLO_RETURN_IF_ERROR(
      Status(google::protobuf::util::MessageToJsonString(tcb_info_json, &json)));
  return json;
}

}  // namespace

FakeSgxPcsClient::FakeSgxPcsClient()
    : FakeSgxPcsClient(
          std::move(std::move(EcdsaP256Sha256VerifyingKey::CreateFromPem(
                                  kFakePckPublicPem))
                        .value()
                        ->SerializeToDer())
              .value()) {}

FakeSgxPcsClient::FakeSgxPcsClient(absl::string_view pck_der)
    : tcb_info_issuer_chain_(CreateCertificateChainFromPemCerts(
          {kFakeSgxTcbSigner.certificate_pem, kFakeSgxRootCa.certificate_pem})),
      tcb_info_signing_key_(std::move(EcdsaP256Sha256SigningKey::CreateFromPem(
                                          kFakeSgxTcbSigner.signing_key_pem))
                                .value()),
      pck_public_key_der_(reinterpret_cast<const char *>(pck_der.data()),
                          pck_der.size()),
      tcb_infos_(FmspcToTcbInfoMap()),
      fmspc_id_counter_(
          absl::Uniform<decltype(FakeFmspcLayout::unique_id)>(absl::BitGen())) {
}

StatusOr<bool> FakeSgxPcsClient::AddFmspc(Fmspc fmspc, TcbInfo tcb_info) {
  ASYLO_RETURN_IF_ERROR(IsValidFmspcTcbInfoPair(fmspc, tcb_info));
  return tcb_infos_.Lock()
      ->insert({std::move(fmspc), std::move(tcb_info)})
      .second;
}

Status FakeSgxPcsClient::UpdateFmspc(const Fmspc &fmspc, TcbInfo tcb_info) {
  ASYLO_RETURN_IF_ERROR(IsValidFmspcTcbInfoPair(fmspc, tcb_info));

  auto tcb_infos_view = tcb_infos_.Lock();
  auto it = tcb_infos_view->find(fmspc);
  if (it == tcb_infos_view->end()) {
    return absl::InvalidArgumentError(absl::StrCat(
        "Unknown FMSPC: 0x", absl::BytesToHexString(fmspc.value())));
  }
  it->second = std::move(tcb_info);
  return absl::OkStatus();
}

StatusOr<GetPckCertificateResult> FakeSgxPcsClient::GetPckCertificate(
    const Ppid &ppid, const CpuSvn &cpu_svn, const PceSvn &pce_svn,
    const PceId &pce_id) {
  return Status(absl::StatusCode::kUnimplemented,
                "FakeSgxPcsClient::GetPckCertificate() is not implemented");
}

StatusOr<GetPckCertificatesResult> FakeSgxPcsClient::GetPckCertificates(
    const Ppid &ppid, const PceId &pce_id) {
  ASYLO_RETURN_IF_ERROR(PpidIsValidAndMatchesLayout(ppid));
  ASYLO_RETURN_IF_ERROR(ValidatePceId(pce_id));

  const FakePpidLayout *ppid_layout =
      reinterpret_cast<const FakePpidLayout *>(ppid.value().data());
  const CaInfo *ca_info;
  ASYLO_ASSIGN_OR_RETURN(
      ca_info, GetCaInfo(static_cast<SgxCaType>(ppid_layout->fmspc.ca)));

  Fmspc fmspc;
  fmspc.set_value(&ppid_layout->fmspc, kFmspcSize);
  auto readable_view = tcb_infos_.ReaderLock();
  auto tcb_info_it = readable_view->find(fmspc);
  if (tcb_info_it == readable_view->end()) {
    return Status(
        absl::StatusCode::kNotFound,
        absl::StrFormat(
            "Failed to create PCK certificates for platform with PPID 0x%s: "
            "unknown FMSPC 0x%s",
            absl::BytesToHexString(ppid.value()),
            absl::BytesToHexString(fmspc.value())));
  }

  GetPckCertificatesResult result;
  SgxExtensions extension_data;
  extension_data.ppid = ppid;
  extension_data.fmspc = fmspc;
  extension_data.pce_id = pce_id;
  extension_data.sgx_type = SgxType::STANDARD;

  for (const auto &tcb_level : tcb_info_it->second.impl().tcb_levels()) {
    extension_data.tcb = tcb_level.tcb();
    extension_data.cpu_svn = CpuSvnFromTcb(tcb_level.tcb());
    ASYLO_ASSIGN_OR_RETURN(
        *result.pck_certs.add_certs(),
        CreateFakePckCertificateInfo(*ca_info, extension_data));
  }

  result.issuer_cert_chain = ca_info->issuer_chain;
  return result;
}

StatusOr<GetCrlResult> FakeSgxPcsClient::GetCrl(SgxCaType sgx_ca_type) {
  return Status(absl::StatusCode::kUnimplemented,
                "FakeSgxPcsClient::GetCrl() is not implemented");
}

StatusOr<GetTcbInfoResult> FakeSgxPcsClient::GetTcbInfo(const Fmspc &fmspc) {
  ASYLO_RETURN_IF_ERROR(FmspcIsValidAndMatchesLayout(fmspc));

  GetTcbInfoResult result;
  result.issuer_cert_chain = tcb_info_issuer_chain_;

  TcbInfo tcb_info;
  {
    auto tcb_infos_readable_view = tcb_infos_.ReaderLock();
    auto it = tcb_infos_readable_view->find(fmspc);
    if (it == tcb_infos_readable_view->end()) {
      return Status(absl::StatusCode::kNotFound,
                    "No TCB info associated with given FMSPC");
    }

    tcb_info = it->second;
  }

  auto *impl = tcb_info.mutable_impl();
  absl::Time issue_date = absl::Now();
  *impl->mutable_issue_date() =
      ConvertTime<google::protobuf::Timestamp>(issue_date).value();
  absl::Time next_update = issue_date + absl::Hours(24 * 30);
  *impl->mutable_next_update() =
      ConvertTime<google::protobuf::Timestamp>(next_update).value();

  std::string tcb_info_json;
  ASYLO_ASSIGN_OR_RETURN(tcb_info_json, TcbInfoToJson(tcb_info));
  result.tcb_info.set_tcb_info_json(tcb_info_json);

  std::vector<uint8_t> signature;
  ASYLO_CHECK_OK(tcb_info_signing_key_->Sign(tcb_info_json, &signature));
  result.tcb_info.set_signature(signature.data(), signature.size());

  return result;
}

StatusOr<Fmspc> FakeSgxPcsClient::CreateFmspcWithProperties(
    const FakeSgxPcsClient::PlatformProperties &properties) {
  if (!SgxCaType_IsValid(properties.ca) ||
      properties.ca == SGX_CA_TYPE_UNKNOWN) {
    return Status(absl::StatusCode::kInvalidArgument, "Invalid SgxCaType");
  }
  ASYLO_RETURN_IF_ERROR(ValidatePceId(properties.pce_id));

  FakeFmspcLayout layout = {};
  layout.ca = properties.ca;
  layout.pce_id = properties.pce_id.value();

  layout.unique_id = fmspc_id_counter_++;

  Fmspc fmspc;
  fmspc.set_value(ConvertTrivialObjectToBinaryString(layout));
  return fmspc;
}

StatusOr<Ppid> FakeSgxPcsClient::CreatePpidForFmspc(const Fmspc &fmspc) {
  ASYLO_RETURN_IF_ERROR(FmspcIsValidAndMatchesLayout(fmspc));

  FakePpidLayout layout = {};
  memcpy(&layout.fmspc, fmspc.value().data(), kFmspcSize);

  Randomize(absl::MakeSpan(layout.random_id));

  Ppid ppid;
  ppid.set_value(ConvertTrivialObjectToBinaryString(layout));
  return ppid;
}

StatusOr<const FakeSgxPcsClient::CaInfo *> FakeSgxPcsClient::GetCaInfo(
    SgxCaType ca_type) {
  static const CaInfo *kPlatformCaInfo = new CaInfo(
      {kFakeSgxPlatformCa.certificate_pem, kFakeSgxRootCa.certificate_pem},
      kFakeSgxPlatformCa.signing_key_pem);
  static const CaInfo *kProcessorCaInfo = new CaInfo(
      {kFakeSgxProcessorCa.certificate_pem, kFakeSgxRootCa.certificate_pem},
      kFakeSgxProcessorCa.signing_key_pem);

  switch (ca_type) {
    case SgxCaType::PLATFORM:
      return kPlatformCaInfo;
    case SgxCaType::PROCESSOR:
      return kProcessorCaInfo;
    default:
      return Status(absl::StatusCode::kInvalidArgument,
                    absl::StrCat("Unsupported SGX CA type: ",
                                 ProtoEnumValueName(ca_type)));
  }
}

StatusOr<PckCertificates::PckCertificateInfo>
FakeSgxPcsClient::CreateFakePckCertificateInfo(
    const CaInfo &ca_info, const SgxExtensions &extension_data) const {
  PckCertificates::PckCertificateInfo cert_info;
  *cert_info.mutable_tcb_level() = extension_data.tcb;
  *cert_info.mutable_tcbm()->mutable_cpu_svn() = extension_data.cpu_svn;
  *cert_info.mutable_tcbm()->mutable_pce_svn() = extension_data.tcb.pce_svn();
  ASYLO_ASSIGN_OR_RETURN(*cert_info.mutable_cert(),
                         CreateFakePckCertificate(ca_info, extension_data));
  return cert_info;
}

StatusOr<Certificate> FakeSgxPcsClient::CreateFakePckCertificate(
    const CaInfo &ca_info, const SgxExtensions &extension_data) const {
  static constexpr int kSerialNumberByteSize = 20;
  static const X509Name *kSubject =
      new X509Name({{ObjectId::CreateFromShortName("CN").value(),
                     "Asylo Fake SGX PCK Certificate For Testing Only"},
                    {ObjectId::CreateFromShortName("O").value(),
                     "Asylo Fake SGX PKI For Testing Only"},
                    {ObjectId::CreateFromShortName("L").value(), "Kirkland"},
                    {ObjectId::CreateFromShortName("ST").value(), "WA"},
                    {ObjectId::CreateFromShortName("C").value(), "US"}});

  X509CertificateBuilder builder;

  // Use a random serial number.
  uint8_t serial_number_bytes[kSerialNumberByteSize];
  Randomize(absl::MakeSpan(serial_number_bytes));
  ASYLO_ASSIGN_OR_RETURN(builder.serial_number,
                         BignumFromBigEndianBytes(serial_number_bytes));

  ASYLO_ASSIGN_OR_RETURN(builder.issuer, ca_info.certificate->GetSubjectName());

  // PCK certificates should be valid for approximately seven years.
  absl::Time now = absl::Now();
  builder.validity = {now, now + absl::Hours(24 * 365 * 7)};
  builder.subject = *kSubject;

  builder.subject_public_key_der = pck_public_key_der_;

  ASYLO_ASSIGN_OR_RETURN(builder.authority_key_identifier,
                         ca_info.certificate->GetSubjectKeyIdentifier());
  builder.subject_key_identifier_method =
      SubjectKeyIdMethod::kSubjectPublicKeySha1;
  builder.key_usage = {/*certificate_signing=*/false,
                       /*crl_signing=*/false,
                       /*digital_signature=*/true};
  builder.basic_constraints = {/*is_ca=*/false, /*pathlen=*/absl::nullopt};

  X509Extension sgx_extensions;
  sgx_extensions.oid = GetSgxExtensionsOid();
  sgx_extensions.is_critical = false;  // SGX extensions are non-critical.
  ASYLO_ASSIGN_OR_RETURN(sgx_extensions.value,
                         WriteSgxExtensions(extension_data));
  builder.other_extensions.push_back(std::move(sgx_extensions));

  std::unique_ptr<X509Certificate> certificate;
  ASYLO_ASSIGN_OR_RETURN(certificate,
                         builder.SignAndBuild(*ca_info.signing_key));
  return certificate->ToCertificateProto(Certificate::X509_PEM);
}

FakeSgxPcsClient::CaInfo::CaInfo(
    absl::Span<const absl::string_view> issuer_chain_pem,
    absl::string_view signing_key_pem)
    : issuer_chain(CreateCertificateChainFromPemCerts(issuer_chain_pem)),
      certificate(
          std::move(X509Certificate::Create(issuer_chain.certificates(0)))
              .value()),
      signing_key(
          std::move(EcdsaP256Sha256SigningKey::CreateFromPem(signing_key_pem))
              .value()) {}

}  // namespace sgx
}  // namespace asylo


text:
The Shift Network is deeply grateful to have like-minded, mission-oriented investors with a commitment to change the world together.
We are committed to enlightened business practices at all levels and modeling what is possible when a company commits to making people, planet, and profits all matter in each business decision.
Please feel free to look at the company's Vision 2020 PowerPoint which highlights the mission and the future of The Shift Network.
If you have any questions, please contact investorrelations@theshiftnetwork.com.
"I decided to invest in The Shift Network for two main reasons. First, I was impressed by the virtually limitless scalability of the business, coming as it does at a time when the mainstream is discovering the tools and concepts TSN offers through their courses. Second, leading a business such as TSN requires a CEO that is not only a heart-centered visionary but also an astute businessperson. I found Stephen to be exemplary in both areas, and it was largely on the basis of his leadership that I ultimately chose to come aboard. I have been very pleased with the maturation of the company to date, and am more than ever convinced of the longterm value of the enterprise."
Gay Hendricks,
New York Times bestselling author


The Boring Word About Redi Killowatt Where Are You?
This column is going to be short. I have to hurry before another power outage closes down my computer and drops the temperature of my house to below freezing. All day long I have been waiting for the other shoe to drop or in this case for the power to go off (or come on) depending on the state of our electricity at the moment.
It was definitely a day for regrets. I knew I should have ironed my blouse last night, my kids had meant to buy batteries for their radio, and my sister tried to remember why she gave my daughter her hand operated can opener to set up housekeeping in her college dorm.
Having lived for years on a road where the power went out if three raindrops fell together, I'm an old hand at how to cope with no power. The first few hours are an adventure. The kids play with all the board games they haven't looked at in months, everyone wraps up in blankets and catches up on some sleep and the phones are kept busy. But eventually the novelty wears off. You begin eating the food that is getting warm in the refrigerator, disregarding the unbalanced meals that are being consumed, the flashlight batteries run down and the candles melt into little puddles.
If you have an electric stove, hot water heater and a well that operates on an electric pump you reach your breaking point very quickly. This is when you start calling your relatives and make plans to move out.
Never fear – as soon as you have put clothes, food, blankets, kids, pets, etc into the car and driven 500 yards down the road the power will come back on.


text:
Home›Articles›Hackers, Trolls, and Drama | The Online Beatbox Community Dillemma
Hackers, Trolls, and Drama | The Online Beatbox Community Dillemma
by Jon Park
Let's talk about the online beatbox community
Beatbox is growing - there's no doubt about that. But there is a detrimental side effect that we're seeing come to fruition: the rise of hateful comments and negative behavior online.
A quick scroll down the comments sections of major battle videos should give you a good glimpse of what we're talking about, but that's only the tip of the iceberg. As more people enter the beatbox community, more controversial opinions follow as our familial values seem to dissipate.
In this article, we're going to explore whether or not we should overlook these "trolls" and how we can go about creating a more positive online environment.
Let's get started, shall we?
As we've tackled in our previous articles, there are beatboxers out there who are unfairly criticized and mocked for their performances. If you aren't familiar with the beatbox community, we're strongly grounded on the values of family and sportsmanship, which these comments seem to ignore.
However, the issue runs deeper. With the rise of online battling platforms borrowed from the gaming community, severe cases of hacking, slander, and even threats have occurred - all issues that we've seen in the gaming community as well.
These occurrences have thus created a severely negative perception of our online communities and many times driving away new and old members of our beatbox family.
Anarchy of the internet
It's apparent that this is the very nature of the internet. When looking at popular gaming communities, forums, or other niche platforms, they all face a similar issue. So the question is: is the anarchy of the internet uncontrollable?
We hope that our community will be different and that it continues to stay as a "beatbox family," but are we being unrealistic due to the sheer scale and size of our community?
Well, it's a tough question to answer. But what we propose is that rather than being reactive, we must be proactive and actively try to improve our situation. We need to come together to at least try to build something new and positive.
The wrong approach
We believe that dismissing these commenters as "not members of the real beatbox community," or turning a blind eye and claiming that these people don't actually exist, is an extremely dangerous approach.
It's a bubble that will continue to grow and one day burst - because there are actual people behind these "trolls" and members in our community unfortunately feel the effects of it. Behind every childish comment or dramatic behavior, there is someone who might be facing different challenges and struggles, but at the end of the day are still involved with the beatbox community.
Whether we like it or not - these people exist and the only way to move forward is to ask the difficult questions about how we can continue to serve everyone in this community.
It's time to address these issues head-on.
Influence of battle culture
The online community is generally comprised of a younger demographic, which at first might seem like the main factor as to why all the ruckus happens. However, it's also integral to note three other factors: battles, ranking systems, and power trips.
The greatest issue we see with the online community is that the foundations are set by a dangerous battling culture. Servers were built for beatboxers to come and compete to see who was a "better beatboxer," instead of focusing on the mastery of a craft.
Credit should be given to the many beatboxers out there who help coach and provide constructive feedback - but as we have seen, it's a difficult thing to keep up when the community wrestles with negative attitudes.
Ranks and power trips
The nature of the online anarchy places greater value on arbitrary points as indicators of power. Whether it be points from battles won or how many subscribers one has, these determinants commission one's influence in the community, instead of positive merit-based factors like leadership ability, compassion, and organization.
We need community leaders, not moderators
Instead of stepping on other community member's heads to gain the most members on your discord channel, we need selfless leaders to take on the challenge of building a more positive community.
The last thing we need are more moderators and arbitrary titles, and especially these really small power trips. We don't need ban-happy moderators. We need leaders.
We're stepping in
And we need your help. With the firm belief that we're going to help shape a positive online beatbox culture, we have created the Human Beatbox Family discord channel with a small set of volunteers, like JWatFx, who are passionate about leading change in our community.
We won't be able to eliminate drama completely, but here's what we want to achieve.
We are creating a platform where beatboxers come not only to battle, but also to appreciate our art form as a whole. We'll be conducting more community-based events, such as workshops, jams, and Q&A sessions with talented beatboxers and ultimately foster the positive vibes we have in our offline community. Let's do this.
Here's a link to our discord channel!
Here's a link to the 2016 Online Beatbox Battle!
2016 Online Beatbox Battle
How to structure a beatbox routine
Jon Park
Fighting for a better beatbox community.
PC Recording (using Audacity)
Articles, Guides and Tips
Reeps One: Why Leaving the Battling Scene Was the Right Decision
Berywam is on Spotify!
Analysis, Articles
Rich 5 December, 2016 at 17:09 Log in to Reply
I love this article but this is only scratching the surface.
Jon Park 6 December, 2016 at 00:19 Log in to Reply
Completely agree – we have to work together on all fronts!


Our team aims at providing a novel approach to model and control soft robots. The methods used to control rigid robots are not directly relevant and new approaches have to be invented or updated to be applied to this kind of robots. We study both kinematics and dynamics control of soft robots.
From the kinematic equations, we deduce the soft-robot Jacobian matrix and discuss the conditions to avoid singular configurations. We also propose a novel observer based control methodology where the observer is built by Finite Element Model. A closed-loop controller for position control of soft robot is designed based on the discrete-time model with feedback signal being extracted by means of visual servoing.
Considering the dynamics of the robots, based on real-time Finite Element Method (FEM), we obtain a model in the workspace of soft robots. We then use Model Order Reduction to get a system of reasonable size to control both velocity and position of the soft robot.
F. Largilliere, V. Verona, E. Coevoet, M. Sanz-Lopez, J. Dequidt and C. Duriez.
Control of Elastic Soft Robots based on Real-Time Finite Element Method.


text:
Robert F. Bukaty/AP
Kate, the Duchess of Cambridge, shown here in July 2011, is suing a French magazine after it published photos of her sunbathing.
Kate Middleton photos: Reminder of long reach of the public eye
Topless Kate Middleton photos in a French gossip magazine – less than a month after Prince Harry's nude Las Vegas photos went viral on the web – rip the relative decorum that had surrounded the royal couple.
September 14, 2012 | Paris
French magazine Closer published a series of photos of Britain's Duchess of Cambridge, Kate Middleton, sunbathing topless on Friday, dealing a fresh blow to the royal family as it tries to move on from a scandal over naked shots of Prince Harry.
Closer, a weekly round-up of celebrity gossip, ran a five-page spread of photos of Middleton relaxing topless with Prince William on a balcony at a 19th century hunting lodge in southern France it said is owned by a son of the late Princess Margaret.
QUIZ: Are you a Helicopter Parent?
Under the headline "Oh my God!," the photos show the Duchess removing her bikini top then relaxing on a sun lounger, apparently oblivious to paparazzi lurking nearby as the pair vacationed at the property in early September.
The publication reopens a debate over the privacy of Britain's royal family and the freedom of the press just weeks after a US website published grainy photos of William's younger brother Harry cavorting naked in a Las Vegas hotel room.
Reading, writing, and paychecks. What's a teacher worth?
"Harry started the fashion: these days the Windsors take their clothes off," the French magazine quipped in the photo spread, which it claimed as a world exclusive.
The royal couple, who are on a tour of southeast Asia, learned of the magazine spread while in Malaysia and were angry and sad their privacy had been breached, a royal source said, adding the pictures were believed to be genuine.
A second source said Buckingham Palace planned to contact French lawyers to see what options were available.
"There is a feeling of anger and disbelief about these photographs," the source said. "We feel there has been a red line crossed with regard to publishing these images."
There was no immediate comment from Closer magazine.
The photos of Harry stained a positive image the Royal family has carefully crafted as it worked to turn the page on Princess Diana's death in 1997 and a raft of scandals at the time including Prince Andrew's ex-wife Sarah Ferguson photographed as she sunbathed topless.
The first royal source said Friday's photos in Closer, taken at a private location and in breach of French privacy laws, had "turned the clock back 15 years."
Willam and Kate were on a short vacation at the Chateau d'Autet near Aix-en-Provence in the Luberon region, whose picture-postcard villages, rolling lavender fields and vineyards have made it a favorite getaway spot for wealthy foreigners.
At one point the Duchess, clearly recognizable in the slightly fuzzy images, stands up and partly peels down her bikini bottoms as William rubs sun lotion on her back.
"The last time we saw Kate and William on a balcony it was for their wedding. But they had more clothes on," reads one photo caption. Another says: "People always say she doesn't need to dress up to look good. Well ... Kate is proving this."
Closer also said Kate was spotted smoking a cigarette as the couple walked out of nearby Marseille airport where they arrived on a commercial flight.
In Pictures Kate Middleton: From girl to duchess
Prince William and Kate Middleton royal wedding: Do monarchies still matter?
In Pictures Prince William and Kate's first royal tour
In Pictures Kate Middleton's dresses
Modern Parenthood Prince Harry nude photos: A reminder we're all in the public eye
https://www.csmonitor.com/The-Culture/2012/0914/Kate-Middleton-photos-Reminder-of-long-reach-of-the-public-eye