text:
"""Tests for tf.batch_sequences_with_states."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os

import numpy as np

from tensorflow.contrib.training.python.training import sequence_queueing_state_saver as sqss
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import errors_impl
from tensorflow.python.framework import ops
from tensorflow.python.framework import sparse_tensor
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import random_ops
from tensorflow.python.ops import string_ops
from tensorflow.python.ops import variables
from tensorflow.python.platform import test
from tensorflow.python.training import coordinator
from tensorflow.python.training import queue_runner_impl
from tensorflow.python.training import saver

class BatchSequencesWithStatesTest(test.TestCase):

  def setUp(self):
    super(BatchSequencesWithStatesTest, self).setUp()
    self.value_length = 4
    ind1 = np.array([
        [0, 0],
        [1, 0], [1, 3], [1, 4],
        [3, 2], [3, 3]])
    val1 = np.array([0, 10, 13, 14, 32, 33])
    shape1 = np.array([self.value_length, 6])
    sp_tensor1 = sparse_tensor.SparseTensor(
        array_ops.constant(ind1, dtypes.int64),
        array_ops.constant(val1, dtypes.int64),
        array_ops.constant(shape1, dtypes.int64))
    ind2 = np.array([
        [0, 0, 1],
        [0, 1, 0],
        [0, 1, 2],
        [1, 0, 3],
        [1, 1, 0],
        [1, 1, 1],
        [1, 1, 2],
        [1, 2, 2]])
    val2 = np.array([1, 10, 12, 103, 150, 149, 150, 122])
    shape2 = np.array([self.value_length, 3, 4])
    sp_tensor2 = sparse_tensor.SparseTensor(
        array_ops.constant(ind2, dtypes.int64),
        array_ops.constant(val2, dtypes.int64),
        array_ops.constant(shape2, dtypes.int64))
    self.batch_size = 2
    self.key = string_ops.string_join([
        "key_", string_ops.as_string(
            math_ops.cast(10000 * random_ops.random_uniform(()), dtypes.int32))
    ])
    self.sequences = {
        "seq1": np.random.rand(self.value_length, 5),
        "seq2": np.random.rand(self.value_length, 4, 2),
        "seq3": sp_tensor1,
        "seq4": sp_tensor2}
    self.context = {"context1": [3, 4]}
    self.initial_states = {
        "state1": np.random.rand(6, 7),
        "state2": np.random.rand(8)
    }

  def _prefix(self, key_value):
    return set(
        [s.decode("ascii").split(":")[0].encode("ascii") for s in key_value])

  def _testBasics(self, num_unroll, length, pad,
                  expected_seq1_batch1, expected_seq2_batch1,
                  expected_seq1_batch2, expected_seq2_batch2,
                  expected_seq3_batch1, expected_seq3_batch2,
                  expected_seq4_batch1, expected_seq4_batch2):

    with self.test_session() as sess:
      next_batch = sqss.batch_sequences_with_states(
          input_key=self.key,
          input_sequences=self.sequences,
          input_context=self.context,
          input_length=length,
          initial_states=self.initial_states,
          num_unroll=num_unroll,
          batch_size=self.batch_size,
          num_threads=3,
          # to enforce that we only move on to the next examples after finishing
          # all segments of the first ones.
          capacity=2,
          pad=pad)

      state1 = next_batch.state("state1")
      state2 = next_batch.state("state2")
      state1_update = next_batch.save_state("state1", state1 + 1)
      state2_update = next_batch.save_state("state2", state2 - 1)

      # Make sure queue runner with SQSS is added properly to meta graph def.
      # Saver requires at least one variable.
      v0 = variables.Variable(10.0, name="v0")
      ops.add_to_collection("variable_collection", v0)
      variables.global_variables_initializer()
      save = saver.Saver([v0])
      test_dir = os.path.join(test.get_temp_dir(), "sqss_test")
      filename = os.path.join(test_dir, "metafile")
      meta_graph_def = save.export_meta_graph(filename)
      qr_saved = meta_graph_def.collection_def[ops.GraphKeys.QUEUE_RUNNERS]
      self.assertTrue(qr_saved.bytes_list.value is not None)

      coord = coordinator.Coordinator()
      threads = queue_runner_impl.start_queue_runners(coord=coord)

      # Step 1
      (key_value, next_key_value, seq1_value, seq2_value, seq3_value,
       seq4_value, context1_value, state1_value, state2_value, length_value,
       _, _) = sess.run(
           (next_batch.key, next_batch.next_key, next_batch.sequences["seq1"],
            next_batch.sequences["seq2"], next_batch.sequences["seq3"],
            next_batch.sequences["seq4"], next_batch.context["context1"],
            state1, state2, next_batch.length, state1_update, state2_update))
      expected_first_keys = set([b"00000_of_00002"])
      expected_second_keys = set([b"00001_of_00002"])
      expected_final_keys = set([b"STOP"])

      self.assertEqual(expected_first_keys, self._prefix(key_value))
      self.assertEqual(expected_second_keys, self._prefix(next_key_value))
      self.assertAllEqual(
          np.tile(self.context["context1"], (self.batch_size, 1)),
          context1_value)
      self.assertAllEqual(expected_seq1_batch1, seq1_value)
      self.assertAllEqual(expected_seq2_batch1, seq2_value)
      self.assertAllEqual(expected_seq3_batch1.indices, seq3_value.indices)
      self.assertAllEqual(expected_seq3_batch1.values, seq3_value.values)
      self.assertAllEqual(expected_seq3_batch1.dense_shape,
                          seq3_value.dense_shape)
      self.assertAllEqual(expected_seq4_batch1.indices, seq4_value.indices)
      self.assertAllEqual(expected_seq4_batch1.values, seq4_value.values)
      self.assertAllEqual(expected_seq4_batch1.dense_shape,
                          seq4_value.dense_shape)
      self.assertAllEqual(
          np.tile(self.initial_states["state1"], (self.batch_size, 1, 1)),
          state1_value)
      self.assertAllEqual(
          np.tile(self.initial_states["state2"], (self.batch_size, 1)),
          state2_value)
      self.assertAllEqual(length_value, [num_unroll, num_unroll])

      # Step 2
      (key_value, next_key_value, seq1_value, seq2_value, seq3_value,
       seq4_value, context1_value, state1_value, state2_value, length_value,
       _, _) = sess.run(
           (next_batch.key, next_batch.next_key, next_batch.sequences["seq1"],
            next_batch.sequences["seq2"], next_batch.sequences["seq3"],
            next_batch.sequences["seq4"], next_batch.context["context1"],
            state1, state2, next_batch.length, state1_update, state2_update))

      self.assertEqual(expected_second_keys, self._prefix(key_value))
      self.assertEqual(expected_final_keys, self._prefix(next_key_value))
      self.assertAllEqual(
          np.tile(self.context["context1"], (self.batch_size, 1)),
          context1_value)
      self.assertAllEqual(expected_seq1_batch2, seq1_value)
      self.assertAllEqual(expected_seq2_batch2, seq2_value)
      self.assertAllEqual(expected_seq3_batch2.indices, seq3_value.indices)
      self.assertAllEqual(expected_seq3_batch2.values, seq3_value.values)
      self.assertAllEqual(expected_seq3_batch2.dense_shape,
                          seq3_value.dense_shape)
      self.assertAllEqual(expected_seq4_batch2.indices, seq4_value.indices)
      self.assertAllEqual(expected_seq4_batch2.values, seq4_value.values)
      self.assertAllEqual(expected_seq4_batch2.dense_shape,
                          seq4_value.dense_shape)
      self.assertAllEqual(1 + np.tile(self.initial_states["state1"],
                                      (self.batch_size, 1, 1)), state1_value)
      self.assertAllEqual(-1 + np.tile(self.initial_states["state2"],
                                       (self.batch_size, 1)), state2_value)
      self.assertAllEqual([1, 1], length_value)

      coord.request_stop()
      coord.join(threads, stop_grace_period_secs=2)

  def _testBasicPadding(self, pad):
    num_unroll = 2  # Divisor of value_length - so no padding necessary.
    expected_seq1_batch1 = np.tile(
        self.sequences["seq1"][np.newaxis, 0:num_unroll, :],
        (self.batch_size, 1, 1))
    expected_seq2_batch1 = np.tile(
        self.sequences["seq2"][np.newaxis, 0:num_unroll, :, :],
        (self.batch_size, 1, 1, 1))
    expected_seq1_batch2 = np.tile(
        self.sequences["seq1"][np.newaxis, num_unroll:self.value_length, :],
        (self.batch_size, 1, 1))
    expected_seq2_batch2 = np.tile(
        self.sequences["seq2"][np.newaxis, num_unroll:self.value_length, :, :],
        (self.batch_size, 1, 1, 1))
    ind1_1 = np.array([
        # batch entry 1
        [0, 0, 0],
        [0, 1, 0], [0, 1, 3], [0, 1, 4],
        # batch entry 2
        [1, 0, 0],
        [1, 1, 0], [1, 1, 3], [1, 1, 4]])
    ind1_2 = np.array([
        # batch entry 1
        [0, 1, 2], [0, 1, 3],
        # batch entry 2
        [1, 1, 2], [1, 1, 3]])
    val1_1 = np.array([0, 10, 13, 14,
                       0, 10, 13, 14])
    val1_2 = np.array([32, 33,
                       32, 33])
    shape1 = np.array([self.batch_size, num_unroll, 6])

    # For sp_tensor2 all values fall into the first segment.
    ind2_1 = np.array([
        # batch entry 1
        [0, 0, 0, 1],
        [0, 0, 1, 0],
        [0, 0, 1, 2],
        [0, 1, 0, 3],
        [0, 1, 1, 0],
        [0, 1, 1, 1],
        [0, 1, 1, 2],
        [0, 1, 2, 2],
        # batch entry 2
        [1, 0, 0, 1],
        [1, 0, 1, 0],
        [1, 0, 1, 2],
        [1, 1, 0, 3],
        [1, 1, 1, 0],
        [1, 1, 1, 1],
        [1, 1, 1, 2],
        [1, 1, 2, 2],
    ])
    val2_1 = np.array([1, 10, 12, 103, 150, 149, 150, 122,
                       1, 10, 12, 103, 150, 149, 150, 122])
    shape2 = np.array([self.batch_size, num_unroll, 3, 4])
    expected_seq3_batch1 = sparse_tensor.SparseTensorValue(
        ind1_1, val1_1, shape1)
    expected_seq3_batch2 = sparse_tensor.SparseTensorValue(
        ind1_2, val1_2, shape1)
    expected_seq4_batch1 = sparse_tensor.SparseTensorValue(
        ind2_1, val2_1, shape2)
    expected_seq4_batch2 = sparse_tensor.SparseTensorValue(
        np.empty(shape=[0, 4], dtype=np.int64), np.array([]), shape2)
    self._testBasics(
        num_unroll=num_unroll,
        length=3,
        pad=pad,
        expected_seq1_batch1=expected_seq1_batch1,
        expected_seq1_batch2=expected_seq1_batch2,
        expected_seq2_batch1=expected_seq2_batch1,
        expected_seq2_batch2=expected_seq2_batch2,
        expected_seq3_batch1=expected_seq3_batch1,
        expected_seq3_batch2=expected_seq3_batch2,
        expected_seq4_batch1=expected_seq4_batch1,
        expected_seq4_batch2=expected_seq4_batch2)

  def testBasicPadding(self):
    self._testBasicPadding(pad=True)

  def testBasicNoPadding(self):
    self._testBasicPadding(pad=False)

  def testNotAMultiple(self):
    num_unroll = 3  # Not a divisor of value_length -
    # so padding would have been necessary.
    with self.test_session() as sess:
      with self.assertRaisesRegexp(errors_impl.InvalidArgumentError,
                                   ".*should be a multiple of: 3, but saw "
                                   "value: 4. Consider setting pad=True."):
        coord = coordinator.Coordinator()
        threads = None
        try:
          with coord.stop_on_exception():
            next_batch = sqss.batch_sequences_with_states(
                input_key=self.key,
                input_sequences=self.sequences,
                input_context=self.context,
                input_length=3,
                initial_states=self.initial_states,
                num_unroll=num_unroll,
                batch_size=self.batch_size,
                num_threads=3,
                # to enforce that we only move on to the next examples after
                # finishing all segments of the first ones.
                capacity=2,
                pad=False)
            threads = queue_runner_impl.start_queue_runners(coord=coord)
            sess.run([next_batch.key])
        except errors_impl.OutOfRangeError:
          pass
        finally:
          coord.request_stop()
          if threads is not None:
            coord.join(threads, stop_grace_period_secs=2)

  def testAdvancedPadding(self):
    num_unroll = 3  # Not a divisor of value_length - so padding to 6 necessary.
    expected_seq1_batch1 = np.tile(
        self.sequences["seq1"][np.newaxis, 0:num_unroll, :],
        (self.batch_size, 1, 1))
    expected_seq2_batch1 = np.tile(
        self.sequences["seq2"][np.newaxis, 0:num_unroll, :, :],
        (self.batch_size, 1, 1, 1))

    padded_seq1 = np.concatenate(
        [
            self.sequences["seq1"][np.newaxis, num_unroll:self.value_length, :],
            np.zeros((1, 1, 5)), np.zeros((1, 1, 5))
        ],
        axis=1)
    expected_seq1_batch2 = np.concatenate(
        [padded_seq1] * self.batch_size, axis=0)

    padded_seq2 = np.concatenate(
        [
            self.sequences["seq2"][np.newaxis, num_unroll:self.value_length, :],
            np.zeros((1, 1, 4, 2)), np.zeros((1, 1, 4, 2))
        ],
        axis=1)
    expected_seq2_batch2 = np.concatenate(
        [padded_seq2] * self.batch_size, axis=0)

    ind1_1 = np.array([
        # batch entry 1
        [0, 0, 0],
        [0, 1, 0], [0, 1, 3], [0, 1, 4],
        # batch entry 2
        [1, 0, 0],
        [1, 1, 0], [1, 1, 3], [1, 1, 4]])
    ind1_2 = np.array([
        # batch entry 1
        [0, 0, 2], [0, 0, 3],
        # batch entry 2
        [1, 0, 2], [1, 0, 3]])
    val1_1 = np.array([0, 10, 13, 14,
                       0, 10, 13, 14])
    val1_2 = np.array([32, 33,
                       32, 33])
    shape1 = np.array([self.batch_size, num_unroll, 6])

    # For sp_tensor2 all values fall into the first segment.
    ind2_1 = np.array([
        # batch entry 1
        [0, 0, 0, 1],
        [0, 0, 1, 0],
        [0, 0, 1, 2],
        [0, 1, 0, 3],
        [0, 1, 1, 0],
        [0, 1, 1, 1],
        [0, 1, 1, 2],
        [0, 1, 2, 2],
        # batch entry 2
        [1, 0, 0, 1],
        [1, 0, 1, 0],
        [1, 0, 1, 2],
        [1, 1, 0, 3],
        [1, 1, 1, 0],
        [1, 1, 1, 1],
        [1, 1, 1, 2],
        [1, 1, 2, 2],
    ])
    val2_1 = np.array([1, 10, 12, 103, 150, 149, 150, 122,
                       1, 10, 12, 103, 150, 149, 150, 122])
    shape2 = np.array([self.batch_size, num_unroll, 3, 4])
    expected_seq3_batch1 = sparse_tensor.SparseTensorValue(
        ind1_1, val1_1, shape1)
    expected_seq3_batch2 = sparse_tensor.SparseTensorValue(
        ind1_2, val1_2, shape1)
    expected_seq4_batch1 = sparse_tensor.SparseTensorValue(
        ind2_1, val2_1, shape2)
    expected_seq4_batch2 = sparse_tensor.SparseTensorValue(
        np.empty(shape=[0, 4], dtype=np.int64), np.array([]), shape2)

    self._testBasics(
        num_unroll=num_unroll,
        length=None,
        pad=True,
        expected_seq1_batch1=expected_seq1_batch1,
        expected_seq1_batch2=expected_seq1_batch2,
        expected_seq2_batch1=expected_seq2_batch1,
        expected_seq2_batch2=expected_seq2_batch2,
        expected_seq3_batch1=expected_seq3_batch1,
        expected_seq3_batch2=expected_seq3_batch2,
        expected_seq4_batch1=expected_seq4_batch1,
        expected_seq4_batch2=expected_seq4_batch2)

class PaddingTest(test.TestCase):

  def testPaddingInvalidLengths(self):
    with ops.Graph().as_default() as g, self.test_session(graph=g):
      sequences = {
          "key_1": constant_op.constant([1, 2, 3]),  # length 3
          "key_2": constant_op.constant([1.5, 2.5])  # length 2
      }

      _, padded_seq = sqss._padding(sequences, 2)
      with self.assertRaisesOpError(
          ".*All sequence lengths must match, but received lengths.*"):
        padded_seq["key_1"].eval()

  def testPadding(self):
    with ops.Graph().as_default() as g, self.test_session(graph=g):
      sequences = {
          "key_1": constant_op.constant([1, 2]),
          "key_2": constant_op.constant([0.5, -1.0]),
          "key_3": constant_op.constant(["a", "b"]),  # padding strings
          "key_4": constant_op.constant([[1, 2, 3], [4, 5, 6]])
      }
      _, padded_seq = sqss._padding(sequences, 5)

      expected_padded_seq = {
          "key_1": [1, 2, 0, 0, 0],
          "key_2": [0.5, -1.0, 0.0, 0.0, 0.0],
          "key_3": ["a", "b", "", "", ""],
          "key_4": [[1, 2, 3], [4, 5, 6], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
      }

      for key, val in expected_padded_seq.items():
        self.assertTrue(
            math_ops.reduce_all(math_ops.equal(val, padded_seq[key])).eval())

class SparseTensorReConstructionTest(test.TestCase):

  def testAddManyTakeManyRoundTripBatched(self):
    with self.test_session(use_gpu=False) as sess:
      # N == 4 because shape_value == [4, 5]
      indices_value_1 = np.array([[0, 0], [0, 1], [2, 0]], dtype=np.int64)
      values_value_1 = np.array([b"a", b"b", b"c"])
      shape_value_1 = np.array([4, 5], dtype=np.int64)
      sparse_tensor_1 = sparse_tensor.SparseTensor(
          array_ops.placeholder(dtypes.int64),
          array_ops.placeholder(dtypes.string),
          array_ops.placeholder(dtypes.int64))
      dict1 = {"key": sparse_tensor_1}
      indices_value_2 = np.array([[1, 4], [2, 3]], dtype=np.int64)
      values_value_2 = np.array([b"d", b"e"])
      shape_value_2 = np.array([4, 5], dtype=np.int64)
      sparse_tensor_2 = sparse_tensor.SparseTensor(
          array_ops.placeholder(dtypes.int64),
          array_ops.placeholder(dtypes.string),
          array_ops.placeholder(dtypes.int64))
      dict2 = {"key": sparse_tensor_2}

      input_seq1, keys1, tensor_list1 = sqss._deconstruct_sparse_tensor_seq(
          dict1, shared_name="a")
      handles_1 = input_seq1["key"]
      input_seq2, _, _ = sqss._deconstruct_sparse_tensor_seq(
          dict2, shared_name="a")
      handles_2 = input_seq2["key"]

      combined_handles = array_ops.stack(
          [handles_1[1], handles_1[2], handles_1[3],
           handles_2[1], handles_2[2], handles_2[3]])
      batched_dict = {"key": combined_handles}
      sqss._reconstruct_sparse_tensor_seq(
          batched_dict,
          keys1,
          tensor_list1,
          batch_size=2,
          num_unroll=3)

      roundtrip_value, = sess.run(
          [batched_dict["key"]],
          feed_dict={sparse_tensor_1.indices: indices_value_1,
                     sparse_tensor_1.values: values_value_1,
                     sparse_tensor_1.dense_shape: shape_value_1,
                     sparse_tensor_2.indices: indices_value_2,
                     sparse_tensor_2.values: values_value_2,
                     sparse_tensor_2.dense_shape: shape_value_2})

      self.assertAllEqual(roundtrip_value.indices,
                          np.array([[0, 1, 0], [1, 0, 4], [1, 1, 3]],
                                   dtype=np.int64))
      self.assertAllEqual(roundtrip_value.values,
                          np.array([b"c", b"d", b"e"]))
      self.assertAllEqual(roundtrip_value.dense_shape,
                          np.array([2, 3, 5], dtype=np.int64))

if __name__ == "__main__":
  test.main()


text:
1. What is the function that creates Regex objects?
2. Why are raw strings often used when creating Regex objects?
3. What does the `search()` method return?
4. How do you get the actual strings that match the pattern from a Match object?
5. In the regex created from `r'(\d\d\d)-(\d\d\d-\d\d\d\d)'`, what does group 0 cover? Group 1? Group 2?
6. Parentheses and periods have specific meanings in regular expression syntax. How would you specify that you want a regex to match actual parentheses and period characters?
7. The `findall()` method returns a list of strings or a list of tuples of strings. What makes it return one or the other?
8. What does the `|` character signify in regular expressions?
9. What two things does the `?` character signify in regular expressions?
10. What is the difference between the `+` and `*` characters in regular expressions?
11. What is the difference between `{3}` and `{3,5}` in regular expressions?
12. What do the `\d`, `\w`, and `\s` shorthand character classes signify in regular expressions?
13. What do the `\D`, `\W`, and `\S` shorthand character classes signify in regular expressions?
14. How do you make a regular expression case-insensitive?
15. What does the `.` character normally match? What does it match if `re.DOTALL` is passed as the second argument to `re.compile()`?
16. What is the difference between `.*` and `.*?`?
17. What is the character class syntax to match all numbers and lowercase letters?
18. If `numRegex = re.compile(r'\d+')`, what will `numRegex.sub('X', '12 drummers, 11 pipers, five rings, 3 hens')` return?
19. What does passing `re.VERBOSE` as the second argument to `re.compile()` allow you to do?
20. How would you write a regex that matches a number with commas for every three digits? It must match the following:

```
'42'
'1,234'
'6,368,745'
```

but not the following:

```
'12,34,567' (which has only two digits between the commas)
'1234' (which lacks commas)
```

21. How would you write a regex that matches the full name of someone whose last name is Nakamoto? You can assume that the first name that comes before it will always be one word that begins with a capital letter. The regex must match the following:

```
'Satoshi Nakamoto'
'Alice Nakamoto'
'Robo op Nakamoto'
```
but not the following:
```
'satoshi Nakamoto' (where the first name is not capitalized)
'Mr. Nakamoto' (where the preceding word has a nonletter character)
'Nakamoto' (which has no first name)
'Satoshi nakamoto' (where Nakamoto is not capitalized)
```

22. How would you write a regex that matches a sentence where the first word is either Alice, Bob, or Carol; the second word is either eats, pets, or throws; the third word is apples, cats, or baseballs; and the sentence ends with a period? This regex should be case-insensitive. It must match the following:

```
'Alice eats apples.'
'Bob pets cats.'
'Carol throws baseballs.'
'Alice throws Apples.'
'BOB EATS CATS.'
```

but not the following:

```
'Robo op eats apples.'
'ALICE THROWS FOOTBALLS.'
'Carol eats 7 cats.'
```

redpajama_set_name: RedPajamaGithub


text:
import TTT_game
import TTT_AI

def board_numbers():
    # Prints out the board coordinates.
    print "012"
    print "345"
    print "678"

def print_board(board):
    # Prints out the current board setting
    for i in range(0,3,1):
        string = ""
        for j in range(0,3,1):
            string += board[((i*3)+j)]
        print string

def main():
    board_numbers()
    g = TTT_game.game()

    # Asking for AI game difficulity
    difficulty_message = "Enter game difficulity (0 for easy, 1 for medium, 2 for hard): "
    difficulty = int(raw_input(difficulty_message))
    a = TTT_AI.AI(difficulty)

    # Asking who goes first
    order_message = "AI first [y/n]: "
    order = raw_input(order_message)
    if order == "y":
        ai_move = a.next_move(g.board,g.turn)
        if g.TakeTurn(ai_move) == False:
            error_message = "AI gave bad coordinate: " + str(ai_move)
            print(error_message)
            exit()
    elif order != "n":
        error_message = "Input needs to be 'y' or 'n'"
        print(error_message)
        exit()

    # Game main loop
    while g.gameover == False:
        # Beginning Output
        print(g.message)
        print_board(g.board)

        # Finding the move
        coor = int(raw_input("Please Enter Move: "))

        # Running through game move
        if coor < 9 and coor >= 0:
            if (g.TakeTurn(coor)):
                g.CheckEnd()
                if g.gameover == False: # Continue AI move if game is not over
                    ai_move = a.next_move(g.board,g.turn)
                    if (g.TakeTurn(ai_move)): # Check move
                        g.CheckEnd() # Checking if AI made winning move or tie.
                    else:
                        error_message = "AI gave bad coordinate: " + str(ai_move)
                        print(error_message)
                        exit()

    # End Message and goodbye
    print("\n"+g.message)
    print_board(g.board)
    print("Goodbye")

main()


text:
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

package org.cef.handler;

import org.cef.browser.CefBrowser;
import org.cef.browser.CefMessageRouter;
import org.cef.callback.CefNative;

import java.util.HashMap;
import java.util.Vector;

/**
 * Implement this interface to provide handler implementations.
 */
public abstract class CefClientHandler implements CefNative {
    // Used internally to store a pointer to the CEF object.
    private HashMap<String, Long> N_CefHandle = new HashMap<String, Long>();
    private Vector<CefMessageRouter> msgRouters = new Vector<>();

    public CefClientHandler() {
        try {
            N_CefClientHandler_CTOR();
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    @Override
    public void setNativeRef(String identifer, long nativeRef) {
        synchronized (N_CefHandle) {
            N_CefHandle.put(identifer, nativeRef);
        }
    }

    @Override
    public long getNativeRef(String identifer) {
        synchronized (N_CefHandle) {
            if (N_CefHandle.containsKey(identifer)) {
                return N_CefHandle.get(identifer);
            }
        }
        return 0;
    }

    protected void dispose() {
        try {
            // Call native DTOR if handler will be destroyed
            for (int i = 0; i < msgRouters.size(); i++) {
                msgRouters.get(i).dispose();
            }
            msgRouters.clear();

            N_CefClientHandler_DTOR();
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    /**
     * Returns the java part of the browser implementation.
     *
     * @param identifer the unique identifier of the browser.
     * @return The found browser or null if none is found.
     */
    abstract protected CefBrowser getBrowser(int identifier);

    /**
     * Returns a list of all browser instances.
     *
     * @return an array of browser Instances.
     */
    abstract protected Object[] getAllBrowser();

    /**
     * Return the handler for context menus. If no handler is provided the
     * default implementation will be used.
     */
    abstract protected CefContextMenuHandler getContextMenuHandler();

    /**
     * Return the handler for dialogs. If no handler is provided the
     * default implementation will be used.
     */
    abstract protected CefDialogHandler getDialogHandler();

    /**
     * Return the handler for browser display state events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefDisplayHandler getDisplayHandler();

    /**
     * Return the handler for download events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefDownloadHandler getDownloadHandler();

    /**
     * Return the handler for drag events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefDragHandler getDragHandler();

    /**
     * Return the handler for focus events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefFocusHandler getFocusHandler();

    /**
     * Return the handler for geolocation requests.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefGeolocationHandler getGeolocationHandler();

    /**
     * Return the handler for javascript dialog requests.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefJSDialogHandler getJSDialogHandler();

    /**
     * Return the handler for keyboard events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefKeyboardHandler getKeyboardHandler();

    /**
     * Return the handler for browser life span events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefLifeSpanHandler getLifeSpanHandler();

    /**
     * Return the handler for browser load status events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefLoadHandler getLoadHandler();

    /**
     * Return the handler for off-screen rendering events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefRenderHandler getRenderHandler();

    /**
     * Return the handler for browser request events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefRequestHandler getRequestHandler();

    /**
     * Return the handler for windowed rendering events.
     * This method is a callback method and is called by
     * the native code.
     */
    abstract protected CefWindowHandler getWindowHandler();

    protected synchronized void addMessageRouter(CefMessageRouter h) {
        try {
            msgRouters.add(h);
            N_addMessageRouter(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeContextMenuHandler(CefContextMenuHandler h) {
        try {
            N_removeContextMenuHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeDialogHandler(CefDialogHandler h) {
        try {
            N_removeDialogHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeDisplayHandler(CefDisplayHandler h) {
        try {
            N_removeDisplayHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeDownloadHandler(CefDisplayHandler h) {
        try {
            N_removeDownloadHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeDragHandler(CefDragHandler h) {
        try {
            N_removeDragHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeFocusHandler(CefFocusHandler h) {
        try {
            N_removeFocusHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeGeolocationHandler(CefGeolocationHandler h) {
        try {
            N_removeGeolocationHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeJSDialogHandler(CefJSDialogHandler h) {
        try {
            N_removeJSDialogHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeKeyboardHandler(CefKeyboardHandler h) {
        try {
            N_removeKeyboardHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeLifeSpanHandler(CefLifeSpanHandler h) {
        try {
            N_removeLifeSpanHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeLoadHandler(CefLoadHandler h) {
        try {
            N_removeLoadHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected synchronized void removeMessageRouter(CefMessageRouter h) {
        try {
            msgRouters.remove(h);
            N_removeMessageRouter(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeRenderHandler(CefRenderHandler h) {
        try {
            N_removeRenderHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeRequestHandler(CefRequestHandler h) {
        try {
            N_removeRequestHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    protected void removeWindowHandler(CefWindowHandler h) {
        try {
            N_removeWindowHandler(h);
        } catch (UnsatisfiedLinkError err) {
            err.printStackTrace();
        }
    }

    private final native void N_CefClientHandler_CTOR();

    private final native void N_addMessageRouter(CefMessageRouter h);

    private final native void N_removeContextMenuHandler(CefContextMenuHandler h);

    private final native void N_removeDialogHandler(CefDialogHandler h);

    private final native void N_removeDisplayHandler(CefDisplayHandler h);

    private final native void N_removeDownloadHandler(CefDisplayHandler h);

    private final native void N_removeDragHandler(CefDragHandler h);

    private final native void N_removeFocusHandler(CefFocusHandler h);

    private final native void N_removeGeolocationHandler(CefGeolocationHandler h);

    private final native void N_removeJSDialogHandler(CefJSDialogHandler h);

    private final native void N_removeKeyboardHandler(CefKeyboardHandler h);

    private final native void N_removeLifeSpanHandler(CefLifeSpanHandler h);

    private final native void N_removeLoadHandler(CefLoadHandler h);

    private final native void N_removeMessageRouter(CefMessageRouter h);

    private final native void N_removeRenderHandler(CefRenderHandler h);

    private final native void N_removeRequestHandler(CefRequestHandler h);

    private final native void N_removeWindowHandler(CefWindowHandler h);

    private final native void N_CefClientHandler_DTOR();
}


text:
#ifndef SOFTWARESPMV_H_
#define SOFTWARESPMV_H_

#include "SpMV.h"

class SoftwareSpMV: public SpMV {
public:
	SoftwareSpMV(SparseMatrix * A, SpMVData *x = 0, SpMVData *y = 0);
	virtual ~SoftwareSpMV();

	void measurePreprocessingTimes();

	virtual bool exec();

	virtual unsigned int statInt(std::string name);
	virtual std::vector<std::string> statKeys();

protected:
	bool m_allocX, m_allocY;
	unsigned int m_execTime;
	unsigned int m_cmsTime;
	unsigned int m_maxAliveTime;
	unsigned int m_maxColSpanTime;
	unsigned int m_maxAlive;
	unsigned int m_maxColSpan;
};

#endif /* SOFTWARESPMV_H_ */


text:
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RequestHandler.cs" company="Julien Blin">
//   Copyright (c) 2014 Julien Blin
// </copyright>
// <summary>
//   Base class for <see cref="IRequestHandler" /> implementations.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hexagon
{
    using Hexagon.Messages;

    /// <summary>
    /// Base class for <see cref="IRequestHandler{TRequest,TResponse}"/> implementations.
    /// </summary>
    /// <typeparam name="TRequest">
    /// The type of request to handle.
    /// </typeparam>
    /// <typeparam name="TResponse">
    /// The type of response.
    /// </typeparam>
    public abstract class RequestHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
        where TRequest : IRequest<TResponse>
        where TResponse : IResponse
    {
        /// <summary>
        /// The logger.
        /// </summary>
        private ILogger logger;

        /// <summary>
        /// Gets or sets the <see cref="ILogger"/>.
        /// </summary>
        public ILogger Logger
        {
            get
            {
                return this.logger ?? (this.logger = NullLogger.Instance);
            }

            set
            {
                this.logger = value;
            }
        }

        /// <inheritdoc />
        void IRequestHandler.Handle(IRequest request, IResponse response)
        {
            Guard.AgainstNull(() => request, request);
            Guard.AgainstNull(() => response, response);
            Guard.AgainstTypeIncompatibility<TRequest>(() => request, request);
            Guard.AgainstTypeIncompatibility<TResponse>(() => response, response);

            this.Handle((TRequest)request, (TResponse)response);
        }

        /// <summary>
        /// Actual handling of <paramref name="request"/>.
        /// </summary>
        /// <param name="request">
        /// The request to handle.
        /// </param>
        /// <param name="response">
        /// The response to fill.
        /// </param>
        protected abstract void Handle(TRequest request, TResponse response);
    }
}


text:
<?php
/**
 * Timezone Setting
 * List of Supported Timezones: http://www.php.net/manual/en/timezones.php
 */
date_default_timezone_set('America/Chicago');

/**
  * Enable Sessions
  * Checks to see if a session_id exists.  If not, a new session is started.
  */
if(!session_id()) session_start();

/**
 * Sandbox Mode - TRUE/FALSE
 * Check the domain of the current page and set $sandbox accordingly.
 * This allows you to automatically use Sandbox or Live credentials throughout
 * your application based on what server the app is running from.
 *
 * I like to do this so I don't forget to update Sandbox credentials to Live
 * prior to uploading files to a production server.
 *
 * In this case, it's checking to see if the current URL is http://sandbox.domain.*
 * If so, $sandbox is true and the PayPal sandbox will be used throughout.  If not,
 * we'll assume it must be a live transaction and will use live credentials throughout.
 *
 * Following this pattern will allow you to create your own http://sandbox.domain.com test server,
 * and then any time your code runs from that server, PayPal's sandbox will be used automatically.
 *
 * If you would rather just set $sandbox to true/false on your own that's fine,
 * but you have to make sure your live server always uses false and your test server
 * always uses true.  It's easy to forget this and up with real customers processing
 * payments from your live site on the PayPal sandbox.
 */
$host_split = explode('.',$_SERVER['HTTP_HOST']);
$sandbox = $host_split[0] == 'sandbox' && $host_split[1] == 'domain' ? TRUE : FALSE;
$domain = $sandbox ? 'http://sandbox.domain.com/' : 'http://www.domain.com/';

/**
 * Enable error reporting if running in sandbox mode.
 */
if($sandbox)
{
	error_reporting(E_ALL|E_STRICT);
	ini_set('display_errors', '1');
}

/*
 * PayPal API Version
 * ------------------
 * The library is currently using PayPal API version 109.0.
 * You may adjust this value here and then pass it into the PayPal object when you create it within your scripts to override if necessary.
 */
$api_version = '112.0';

/*
 * PayPal Application ID
 * --------------------------------------
 * The application is only required with Adaptive Payments applications.
 * You obtain your application ID but submitting it for approval within your
 * developer account at http://developer.paypal.com
 *
 * We're using shorthand if/else statements here to set both Sandbox and Production values.
 * Your sandbox values go on the left and your live values go on the right.
 * The sandbox value included here is a global value provided for developrs to use in the PayPal sandbox.
 */
$application_id = $sandbox ? 'APP-80W284485P519543T' : '';

/*
 * PayPal Developer Account Email Address
 * This is the email address that you use to sign in to http://developer.paypal.com
 */
$developer_account_email = '';

/*
 * PayPal Gateway API Credentials
 * ------------------------------
 * These are your PayPal API credentials for working with the PayPal gateway directly.
 * These are used any time you're using the parent PayPal class within the library.
 *
 * We're using shorthand if/else statements here to set both Sandbox and Production values.
 * Your sandbox values go on the left and your live values go on the right.
 *
 * You may obtain these credentials by logging into the following with your PayPal account: https://www.paypal.com/us/cgi-bin/webscr?cmd=_login-api-run
 */
$api_username = $sandbox ? 'SANDBOX_API_USERNAME' : 'LIVE_API_USERNAME';
$api_password = $sandbox ? 'SANDBOX_API_PASSWORD' : 'LIVE_API_PASSWORD';
$api_signature = $sandbox ? 'SANDBOX_API_SIGNATURE' : 'LIVE_API_SIGNATURE';

/*
 * Payflow Gateway API Credentials
 * ------------------------------
 * These are the credentials you use for your PayPal Manager:  http://manager.paypal.com
 * These are used when you're working with the PayFlow child class.
 *
 * We're using shorthand if/else statements here to set both Sandbox and Production values.
 * Your sandbox values go on the left and your live values go on the right.
 *
 * You may use the same credentials you use to login to your PayPal Manager,
 * or you may create API specific credentials from within your PayPal Manager account.
 */
$payflow_username = $sandbox ? 'SANDBOX_PAYFLOW_USERNAME' : 'LIVE_PAYFLOW_USERNAME';
$payflow_password = $sandbox ? 'SANDBOX_PAYFLOW_PASSWORD' : 'LIVE_PAYFLOW_PASSWORD';
$payflow_vendor = $sandbox ? 'SANDBOX_PAYFLOW_VENDOR' : 'LIVE_PAYFLOW_VENDOR';
$payflow_partner = $sandbox ? 'SANDBOX_PAYFLOW_PARTNER' : 'LIVE_PAYFLOW_PARTNER';

/*
 * PayPal REST API Credentials
 * ---------------------------
 * These are the API credentials used for the PayPal REST API.
 * These are used any time you're working with the REST API child class.
 *
 * You may obtain these credentials from within your account at http://developer.paypal.com
 */
$rest_client_id = $sandbox ? 'SANDBOX_CLIENT_ID' : 'LIVE_CLIENT_ID';
$rest_client_secret = $sandbox ? 'SANDBOX_CLIENT_ID' : 'LIVE_SECRET_ID';

/*
 * PayPal Finance Portal API
 * -------------------------
 * These are credentials used for obtaining a PublisherID used in Bill Me Later Banner code.
 * As of now, these are specialized API's and you must obtain credentials directly from a PayPal rep.
 */
$finance_access_key = $sandbox ? 'SANDBOX_ACCESS_KEY' : 'LIVE_ACCESS_KEY';
$finance_client_secret = $sandbox ? 'SANDBOX_CLIENT_SECRET' : 'LIVE_CLIENT_SECRET';

/**
 * Third Party User Values
 * These can be setup here or within each caller directly when setting up the PayPal object.
 */
$api_subject = '';	// If making calls on behalf a third party, their PayPal email address or account ID goes here.
$device_id = '';
$device_ip_address = $_SERVER['REMOTE_ADDR'];
?>


text:
#ifndef SkError_DEFINED
#define SkError_DEFINED

/** \file SkError.h
*/

enum SkError {
    /** All is well
     */
    kNoError_SkError=0,

    /** User argument passed to Skia function was invalid: NULL when that's
     *  not allowed, out of numeric range, bad enum, or violating some
     *  other general precondition.
     */
    kInvalidArgument_SkError,

    /** User tried to perform some operation in a state when the operation
     *  was not legal, or the operands make no sense (e.g., asking for
     *  pixels from an SkPictureCanvas).  Other examples might be
     *  inset()'ing a rectangle to make it degenerate (negative width/height).
     */
    kInvalidOperation_SkError,

    /** Probably not needed right now, but in the future we could have opaque
     *  handles for SkPictures floating around, and it would be a good idea
     *  to anticipate this kind of issue.
     */
    kInvalidHandle_SkError,

    /** This is probably not possible because paint surely has defaults for
     *  everything, but perhaps a paint can get into a bad state somehow.
     */
    kInvalidPaint_SkError,

    /** Skia was unable to allocate memory to perform some task.
     */
    kOutOfMemory_SkError,

    /** Skia failed while trying to consume some external resource.
     */
    kParseError_SkError
};

/** Return the current per-thread error code.  Error codes are "sticky"; they
 *  are not not reset by subsequent successful operations.
 */
SkError SkGetLastError();

/** Clear the current per-thread error code back to kNoError_SkError.
 */
void SkClearLastError();

/** Type for callback functions to be invoked whenever an error is registered.
 *  Callback functions take the error code being set, as well as a context
 *  argument that is provided when the callback is registered.
 */
typedef void (*SkErrorCallbackFunction)(SkError, void *);

/** Set the current per-thread error callback.
 *
 *  @param cb The callback function to be invoked.  Passing NULL
 *            for cb will revert to the default error callback which
 *            does nothing on release builds, but on debug builds will
 *            print an informative error message to the screen.
 *  @param context An arbitrary pointer that will be passed to
 *                 the provided callback function.
 */
void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context);

/** Get a human-readable description of the last (per-thread) error that
 *  occurred.  The returned error message will include not only a human
 *  readable version of the error code, but also information about the
 *  conditions that led to the error itself.
 */
const char *SkGetLastErrorString();

#endif /* SkError_DEFINED */


text:
1. Git-ged commands
    - repo-level commands:
        - _init_: populates `refs/heads/{master,content,intent/master}` with README, LICENSE_DEFAULT, etc. as specified by user
        - _clone_: same as git clone
        - _attach_: same as git remote add, except that it allows the user to define the set of permanames of interest in the remote repo
        - _fetch_: same as git fetch, except that only permanames that the user currently has are fetched (along with `refs/heads/master`)
        - _push_: same as git push, except that only permanames that the remote repo has are updated
    - entity- and state-level commands:
        - _intent_: captures one-line user intent to capture large-scale project (separate from commit message on a single entity)
        - _ingest_: populates `refs/local/gedcoms/{permaname(s)}` with a raw gedcom, adding new gedN files for permaname collisions
        - _filter_: performs living filter and populates `refs/heads/gedcoms/{permaname}`
        - _import_: creates any new persons/families and records import flag & new person/family permaname+state links in gedX.IMPORT
        - _resolve_: deals with multiple-record histories in a smart way (gedcoms/persons/families)
        - _owner_: establishes identity of the owner of the repo in `refs/heads/content:/OWNER`, adds person for the user and allows specification of 'mpmmp' ancestor links to deceased horizon
    - interactive-use commands:
        - _workspace_: (subcommands: checkout, update, reset)
            - _checkout_: grabs every specified person/family/gedcom permaname and puts it under the path repo/[persons|families|gedcoms]/{permaname} in a transient commit
            - _update_: grabs the head of every specified person/family/gedcom permaname and puts it under a new `refs/heads/workspace` commit
            - _reset_: warns if un-git-ged-committed `refs/heads/workspace` history, then nukes it and recreates a `refs/heads/workspace` commit with the same permanames as it had before
        - _commit_: creates commits on every separate permaname that has changed, using current intent as default commit subject plus details of all entities that changed

2. Data Licenses
    - Data license defaults to Creative Commons Attribution-ShareAlike 3.0 Unported
    - Users can update license at repo/gedcom/record level
    - Other common license options are easily specifiable
        - Other Creative Commons options: CC-BY-3.0, CC-BY-NC-3.0, CC-BY-NC-SA-3.0, CC0-1.0
        - Open Data Commons options: ODC-PDDL-1.0, ODC-BY-1.0, ODC-ODBL-1.0

3. Gedcom
    - all ingested gedcoms are stored verbatim under a `refs/local/gedcoms/{permaname}` ref
    - all imported, living-filtered gedcoms are stored under a `refs/heads/gedcoms/{permaname}` ref
    - there are multiple permanames for a gedcom:
        - primary permaname for gedcom is the sha256 hash of "FILE & SUBM name[/email]"
        - alternate permaname for gedcom is the sha256 hash of "FILE & DATE"
        - alternate permaname for gedcom is the sha256 hash of "source path & SUBM name"
        - alternate permaname for gedcom is the sha256 hash of all person _UUIDs, sorted alphanumerically
    - keep your email, paths & filenames consistent to maximize permaname collisions
    - copies the repo's LICENSE\_DEFAULT unless overridden by the user at ingest time

4. Person
    - all imported persons are stored in a standard JSON format under a `refs/heads/persons/{permaname}` refs
    - there are **multiple** permanames for a person:
        - one is designated as primary, all permanames are annotated internally to the person by a versioned hash function (for easy recomputation)
        - primary permaname for person defaults to the sha256 hash of the gedcom UID + sorted 'not-same-as' list
        - alternate permaname for person is the sha256 hash of "<displayname>[ birthdate][ deathdate][ sorted 'not-same-as' list]" (can be designated as primary)
        - alternate permaname for person is the sha256 hash of "<displayname> child of <permaname>" (for each parent, if there is no birth/death)
        - other alternate permanames are definable, as long as the context-free code for computing them is included under `refs/heads/code`
        - permanames based on "displayname" state should not change when the person's name is updated, they are designed to produce collisions based on import data
        - although a person's primary permaname should remain largely constant, it can change for reasons of disambiguation (addition of a 'not-same-as' link)
    - proper protection of living data
        - all imported persons must be deceased and publicly-viewable, or the record will initially exist under the `refs/local/persons/...` refspace
        - import is responsible for initially segmenting living vs. deceased, but after import the app is responsible for calculating living after edit and moving the record if necessary
        - the same living check & segmentation logic that import uses will be available on-demand for apps to use after edit
        - when a deceased record is made living, the deceased record's permaname gets a new commit that marks it as no-longer-visible (so that on subsequent fetch, other repositories can delete their records)
    - includes optional "supersedes", "superseded-by", "derived-from", "descendant-of", "same-as", and "not-same-as" link attributes
        - the "supersedes", "superseded-by", and "derived-from" link attributes allow for proper history-aware linkage across permanames for tracing merge or other complicated person record derivation
        - the "descendant-of" attribute is for attaching non-descript living persons to their deceased horizon via "mpmmp" links
        - the "same-as" attribute is a loose identity link to an alternate history of a person determined to be the same historical person, it is a hint that a merge or other record derivation may be useful in the future
        - if the "not-same-as" attribute refers to a disconnected history of a *different* person under the same permaname, it is best to change the permaname of each person this attribute is added to
    - person merge is often not needed if the persons originated unchanged from the same gedcom
    - person merge may be a "comes before/comes after" decision at import time
    - person merge decisions can be deferred by storing two person entities under the same permaname and letting the user make the before/after decision at a later time
    - multiple persons can be stored under the same permaname under 'entity1'..'entityN' blob names
    - copies the gedcom LICENSE if imported, copies the repo's LICENSE\_DEFAULT if a newly-created person

5. Family
    - direct represenation of the GEDCOM family concept
    - all imported families are stored in a standard JSON format under a `refs/heads/families/{permaname}` refs
    - there are multiple permanames for a family:
        - one is designated as primary, all permanames are annotated internally to the family by a versioned hash function (for easy recomputation)
        - primary permaname for family defaults to the sha256 hash of the parents' primary permanames in alphanumeric order
        - alternate permaname for family is the sha256 hash of "<displayname>[ displayname][ marriage date]" (if there is marriage information, displaynames ordered by primary permaname alphanumeric ordering of parents)
        - other alternate permanames are definable, as long as the context-free code for computing them is included under `refs/heads/code`
        - permanames based on "displayname" state should not change when the person's name is updated, they are designed to produce collisions based on import data
        - primary permaname should change if the parents' permanames are modified, or if a parent is replaced with a different person
    - includes person links for each person in each family position
    - includes optional "supersedes", "superseded-by", "derived-from", "same-as", and "not-same-as" link attributes (like person)
    - includes optional "prior-family" link attribute that tracks temporal household dissolution & recomposition
    - family merge is often not needed if the family originated unchanged from the same gedcom
    - family merge can be a "comes before/comes after" decision at import time, but is not as likely as person to fit this workflow
    - family merge decisions can be deferred by storing two family entities under the same permaname and letting the user make the before/after decision at a later time
    - multiple families can be stored under the same permaname under 'entity1'..'entityN' blob names
    - copies the gedcom LICENSE if imported, copies the repo's LICENSE\_DEFAULT if a newly-created record

6. Link Attribute
    - link attributes always refer to BOTH primary permaname & state
    - link attributes are encoded similar to XFN to start

7. Merge Strategies
    - merge comes in at least 4 flavors:
        1. (import) alternate record storage + history linkage (recommended for automated import processes)
        2. (post-import) "comes before/comes after" record replacement strategy for dealing with record reconciliation
        3. (post-import) "pick correct values" record reconciliation strategy for dealing with partial truth from multiple sources (sets "derived-from" attribute(s))
        4. (post-import) "disambiguation" record reconciliation strategy for separating records that are NOT the same person (sets "not-same-as" attribute(s))
    - of course anyone can do anything they please to their records, but these strategies seem to deserve automation support

8. Record deriviation tracing
    - each of the following link attributes refers to another record via permaname+state reference
    - "supersedes" indicates that a person (or family) is a full, identical replacement for another (used to be able to react to remote merges)
    - "superseded-by" indicates that a static, not-to-be-further-edited  person (or family) is left behind after having been merged into the canonical record (used to detect conflicts between local edits & remote merge or vice versa)
    - "same-as" indicates a more-tentative-than-merge attempt at establishing identity to allow for disparate efforts to proceed before attempting a full merge
    - "disambiguated-by" indicates a forward-reference from a person/family that has no useful future except for providing opportunity for fruitful permaname collision & disambiguation hints to users on subsequent imports
    - "derived-from" indicates a record that took a significant amount of data from another record, from which an identity was extracted
    - "not-same-as" indicates a definitive statement that one person (or family) is NOT the same as another (used when extracting a half-merged entity that collided on a permaname)
    - "prior-family" indicates that a family has many of the same members of a prior family, but temporal household dissolution & recomposition require two different families to be tracked (allows for "current family" computations based on a directed graph of prior-family edges)

9. Deletion of Records
    - person/family/gedcom delete comes in three flavors:
        1. "deref": I no longer care to track or maintain this person, if anyone has this person cloned, let them continue to maintain the record
        2. "hide": I want the record gone on any repo that follows mine, if they fetch from me, MAKE their record go away, dead-to-living transition uses this mechanism
        3. "delete": I want the record gone on any repo that follows mine, if they fetch from me, SUGGEST that their record go away
    - "hide" and "delete" stubs hang around for a longish-but-limited amount of time, and there is a mechanism that automatically cleans them up every so often

### GIT-GED REFS LAYOUT

Here are the general patterns of things that live under `refs/`:

1. `refs/heads/*`:
    - stuff that can be cloned/fetched

2. `refs/heads/{gedcoms,persons,families/intents}/*`:
    - data that can be cloned/fetched/forked piecemeal

3. `refs/local/*`:
    - dispensible stuff that is used for local import actions (not needed for collaboration)
    - hidden stuff that should not be published on a clone/fork

Here are specific details about each kind of ref:

1. `refs/heads/master` (fetchable, but non-mergeable):
    - `README`: simple documentation of git-ged, with pointer to software to parse/use
    - `LAYOUT`: this file containing details of git-ged structure

2. `refs/heads/content` (fetchable, but non-mergeable):
    - `META`: last version of git-ged that wrote
    - `OWNER`: the identity of the owner of this repo + OpenID URLs, blog URLs and/or email(s)
    - `LICENSE_DEFAULT`: default license for any new records added or imported into to this repository, defaults to Creative Commons Share-alike
    - `ROOTS`: links to various person permaname roots, to start tree navigation from
    - `ENTITIES`: list of gedcom/person/family/intent permaname+state links, may end up needing to be sharded for very large repos
    - `INTENTS`: list of last N intents & date & author
    - `CHANGELOG`: contains up to last 100 edits performed, including list of entities changed, updated by git-ged commit
    - `LIMITS`: maximum number of intents, etc.

3. `refs/heads/intents/master` (fetchable, but non-mergeable):
    - `INTENT`: stores the user's git identity, date, and, single-line 140-char intent message in the tree itself to capture "why"
    - MUST exist: if no intent is explicitly stored, init/import/edit must stub one in that describes the largest-scope action being taken
    - able to cherry-pick an intent from some other user to show you're working toward the same goal as someone else
    - able to generate a feed of intents from here
    - capped at 100 or so max commits (large limit)

4. `refs/heads/intents/{permanames}`:
    - selective intents used to document why a certain change is made (linked from entities at commit)

5. `refs/heads/workspace` (fetchable, but non-mergeable):
    - non-history-preserving workspace tree for pulling a subset of records into a filesystem for edit

6. `refs/heads/gedcoms/{permanames}`:
    - `ged1`: the living-filtered gedcom file renamed to a standard filename
    - `gedN`: the living-filtered gedcom file renamed to a standard filename
    - contains NO living data, as a result of "ingest" followed by "import"
    - `gedX.META`: link to intent; original file name & path; where/who the file came from; all permanames this gedcom was stored under (by permaname kind)
    - `gedX.LICENSE`: license for use of this gedcom as a whole, copied to individual persons/families at import time

7. `refs/local/gedcoms/{permanames}`:
    - _may_ contain living data, populated without filtering by "ingest"
    - `ged1`: the raw gedcom file renamed to a standard filename
    - `gedN`: the raw gedcom file renamed to a standard filename
    - pre-existing permanames get forwarded up to the new tree (collisions, yay!)
    - new permanames get created, non-colliding permanames don't get forwarded (gc'd by some other mechanism)
    - if the gedcom contains no living data, "import" can delete the `refs/local` refs
    - can coexist with `refs/heads/gedcoms/{permaname}` for a while as documentation of exactly what got imported
    - fetch/clone/fork does NOT include the original gedcom, just the "post-import" one (because only `refs/heads` comes along)

8. `refs/heads/persons/{permanames}`:
    - `entity1`: the primary person in a standard JSON form
    - `entityN`: alternate, not-yet-merged person records
    - `entityX.{format}`: the primary person (or an alternate) in an alternate format
    - `entityX.META`: link to intent; link(s) to gedcom permanames
    - `entityX.IDENTITY`: optional "supersedes", "superseded-by", "derived-from", "same-as", and "not-same-as" link attributes; also any arbitrary XFNs to other permanames
    - `entityX.LICENSE`: license for use of this person, copied from gedcom at import time, or from repo's LICENSE\_DEFAULT at non-import-creation time
    - commits on a person can easily be merged/fast-forwarded if history is shared and there are no textual conflicts
    - commits on two persons of the same permaname that do NOT share history can undergo person merge
    - merge commits set "supersedes" and "superseded-by" link attributes to allow post-merge traceability
    - merging of META takes a "most recent intent / union" approach
    - merging of IDENTITY takes a "union with conflict detection & manual resolution" approach
    - merging of LICENSE takes the more restrictive license by default

9. `refs/local/persons/{permanames}`:
    - non-public person record, behaves like person in every other respect
    - typically a person record should exist under EITHER `refs/local` OR `refs/heads`
    - if both exist, the `refs/heads` record is used exclusively

10. `refs/heads/families/{permanames}`:
    - `entity1`: the primary family in a standard JSON form
    - `entityN`: alternate, not-yet-merged family records
    - `entityX.{format}`: the primary person (or an alternate) in an alternate format
    - `entityX.META`: link to intent; link(s) to gedcom permanames
    - `entityX.IDENTITY`: optional "prior-family", "derived-from", "supersedes", "superseded-by", "same-as", and "not-same-as" link attributes; also any arbitrary XFNs to other permanames
    - `entityX.LICENSE`: license for use of this person, copied from gedcom at import time, or from repo's LICENSE\_DEFAULT at non-import-creation time
    - commits on a family can easily be merged/fast-forwarded if history is shared and there are no textual conflicts
    - commits on two families of the same permaname that do NOT share history can undergo family merge
    - merging of META takes a "most recent intent / union" approach
    - merging of IDENTITY takes a "union with conflict detection & manual resolution" approach
    - merging of LICENSE takes the more restrictive license by default

11. `refs/local/families/{permanames}`:
    - non-public family record, behaves like family in every other respect
    - typically a family record should exist under EITHER `refs/local` OR `refs/heads`
    - if both exist, the `refs/heads` record is used exclusively


text:
using AccidentalFish.ApplicationSupport.Core.Blobs;
using Microsoft.WindowsAzure.Storage.Blob;

namespace AccidentalFish.ApplicationSupport.Azure.Blobs
{
    // ReSharper disable once InconsistentNaming
    public static class IBlobExtensions
    {
        public static string GetSharedAccessSignature(this IBlob blob, SharedAccessBlobPolicy policy)
        {
            BlockBlob azureBlob = (BlockBlob) blob;
            return azureBlob.CloudBlockBlob.GetSharedAccessSignature(policy);
        }

        public static CloudBlockBlob CloudBlockBlob(this IBlob blob)
        {
            BlockBlob azureBlob = (BlockBlob) blob;
            return azureBlob.CloudBlockBlob;
        }
    }
}