<commit_before>/**
 * Created by oszust on 08.05.17.
 */
import React, { PropTypes, Component } from 'react';
import { gql } from 'react-apollo';
import { FormattedMessage } from 'react-intl';
import Typography from 'material-ui/Typography';
import Table, { TableRow, TableCell, TableBody } from 'material-ui/Table';
import EnhancedTableHead from '../../EnhancedTableHead';
import messages from './messages';

export const TestResultsFragment = gql`
  fragment TestResults on Submit {
    testResults {
      id
      test
      status
      ramUsage
      executionTime
    }
  }
`;

const columnData = [
  { id: 'test', label: <FormattedMessage {...messages.test} /> },
  { id: 'status', label: <FormattedMessage {...messages.status} /> },
  { id: 'executionTime', label: <FormattedMessage {...messages.executionTime} /> },
  { id: 'ramUsage', label: <FormattedMessage {...messages.ramUsage} /> },
];

class TestsTable extends Component {
  static propTypes = {
    tests: PropTypes.arrayOf(
      React.PropTypes.shape({
        status: React.PropTypes.node.isRequired,
        executionTime: React.PropTypes.number.isRequired,
        ramUsage: React.PropTypes.number.isRequired,
        test: React.PropTypes.number.isRequired,
      })
    ).isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      order: 'asc',
      orderBy: 'test',
    };
  }

  handleRequestSort = (event, property) => {
    const orderBy = property;
    let order = 'desc';

    if (this.state.orderBy === property && this.state.order === 'desc') {
      order = 'asc';
    }

    this.setState({ order, orderBy });
  };

  render() {
    const { order, orderBy } = this.state;

    const tests = Object.values(this.props.tests)
      .sort((a, b) => (order === 'desc' ? b[orderBy] > a[orderBy] : a[orderBy] > b[orderBy]));
    return (

        <Typography type="title"><FormattedMessage {...messages.tests} /></Typography>

          <EnhancedTableHead
            columns={columnData}
            order={order}
            orderBy={orderBy}
            onRequestSort={this.handleRequestSort}
          />
          <TableBody>
            {tests.map((test) =>
              <TableRow key={test.id}>
                <TableCell>{test.test}</TableCell>
                <TableCell>{test.status}</TableCell>
                <TableCell>{test.executionTime}</TableCell>
                <TableCell>{test.ramUsage}</TableCell>
              </TableRow>
            )}
          </TableBody>

    );
  }
}

export default TestsTable;
<commit_msg>Add units to test results (#199)<commit_after>/**
 * Created by oszust on 08.05.17.
 */
import React, { PropTypes, Component } from 'react';
import { gql } from 'react-apollo';
import { FormattedMessage } from 'react-intl';
import Typography from 'material-ui/Typography';
import Table, { TableRow, TableCell, TableBody } from 'material-ui/Table';
import EnhancedTableHead from '../../EnhancedTableHead';
import messages from './messages';

export const TestResultsFragment = gql`
  fragment TestResults on Submit {
    testResults {
      id
      test
      status
      ramUsage
      executionTime
    }
  }
`;

const columnData = [
  { id: 'test', label: <FormattedMessage {...messages.test} /> },
  { id: 'status', label: <FormattedMessage {...messages.status} /> },
  { id: 'executionTime', label: <FormattedMessage {...messages.executionTime} /> },
  { id: 'ramUsage', label: <FormattedMessage {...messages.ramUsage} /> },
];

class TestsTable extends Component {
  static propTypes = {
    tests: PropTypes.arrayOf(
      React.PropTypes.shape({
        status: React.PropTypes.node.isRequired,
        executionTime: React.PropTypes.number.isRequired,
        ramUsage: React.PropTypes.number.isRequired,
        test: React.PropTypes.number.isRequired,
      })
    ).isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      order: 'asc',
      orderBy: 'test',
    };
  }

  handleRequestSort = (event, property) => {
    const orderBy = property;
    let order = 'desc';

    if (this.state.orderBy === property && this.state.order === 'desc') {
      order = 'asc';
    }

    this.setState({ order, orderBy });
  };

  render() {
    const { order, orderBy } = this.state;

    const tests = Object.values(this.props.tests)
      .sort((a, b) => (order === 'desc' ? b[orderBy] > a[orderBy] : a[orderBy] > b[orderBy]));
    return (

        <Typography type="title"><FormattedMessage {...messages.tests} /></Typography>

          <EnhancedTableHead
            columns={columnData}
            order={order}
            orderBy={orderBy}
            onRequestSort={this.handleRequestSort}
          />
          <TableBody>
            {tests.map((test) =>
              <TableRow key={test.id}>
                <TableCell>{test.test}</TableCell>
                <TableCell>{test.status}</TableCell>
                <TableCell>{test.executionTime} µs</TableCell>
                <TableCell>{test.ramUsage} kB</TableCell>
              </TableRow>
            )}
          </TableBody>

    );
  }
}

export default TestsTable;
<|endoftext|>


<commit_before>import fs from "fs"
import { inject, observer } from "mobx-react"
import PropTypes from "prop-types"
import {
  always,
  is,
  isNil,
  join,
  keys,
  last,
  length,
  lt,
  map,
  max,
  merge,
  min,
  pickBy,
  replace,
  slice,
  split,
  take,
  takeLast,
  when,
} from "ramda"
import { dotPath, isNilOrEmpty } from "ramdasauce"
import React, { Component } from "react"
import ReactTooltip from "react-tooltip"
import stringifyObject from "stringify-object"
import Command from "../Shared/Command"
import Content from "../Shared/Content"
import AppStyles from "../Theme/AppStyles"
import Colors from "../Theme/Colors"

const PREVIEW_LENGTH = 500
const SOURCE_LINES_UP = 3
const SOURCE_LINES_DOWN = 3
const SOURCE_FILE_PATH_COUNT = 3
const OBJECT_KEYS_COUNT = 5
const OBJECT_PROPERTY_PREVIEW_LENGTH = 80

const getName = level => {
  switch (level) {
    case "debug":
      return "DEBUG"
    case "warn":
      return "WARNING"
    case "error":
      return "ERROR"
    default:
      return "LOG"
  }
}

const stackFrameBaseStyle = {
  ...AppStyles.Layout.hbox,
  padding: 6,
  wordBreak: "break-all",
  cursor: "pointer",
}

const selectionStyle = {
  color: Colors.tag,
  backgroundColor: Colors.backgroundDarker,
  borderLeft: `1px solid ${Colors.tag}`,
  borderRight: `1px solid ${Colors.subtleLine}`,
  borderTop: `1px solid ${Colors.subtleLine}`,
  borderBottom: `1px solid ${Colors.subtleLine}`,
}

const Styles = {
  container: {
    paddingTop: 4,
  },
  stack: {
    marginTop: 10,
    ...AppStyles.Layout.vbox,
  },
  stackTable: {
    ...AppStyles.Layout.vbox,
  },
  stackFrame: {
    ...stackFrameBaseStyle,
    ...AppStyles.Layout.hbox,
    padding: 6,
  },
  stackFrameNodeModule: {
    ...stackFrameBaseStyle,
    opacity: 0.4,
  },
  selectedStackFrame: {
    ...selectionStyle,
  },
  number: {
    color: Colors.constant,
    textAlign: "right",
    width: 50,
    paddingRight: 10,
    paddingTop: 3,
  },
  functionName: {
    flex: 1,
  },
  fileName: {
    flex: 1,
    wordBreak: "break-all",
  },
  lineNumber: {
    color: Colors.constant,
    wordBreak: "break-all",
    width: 50,
    textAlign: "right",
  },
  stackLabel: {
    color: Colors.foregroundDark,
    margin: "0 7px",
    wordBreak: "break-all",
  },
  stackTitle: {
    color: Colors.constant,
    paddingBottom: 10,
    wordBreak: "break-all",
  },
  theadRow: {
    ...AppStyles.Layout.hbox,
    padding: 6,
    color: Colors.foregroundDark,
  },
  headerFrame: {
    textAlign: "right",
    width: 60,
    paddingRight: 5,
  },
  headerFunction: {
    textAlign: "left",
    flex: 1,
  },
  headerFile: {
    flex: 1,
    textAlign: "left",
  },
  headerLineNumber: {
    textAlign: "right",
    width: 60,
  },
  errorMessage: {
    wordBreak: "break-all",
    marginBottom: 30,
    color: Colors.tag,
    paddingLeft: 10,
    paddingTop: 20,
    paddingBottom: 20,
    WebkitUserSelect: "text",
    cursor: "text",
    ...selectionStyle,
  },
  sourceFilename: {
    paddingTop: 5,
    paddingBottom: 5,
    marginBottom: 5,
    color: Colors.tag,
    borderBottom: `1px solid ${Colors.line}`,
  },
  sourceCode: {
    ...AppStyles.Layout.vbox,
    paddingBottom: 10,
  },
  sourceLine: {
    ...AppStyles.Layout.hbox,
    paddingTop: 6,
    paddingBottom: 6,
    cursor: "pointer",
    color: Colors.foregroundDark,
  },
  sourceLineHighlight: {
    opacity: 1,
    ...selectionStyle,
  },
  sourceLineNumber: {
    width: 60,
    paddingRight: 15,
    color: Colors.constant,
    textAlign: "right",
  },
  sourceLineCode: {
    flex: 1,
    whiteSpace: "pre-wrap",
  },
}

@inject("session")
@observer
class LogCommand extends Component {
  static propTypes = {
    command: PropTypes.object.isRequired,
  }

  state = {
    lines: null,
    lineNumber: null,
  }

  constructor(props) {
    super(props)
    this.loadingSource = false
    this.renderStackFrame = this.renderStackFrame.bind(this)
    this.fetchLines = this.fetchLines.bind(this)
    this.renderSource = this.renderSource.bind(this)
    this.fetchLines()
  }

  fetchLines() {
    // prevent-reentry
    if (this.loadingSource) return
    if (!this.state) return
    this.loadingSource = true
    // fetch the top stack frame
    const frame = dotPath("props.command.payload.stack.0", this)
    // jet if we don't have it'
    if (isNilOrEmpty(frame)) return
    const { fileName, lineNumber } = frame
    if (isNilOrEmpty(fileName)) return
    const partialFileName = join("/", takeLast(SOURCE_FILE_PATH_COUNT, split("/", fileName)))

    // kick-off a file read async
    fs.readFile(fileName, "utf-8", (err, data) => {
      // die quietly for we have failed
      if (err) {
        return
      }
      if (data && is(String, data)) {
        try {
          let lines
          let lineCounter = 0
          const lineBreak = /\n/g
          const contents = split(lineBreak, data)

          // create a new structure of lines
          const sourceLines = map(line => {
            lineCounter = lineCounter + 1
            // i am sorry my tab-based brethern.
            const source = replace(/\t/, "  ", line)
            return {
              isSelected: lineCounter === lineNumber,
              lineNumber: lineCounter,
              source,
            }
          }, contents)

          // should just load it all?
          const showWholeFile = contents.length < SOURCE_LINES_UP + SOURCE_LINES_DOWN

          if (showWholeFile) {
            lines = sourceLines
          } else {
            const lo = max(0, lineNumber - SOURCE_LINES_UP - 1)
            const hi = min(contents.length - 1, lineNumber + SOURCE_LINES_UP)
            lines = slice(lo, hi, sourceLines)
          }

          // kick it back to React
          this.setState({ lines, lineNumber, fileName, partialFileName })
        } catch (e) {}
      }
    })
  }

  renderSource() {
    const { lines, fileName, partialFileName } = this.state
    if (isNilOrEmpty(lines)) return null
    const { ui } = this.props.session

    // render a line of code
    const renderLine = line => {
      const { lineNumber, source, isSelected } = line
      const key = `line-${lineNumber}`
      const style = isSelected
        ? merge(Styles.sourceLine, Styles.sourceLineHighlight)
        : Styles.sourceLine
      const onClickStackFrame = e => ui.openInEditor(fileName, lineNumber)

      return (

{lineNumber}

{source}

      )
    }

    return (

{partialFileName}

        {map(renderLine, lines)}

    )
  }

  renderStackFrame(stackFrame, number) {
    const { session } = this.props
    const { ui } = session
    const key = `stack-${number}`
    let { fileName, functionName, lineNumber } = stackFrame
    const justTheFile = last(split("/", fileName))
    fileName = fileName && replace("webpack://", "", fileName)
    functionName = functionName && replace("webpack://", "", functionName)
    const isNodeModule = fileName.indexOf("/node_modules/") >= 0
    const onClickStackFrame = e => ui.openInEditor(fileName, lineNumber)
    const isSelected = number === 1

    let style = isNodeModule ? Styles.stackFrameNodeModule : Styles.stackFrame
    if (isSelected) {
      style = merge(style, Styles.selectedStackFrame)
    }
    const tooltip = fileName
    return (

{functionName || "(anonymous function)"}

          {justTheFile}
          <ReactTooltip place="bottom" class="tooltipThemeReducedWidth" />

{lineNumber}

    )
  }

  renderStack(stack) {
    this.fetchLines()

    let i = 0
    return (

Stack Trace

Function

File

line

          {map(stackFrame => {
            i++
            return this.renderStackFrame(stackFrame, i)
          }, stack)}

    )
  }

  getPreview(message) {
    if (is(String, message)) {
      return take(PREVIEW_LENGTH, message)
    } else if (is(Object, message)) {
      const moreKeys = lt(OBJECT_KEYS_COUNT, length(keys(message)))
      let i = 0
      const previewMessage = moreKeys ? pickBy(() => i++ < OBJECT_KEYS_COUNT, message) : message

      const preview = stringifyObject(previewMessage, {
        transform: (obj, prop, originalResult) => {
          if (is(Object, obj[prop])) {
            return "{...}"
          } else {
            return take(OBJECT_PROPERTY_PREVIEW_LENGTH, originalResult)
          }
        },
      })

      return when(always(moreKeys), replace(/\s\}$/i, ", ...}"))(preview)
    } else if (isNil(message) || is(Boolean, message) || is(Number, message)) {
      return String(message)
    }
    return null
  }

  render() {
    const { command } = this.props
    const { payload } = command
    const { level } = payload
    const { message, stack } = payload
    const title = getName(level)
    const containerTypes = merge(Styles.container, {
      color: level === "debug" ? Colors.foreground : Colors.foreground,
    })
    const hasLines = !!this.state.lines

    let preview = this.getPreview(message)

    return (
      <Command {...this.props} title={title} preview={preview}>

          {!stack && <Content value={message} />}
          {stack &&
{message}
}
          {stack && hasLines && this.renderSource()}
          {stack && this.renderStack(stack)}

      </Command>
    )
  }
}

export default LogCommand
<commit_msg>🐛 prevents crashes when we don't have stack frames with filenames (#666)<commit_after>import fs from "fs"
import { inject, observer } from "mobx-react"
import PropTypes from "prop-types"
import {
  always,
  is,
  isNil,
  join,
  keys,
  last,
  length,
  lt,
  map,
  max,
  merge,
  min,
  pickBy,
  replace,
  slice,
  split,
  take,
  takeLast,
  when,
} from "ramda"
import { dotPath, isNilOrEmpty } from "ramdasauce"
import React, { Component } from "react"
import ReactTooltip from "react-tooltip"
import stringifyObject from "stringify-object"
import Command from "../Shared/Command"
import Content from "../Shared/Content"
import AppStyles from "../Theme/AppStyles"
import Colors from "../Theme/Colors"

const PREVIEW_LENGTH = 500
const SOURCE_LINES_UP = 3
const SOURCE_LINES_DOWN = 3
const SOURCE_FILE_PATH_COUNT = 3
const OBJECT_KEYS_COUNT = 5
const OBJECT_PROPERTY_PREVIEW_LENGTH = 80

const getName = level => {
  switch (level) {
    case "debug":
      return "DEBUG"
    case "warn":
      return "WARNING"
    case "error":
      return "ERROR"
    default:
      return "LOG"
  }
}

const stackFrameBaseStyle = {
  ...AppStyles.Layout.hbox,
  padding: 6,
  wordBreak: "break-all",
  cursor: "pointer",
}

const selectionStyle = {
  color: Colors.tag,
  backgroundColor: Colors.backgroundDarker,
  borderLeft: `1px solid ${Colors.tag}`,
  borderRight: `1px solid ${Colors.subtleLine}`,
  borderTop: `1px solid ${Colors.subtleLine}`,
  borderBottom: `1px solid ${Colors.subtleLine}`,
}

const Styles = {
  container: {
    paddingTop: 4,
  },
  stack: {
    marginTop: 10,
    ...AppStyles.Layout.vbox,
  },
  stackTable: {
    ...AppStyles.Layout.vbox,
  },
  stackFrame: {
    ...stackFrameBaseStyle,
    ...AppStyles.Layout.hbox,
    padding: 6,
  },
  stackFrameNodeModule: {
    ...stackFrameBaseStyle,
    opacity: 0.4,
  },
  selectedStackFrame: {
    ...selectionStyle,
  },
  number: {
    color: Colors.constant,
    textAlign: "right",
    width: 50,
    paddingRight: 10,
    paddingTop: 3,
  },
  functionName: {
    flex: 1,
  },
  fileName: {
    flex: 1,
    wordBreak: "break-all",
  },
  lineNumber: {
    color: Colors.constant,
    wordBreak: "break-all",
    width: 50,
    textAlign: "right",
  },
  stackLabel: {
    color: Colors.foregroundDark,
    margin: "0 7px",
    wordBreak: "break-all",
  },
  stackTitle: {
    color: Colors.constant,
    paddingBottom: 10,
    wordBreak: "break-all",
  },
  theadRow: {
    ...AppStyles.Layout.hbox,
    padding: 6,
    color: Colors.foregroundDark,
  },
  headerFrame: {
    textAlign: "right",
    width: 60,
    paddingRight: 5,
  },
  headerFunction: {
    textAlign: "left",
    flex: 1,
  },
  headerFile: {
    flex: 1,
    textAlign: "left",
  },
  headerLineNumber: {
    textAlign: "right",
    width: 60,
  },
  errorMessage: {
    wordBreak: "break-all",
    marginBottom: 30,
    color: Colors.tag,
    paddingLeft: 10,
    paddingTop: 20,
    paddingBottom: 20,
    WebkitUserSelect: "text",
    cursor: "text",
    ...selectionStyle,
  },
  sourceFilename: {
    paddingTop: 5,
    paddingBottom: 5,
    marginBottom: 5,
    color: Colors.tag,
    borderBottom: `1px solid ${Colors.line}`,
  },
  sourceCode: {
    ...AppStyles.Layout.vbox,
    paddingBottom: 10,
  },
  sourceLine: {
    ...AppStyles.Layout.hbox,
    paddingTop: 6,
    paddingBottom: 6,
    cursor: "pointer",
    color: Colors.foregroundDark,
  },
  sourceLineHighlight: {
    opacity: 1,
    ...selectionStyle,
  },
  sourceLineNumber: {
    width: 60,
    paddingRight: 15,
    color: Colors.constant,
    textAlign: "right",
  },
  sourceLineCode: {
    flex: 1,
    whiteSpace: "pre-wrap",
  },
}

@inject("session")
@observer
class LogCommand extends Component {
  static propTypes = {
    command: PropTypes.object.isRequired,
  }

  state = {
    lines: null,
    lineNumber: null,
  }

  constructor(props) {
    super(props)
    this.loadingSource = false
    this.renderStackFrame = this.renderStackFrame.bind(this)
    this.fetchLines = this.fetchLines.bind(this)
    this.renderSource = this.renderSource.bind(this)
    this.fetchLines()
  }

  fetchLines() {
    // prevent-reentry
    if (this.loadingSource) return
    if (!this.state) return
    this.loadingSource = true
    // fetch the top stack frame
    const frame = dotPath("props.command.payload.stack.0", this)
    // jet if we don't have it'
    if (isNilOrEmpty(frame)) return
    const { fileName, lineNumber } = frame
    if (isNilOrEmpty(fileName)) return
    const partialFileName = join("/", takeLast(SOURCE_FILE_PATH_COUNT, split("/", fileName)))

    // kick-off a file read async
    fs.readFile(fileName, "utf-8", (err, data) => {
      // die quietly for we have failed
      if (err) {
        return
      }
      if (data && is(String, data)) {
        try {
          let lines
          let lineCounter = 0
          const lineBreak = /\n/g
          const contents = split(lineBreak, data)

          // create a new structure of lines
          const sourceLines = map(line => {
            lineCounter = lineCounter + 1
            // i am sorry my tab-based brethern.
            const source = replace(/\t/, "  ", line)
            return {
              isSelected: lineCounter === lineNumber,
              lineNumber: lineCounter,
              source,
            }
          }, contents)

          // should just load it all?
          const showWholeFile = contents.length < SOURCE_LINES_UP + SOURCE_LINES_DOWN

          if (showWholeFile) {
            lines = sourceLines
          } else {
            const lo = max(0, lineNumber - SOURCE_LINES_UP - 1)
            const hi = min(contents.length - 1, lineNumber + SOURCE_LINES_UP)
            lines = slice(lo, hi, sourceLines)
          }

          // kick it back to React
          this.setState({ lines, lineNumber, fileName, partialFileName })
        } catch (e) {}
      }
    })
  }

  renderSource() {
    const { lines, fileName, partialFileName } = this.state
    if (isNilOrEmpty(lines)) return null
    const { ui } = this.props.session

    // render a line of code
    const renderLine = line => {
      const { lineNumber, source, isSelected } = line
      const key = `line-${lineNumber}`
      const style = isSelected
        ? merge(Styles.sourceLine, Styles.sourceLineHighlight)
        : Styles.sourceLine
      const onClickStackFrame = e => ui.openInEditor(fileName, lineNumber)

      return (

{lineNumber}

{source}

      )
    }

    return (

{partialFileName}

        {map(renderLine, lines)}

    )
  }

  renderStackFrame(stackFrame, number) {
    const { session } = this.props
    const { ui } = session
    const key = `stack-${number}`
    let { fileName = "", functionName = "", lineNumber } = stackFrame
    const justTheFile = last(split("/", fileName))
    fileName = fileName && replace("webpack://", "", fileName)
    functionName = functionName && replace("webpack://", "", functionName)
    const isNodeModule = fileName.indexOf("/node_modules/") >= 0
    const onClickStackFrame =
      fileName === "" ? () => true : e => ui.openInEditor(fileName, lineNumber)
    const isSelected = number === 1

    let style = isNodeModule ? Styles.stackFrameNodeModule : Styles.stackFrame
    if (isSelected) {
      style = merge(style, Styles.selectedStackFrame)
    }
    const tooltip = fileName
    return (

{functionName || "(anonymous function)"}

          {justTheFile}
          <ReactTooltip place="bottom" class="tooltipThemeReducedWidth" />

{lineNumber}

    )
  }

  renderStack(stack) {
    this.fetchLines()

    let i = 0
    return (

Stack Trace

Function

File

line

          {map(stackFrame => {
            i++
            return this.renderStackFrame(stackFrame, i)
          }, stack)}

    )
  }

  getPreview(message) {
    if (is(String, message)) {
      return take(PREVIEW_LENGTH, message)
    } else if (is(Object, message)) {
      const moreKeys = lt(OBJECT_KEYS_COUNT, length(keys(message)))
      let i = 0
      const previewMessage = moreKeys ? pickBy(() => i++ < OBJECT_KEYS_COUNT, message) : message

      const preview = stringifyObject(previewMessage, {
        transform: (obj, prop, originalResult) => {
          if (is(Object, obj[prop])) {
            return "{...}"
          } else {
            return take(OBJECT_PROPERTY_PREVIEW_LENGTH, originalResult)
          }
        },
      })

      return when(always(moreKeys), replace(/\s\}$/i, ", ...}"))(preview)
    } else if (isNil(message) || is(Boolean, message) || is(Number, message)) {
      return String(message)
    }
    return null
  }

  render() {
    const { command } = this.props
    const { payload } = command
    const { level } = payload
    const { message, stack } = payload
    const title = getName(level)
    const containerTypes = merge(Styles.container, {
      color: level === "debug" ? Colors.foreground : Colors.foreground,
    })
    const hasLines = !!this.state.lines

    let preview = this.getPreview(message)

    return (
      <Command {...this.props} title={title} preview={preview}>

          {!stack && <Content value={message} />}
          {stack &&
{message}
}
          {stack && hasLines && this.renderSource()}
          {stack && this.renderStack(stack)}

      </Command>
    )
  }
}

export default LogCommand
<|endoftext|>


<commit_before>Monocle.Controls.Spinner = function () {
  if (Monocle.Controls == this) {
    return new Monocle.Controls.Spinner();
  }

  var k = {
    imgURI: "data:image/gif;base64,R0lGODlhGAAYALMAAAAAAJmZmUpKStra2jo6OjM" +
      "zM319fczMzLa2tuvr61FRUSMjI42NjV5eXkJCQv%2F%2F%2FyH5BAEHAA8ALAAAAAAY" +
      "ABgAAAS%2F8MlJq73zGEVKIQozYNRgdF6aGgmJOF54SAMjeM5sHZ2AYIGebjJQFBStz" +
      "PAxaBQcSYlTMKIAAJVBx0D0%2FCpXC8JTNRQEl7DlxpDcAmmsxayQkOOXw9NewFyXEg" +
      "kefBgLAAtRgR8SHYASB1cEiWMOEkZtFwFXDRR0EgxHJAxXmAlsNB1fFwoAnA8BT1UPZ" +
      "lAYCQcjPAWYNDBUJA8HN0gVugJwmTA5eUZnBjoaMEeORCcqKgQMiRg1HB4g2sDiwBEA" +
      "Ow%3D%3D"
  }

  var p = {
    divs: [],
    spinCount: 0
  }

  var API = {
    constructor: Monocle.Controls.Spinner,
    constants: k,
    properties: p
  }

  function initialize() {
  }

  function assignToReader(reader) {
    p.reader = reader;
    if (p.spinCount > 0) {
      p.spinCount -= 1;
      spin();
    }
  }

  function createControlElements() {
    var anim = document.createElement('div');
    anim.style.cssText = Monocle.Styles.ruleText(
      Monocle.Styles.Controls.Spinner.anim
    );
    anim.style.backgroundImage = "url(" + k.imgURI + ")";
    p.divs.push(anim);
    return anim;
  }

  // Registers spin/spun event handlers for: loading, bookchanging, resizing.
  function listenForUsualDelays(listenToElement) {
    if (!listenToElement) {
      if (p.reader) {
        listenToElement = p.reader.properties.divs.box;
      } else {
        throw("No listenToElement or assigned reader.");
      }
    }
    Monocle.addListener(listenToElement, 'monocle:bookchanging', spin);
    Monocle.addListener(listenToElement, 'monocle:bookchange', spun);
    Monocle.addListener(listenToElement, 'monocle:componentloading', spin);
    Monocle.addListener(listenToElement, 'monocle:componentloaded', spun);
    Monocle.addListener(listenToElement, 'monocle:componentchanging', spin);
    Monocle.addListener(listenToElement, 'monocle:componentchange', spun);
    Monocle.addListener(listenToElement, 'monocle:resizing', resizeSpin);
    Monocle.addListener(listenToElement, 'monocle:resize', resizeSpun);
  }

  function resizeSpin(evt) {
    if (p.resizing) {
      return;
    }
    spin(evt);
    p.resizing = true;
  }

  function resizeSpun(evt) {
    spun(evt);
    p.resizing = false;
  }

  function spin(evt) {
    console.log('Spinning on ' + (evt ? evt.type : 'unknown'));
    p.spinCount += 1;
    if (!p.reader) {
      return;
    }
    p.reader.showControl(API);
    var pNode = evt && evt.monocleData.page ? evt.monocleData.page : null;
    for (var i = 0; i < p.divs.length; ++i) {
      p.divs[i].style.display =
        (!pNode || pNode == p.divs[i].parentNode.parentNode) ? 'block' : 'none'
    }
  }

  function spun(evt) {
    console.log('Spun on ' + (evt ? evt.type : 'unknown'));
    p.spinCount -= 1;
    if (p.spinCount > 0 || !p.reader) {
      return;
    }
    p.reader.hideControl(API);
  }

  API.assignToReader = assignToReader;
  API.createControlElements = createControlElements;
  API.listenForUsualDelays = listenForUsualDelays;
  API.spin = spin;
  API.spun = spun;

  initialize();

  return API;
}

Monocle.Styles.Controls.Spinner = {
  anim: {
    "position": "absolute",
    "width": "100%",
    "height": "100%",
    "background-color": "#FFF",
    "background-repeat": "no-repeat",
    "background-position": "center center"
  }
}

Monocle.pieceLoaded('controls/spinner');
<commit_msg>Use the monocle logo for the spinner image.<commit_after>Monocle.Controls.Spinner = function () {
  if (Monocle.Controls == this) {
    return new Monocle.Controls.Spinner();
  }

  var k = {
    imgURI: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAA0CAMAAAANBM47AAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAsSAAALEgHS3X78AAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M1cbXjNgAAABV0RVh0Q3JlYXRpb24gVGltZQAxNy81LzEwnOhoKAAAAE5QTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxKKmWQAAABp0Uk5TAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBl0wLilAAAC8klEQVQYGZXBB2LjOAADQFCimtVFEoD//9HLbrJxipzoZoBToYptUwV8V/Xrsc8RP6i7aduPXHI69mWIAR9UY6Is5rnCuTBsWXeLkijbTFOLf7okW6R8zxEnwphskfIrifJdW4u/RtlpbGLsdjoHfDNkSZTSNg192w3jchSJEtcawCRzDvgjLPINX1SbSSvNXcC7eNuLXpQuTFbp8CZkH/isyS68H0PAF+0iUzxoNni33HPAR51UxDHgRLObslLEw3TPFT7oKPqIeOImURs+WJ0CHlqKXgLOxL4NgyRqxbuqeMNDXURPOBNWSokquRRP+GeVOzwcLlpwJmx3WVJuY2ZRi1ezfOBhdNGGU52ZhrloBzqSucKLerdLxLtIKlc4Nd9LA6wuNTC5aAbQZzs3eFhE9Tg3mw2wqkQgHCZrTJK3iIcoasMTvXX0E30EAK2k+Wbrho8mky2eCLslSz3+2ERKucVHIZsbnqp2WWXEX60ossMnrakeP+jGocabg9SGzyaXHHDRpOIO/zRjDWCTNlzVsLjFm4bODapE33BZoke8mVy8oqXY4rLNXvFmEnXDKJYaly3SjlchkSOwiCngstFMeDXLE4CVygGX3e6FawUgzFIKANbiHHDZ7U4qL7c5SWzxYqFywGXjvVD3F3Zu8ccs5gqXzeYx7CTTWOOvnmTEZZu0ItSxrvAmZrrHZYme8dkhLbiqLkUDPlvMA1cNIiM+613Y4KJNSviiprTgmrrQM75arVzhkllUxFetqBlXVEXa8d0hMeKCxVSH73rRG37XidpxZlXRiN9UhYUtztRFVI+fhUPFE851KlSHn4TNxTueGU2yx3PVbipVeGpxIaeAJ2IynRv8YHEp3iNOjRRdGvxotGjONb7pD7M4RfyiK6ZclhYf1bdDprRW+FW9SZSUlqGtq1BVTTftRaKce1zS7bIpWyW/oK0i38tU4apupWyRsijKVhoj/o+6W45cJEoqaR+bgP8txH5a1nUZ2gq/+Q/51T5MhuG3fQAAAABJRU5ErkJggg=="
  }

  var p = {
    divs: [],
    spinCount: 0
  }

  var API = {
    constructor: Monocle.Controls.Spinner,
    constants: k,
    properties: p
  }

  function initialize() {
  }

  function assignToReader(reader) {
    p.reader = reader;
    if (p.spinCount > 0) {
      p.spinCount -= 1;
      spin();
    }
  }

  function createControlElements() {
    var anim = document.createElement('div');
    anim.style.cssText = Monocle.Styles.ruleText(
      Monocle.Styles.Controls.Spinner.anim
    );
    anim.style.backgroundImage = "url(" + k.imgURI + ")";
    p.divs.push(anim);
    return anim;
  }

  // Registers spin/spun event handlers for: loading, bookchanging, resizing.
  function listenForUsualDelays(listenToElement) {
    if (!listenToElement) {
      if (p.reader) {
        listenToElement = p.reader.properties.divs.box;
      } else {
        throw("No listenToElement or assigned reader.");
      }
    }
    Monocle.addListener(listenToElement, 'monocle:bookchanging', spin);
    Monocle.addListener(listenToElement, 'monocle:bookchange', spun);
    Monocle.addListener(listenToElement, 'monocle:componentloading', spin);
    Monocle.addListener(listenToElement, 'monocle:componentloaded', spun);
    Monocle.addListener(listenToElement, 'monocle:componentchanging', spin);
    Monocle.addListener(listenToElement, 'monocle:componentchange', spun);
    Monocle.addListener(listenToElement, 'monocle:resizing', resizeSpin);
    Monocle.addListener(listenToElement, 'monocle:resize', resizeSpun);
  }

  function resizeSpin(evt) {
    if (p.resizing) {
      return;
    }
    spin(evt);
    p.resizing = true;
  }

  function resizeSpun(evt) {
    spun(evt);
    p.resizing = false;
  }

  function spin(evt) {
    console.log('Spinning on ' + (evt ? evt.type : 'unknown'));
    p.spinCount += 1;
    if (!p.reader) {
      return;
    }
    p.reader.showControl(API);
    var pNode = evt && evt.monocleData.page ? evt.monocleData.page : null;
    for (var i = 0; i < p.divs.length; ++i) {
      p.divs[i].style.display =
        (!pNode || pNode == p.divs[i].parentNode.parentNode) ? 'block' : 'none'
    }
  }

  function spun(evt) {
    console.log('Spun on ' + (evt ? evt.type : 'unknown'));
    p.spinCount -= 1;
    if (p.spinCount > 0 || !p.reader) {
      return;
    }
    p.reader.hideControl(API);
  }

  API.assignToReader = assignToReader;
  API.createControlElements = createControlElements;
  API.listenForUsualDelays = listenForUsualDelays;
  API.spin = spin;
  API.spun = spun;

  initialize();

  return API;
}

Monocle.Styles.Controls.Spinner = {
  anim: {
    "position": "absolute",
    "width": "100%",
    "height": "100%",
    "background-color": "#FFF",
    "background-repeat": "no-repeat",
    "background-position": "center center"
  }
}

Monocle.pieceLoaded('controls/spinner');
<|endoftext|>


<commit_before>var lingcod = (function(){

    var options = {};
    var that = {};

    that.init = function(opts){
        options = opts;
        that.options = opts;

        $('#sidebar').tabs({
            select: function(event, ui){
                if($(this).hasClass('masked')){
                    event.preventDefault();
                }
            }
        });

        var selectedTab = getStore('selectedTab');
        if(selectedTab){
            $('#sidebar').tabs('select', selectedTab);
        };

        resize();

        $('.marinemap-panel').live('click', function(){
            if(!$(this).hasClass('marinemap-menu-items')){
                lingcod.menu_items.closeAll();
            }
        });

        if(window.google){
            google.earth.createInstance(
                "map",
                function(i){
                    geInit(i);
                },
                function(code){
                    geFailure(code);
                });
            setupListeners();
            lingcod.menu_items.init($('.menu_items'));
            // makes button clicking a lot more reliable!!
        }else{
            geFailure();
        }
        $(document).find('a.button').live('dragstart', function(){
            return false;
        });
    };

    var geInit = function(pluginInstance){
        ge = pluginInstance;
        ge.getWindow().setVisibility(true); // required
        ge.getOptions().setStatusBarVisibility(true);
        gex = new GEarthExtensions(ge);

        // that.googleLayers = new lingcod.map.googleLayers(ge,
        //     $('#ge_options'), $('#ge_layers'));
        that.geocoder = new lingcod.map.geocoder(gex, $('#flyToLocation'));
        that.measureTool = new lingcod.measureTool();

        $('#measure_distance').click(function(){
            that.measureTool.clear();
            that.measureTool.measureDistance(gex, "measureAmount");
            $('#measure_clear').removeClass('disabled');
            $('#measureAmountHolder').show();
        });
        $('#measure_area').click(function(){
            that.measureTool.clear();
            that.measureTool.measureArea(gex, "measureAmount");
            $('#measure_clear').removeClass('disabled');
            $('#measureAmountHolder').show();
        });
        $('#measure_clear').click(function(){
            that.measureTool.clear();
            $(this).addClass('disabled');
            $('#measureAmountHolder').hide();
        });
        $('#measure_units').change(function(){
            that.measureTool.setUnits($(this).val());
        });

        $('#datalayerstree').append('

');

        var studyRegion = lingcod.kmlTree({
            url: window.studyregion,
            ge: ge,
            gex: gex,
            animate: false,
            map_div: $('#map'),
            element: $('#study_region'),
            trans: options.media_url + 'common/images/transparent.gif',
            title: true,
            restoreState: true
        });
        if(!setCameraFromLocalStorage()){
            $(studyRegion).bind('kmlLoaded', function(){
                $('#study_region').find('li').dblclick();
            });
        }
        studyRegion.load();

        var publicData = lingcod.kmlTree({
            url: window.public_data_layers,
            ge: ge,
            gex: gex,
            animate: false,
            map_div: $('#map'),
            element: $('#public_data'),
            trans: options.media_url + 'common/images/transparent.gif',
            title: true,
            restoreState: true
        });
        publicData.load();

        var googleLayers = lingcod.kmlTree({
            url: options.media_url + 'common/fixtures/earthLayers.kml',
            ge: ge,
            gex: gex,
            animate: false,
            map_div: $('#map'),
            element: $('#googlelayers'),
            trans: options.media_url + 'common/images/transparent.gif',
            title: true,
            restoreState: true,
            supportItemIcon: true,
            fireEvents: function(){
                return true;
            }
        });

        var updateGoogleLayers = function(tree){
            $('#googlelayers li').each(function(){
                var item = $(this);
                var name = item.find('span.name').text();
                switch(name){
                    case 'Grid':
                        ge.getOptions().setGridVisibility(item.hasClass('visible'));
                        break;
                    case '3d Buildings':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS, item.hasClass('visible'));
                        break;
                    case 'Grey 3d Buildings':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS_LOW_RESOLUTION, item.hasClass('visible'));
                        break;
                    case 'Roads':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, item.hasClass('visible'));
                        break;
                    case 'Borders and Labels':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, item.hasClass('visible'));
                        break;
                }
            });
        }

        $(googleLayers).bind('kmlLoaded', function(){
            updateGoogleLayers(googleLayers);
        });

        $(googleLayers).bind('toggleItem', function(){
            updateGoogleLayers(googleLayers);
        });

        googleLayers.load();

        var panel = lingcod.panel({appendTo: $('#panel-holder'),
            showCloseButton: false});

        that.client = lingcod.rest.client(gex, panel);

        if(typeof options.form_shown === 'function'){
            $(that.client).bind('form_shown', options.form_shown);
        }

        if(options.ecotrust){
            var ecotrustData = lingcod.kmlTree({
                url: options.ecotrust,
                ge: ge,
                gex: gex,
                animate: false,
                map_div: $('#map'),
                element: $('#ecotrust_data'),
                trans: options.media_url + 'common/images/transparent.gif',
                title: true,
                restoreState: true
            });
            ecotrustData.load();
        }

        var editors = [];

        if(options.myshapes){
            for(var i=0;i<options.myshapes.length; i++){
                var url = options.myshapes[i].url;
                var callback = options.myshapes[i]['callback'];
                var editor = lingcod.rest.kmlEditor({
                    ge: ge,
                    gex: gex,
                    appendTo: '#myshapestree',
                    div: '#map',
                    url: options.myshapes[i].url,
                    client: that.client,
                    shared: false,
                    allow_copy: options.allow_copy
                });
                if(callback){
                    $(editor).bind('kmlLoaded', function(event, original_event, kmlObject){
                        console.log(this, this.el, kmlObject);
                        callback(this, this.el, kmlObject)
                    });
                }
                $(editor.tree).bind('copyDone', function(e,location) {
                    this.refresh();
                    this.clearSelection();
                    var node = this.getNodesById(location);
                    if(node.length === 1) {
                        this.selectNode(node, this.lookup(node));
                    } else {
                        alert("No node found with Id " + location);
                    }
                });
                editors.push(editor);
            }
        }

        $('a.myshapes-link').live('click', function(e){
            e.preventDefault();
            $('.marinemap-panel:visible a.close').click();
            var href = $(this).attr('href');
            for(var i=0;i<editors.length;i++){
                var editor = editors[0];
                var nodes = editor.tree.getNodesById(href);
                if(nodes.length === 1){
                    editor.tree.selectNode(nodes);
                    nodes.trigger('dblclick');
                    return false;
                }
            }
            return false;
        });

        that.editors = editors;

        if(options.sharedshapes){
            for(var i=0;i<options.sharedshapes.length; i++){
                var editor = lingcod.rest.kmlEditor({
                    ge: ge,
                    gex: gex,
                    appendTo: '#sharedshapestree',
                    div: '#map',
                    url: options.sharedshapes[i],
                    client: that.client,
                    shared: true,
                    allow_copy: options.allow_copy
                });
                $(editor.tree).bind('copyDone', function(e, location) {
                    var myshapesEditor = that.editors[0];
                    myshapesEditor.tree.refresh();
                    myshapesEditor.tree.clearSelection();
                    var node = myshapesEditor.tree.getNodesById(location);
                    if(node.length === 1) {
                        myshapesEditor.tree.selectNode(node); //, this.lookup(node));
                    } else {
                        alert("No node found with Id " + location);
                    }

                    // MP TODO switch to myshapes panel
                });
                editors.push(editor);
            }
        }

        $('#sidebar, #meta-navigation').click(function(e){
            if(e.target === this || e.target === $('#MyShapes')[0]){
                for(var i=0;i<editors.length;i++){
                    editors[i].clearSelection();
                }
            }
        });

        $('#news').click(function(e){
            opts = {};
            opts['load_msg'] = 'Loading News';
            opts['showClose'] = true;
            panel.showUrl(that.options.news_url, opts);
            e.preventDefault();
        });

        $('#about').click(function(e){
            opts = {};
            opts['load_msg'] = 'Loading Intro';
            opts['showClose'] = true;
            panel.showUrl(that.options.about_url, opts);
            e.preventDefault();
        });

        if (options.show_panel){
            opts = {};
            opts['showClose'] = true;
            if (options.show_panel == 'about') {
                panel.showUrl(that.options.about_url, opts);
            } else if (options.show_panel == 'news') {
                panel.showUrl(that.options.news_url, opts);
            }
        }

        var url = that.options.media_url + 'common/kml/shadow.kmz';
        google.earth.fetchKml(ge, url, function(k){
            ge.getFeatures().appendChild(k);
        });

        var setEarthOptions = function(){
            $('#earthOptions li').each(function(){
                var li = $(this);
                switch(li.attr('id')){
                    case 'nav':
                        if(li.hasClass('visible')){
                            ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
                        }else{
                            ge.getNavigationControl().setVisibility(ge.VISIBILITY_HIDE);
                        }
                        break;
                    case 'overview':
                        ge.getOptions().setOverviewMapVisibility(li.hasClass('visible'));
                        break;
                    case 'scale':
                        ge.getOptions().setScaleLegendVisibility(li.hasClass('visible'));
                        break;
                    case 'atm':
                        ge.getOptions().setAtmosphereVisibility(li.hasClass('visible'));
                        break;
                    case 'terrain':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_TERRAIN, li.hasClass('visible'));
                        break;
                }
            });
        }

        $('#earthOptions li').click(function(e){
            $(this).toggleClass('visible');
            setEarthOptions();
        });

        setEarthOptionsFromLocalStore();
        setEarthOptions();

        var unload = function(){
            setCameraToLocalStorage();
            saveEarthOptionsToLocalStore();
            setStore('selectedTab', $('#sidebar > ul > .ui-tabs-selected a').attr('href'));
            $(window).die('beforunload', unload);
        }

        $(window).bind('beforeunload', unload);
    };

    var studyRegionLoaded = function(kmlObject, node){
        // Reorder so studyRegion is on top of the list
        $('#datalayerstree').prepend(node);
        if (kmlObject.getAbstractView()){
            ge.getView().setAbstractView(kmlObject.getAbstractView());
        }
    };

    var setStore = function(key, value){
        if(!!window.localStorage){
            localStorage.setItem(key, value);
        }
    };

    var getStore = function(key){
        if(!!window.localStorage){
            return localStorage.getItem(key);
        }else{
            return false;
        }
    }

    var setEarthOptionsFromLocalStore = function(){
        if(!!window.localStorage && localStorage.getItem('earthOptions')){
            var json = JSON.parse(localStorage.getItem('earthOptions'));
            for(key in json){
                $('#earthOptions').find('#'+key).toggleClass('visible', json[key]);
            }
        }else{
            return false;
        }
    };

    var saveEarthOptionsToLocalStore = function(){
        if(!!window.localStorage){
            var json = {};
            $('#earthOptions li').each(function(){
                json[$(this).attr('id')] = $(this).hasClass('visible');
            });
            localStorage.setItem('earthOptions', JSON.stringify(json));
        }
    };

    var geFailure = function(errorCode){
        // alert("Failure loading the Google Earth Plugin: " + errorCode);
    }

    var setupListeners = function(){
        $(window).smartresize(function(){
            resize();
        });
        $('#meta-navigation').click(function(){
            lingcod.menu_items.closeAll();
        });
        $('#sidebar').bind('mouseup', function(e){
            lingcod.menu_items.closeAll();
            // return false;
        });
        $('#sidebar-mask').click(function(){
            lingcod.menu_items.closeAll();
        });
        $('#panel-holder').click(function(e){
            if(e.originalTarget === this){
                lingcod.menu_items.closeAll();
            }
        });
    };

    var resize = function(){
        var mh = $('#meta-navigation').outerHeight();
        var h = $(document.body).height() - mh;
        $('#sidebar').css({top: mh, height: h});
        $('#panel-holder').css({top: mh, height: h});

        var w = $(document.body).width() - $('#sidebar').width();
        $('#map_container').height(h).width(w);
    };

    that.maskSidebar = function(){
        $('#panel-holder').show();
        $('#sidebar').addClass('masked');
    };

    that.unmaskSidebar = function(){
        $('#panel-holder').hide();
        $('#sidebar').removeClass('masked');
    };

    that.showLoadingMask = function(msg){
        var msg = msg || 'Loading';
        var lmsg = $('#sidebar-mask').find('span.loadingMsg');
        lmsg.text(msg);
        lmsg.show();
        lingcod.menu_items.disable();
        $('#sidebar').addClass('masked');
    };

    that.hideLoadingMask = function(){
        $('#sidebar-mask').find('span.loadingMsg').hide();
        lingcod.menu_items.enable();
        that.unmaskSidebar();
    }

    var panels = [];

    that.addPanel = function(panel){
        panels.push(panel);
        $(panel).bind('panelshow', onPanelShown);
        $(panel).bind('panelhide', onPanelHide);
        $(panel).bind('panelclose', onPanelHide);
    },

    that.removePanel = function(panel){
        panels.remove(panel);
        $(panel).unbind('panelshow', onPanelShown);
        $(panel).unbind('panelhide', onPanelHide);
        $(panel).unbind('panelclose', onPanelHide);
    };

    var onPanelShown = function(e, panel){
        that.maskSidebar();
    };

    var onPanelHide = function(e, panel){
        var count = 0;
        for(var i=0; i<panels.length; i++){
            var p = panels[i];
            if(p.shown){
                count++;
            }
        }
        if(count <= 0){
            that.unmaskSidebar();
        }
    };

    var setCameraToLocalStorage = function(){
        if(!!window.localStorage){
            localStorage.setItem('marinemap-camera', gex.view.serialize());
        }
    };

    var setCameraFromLocalStorage = function(){
        if(!!window.localStorage && localStorage.getItem('marinemap-camera')){
            gex.view.deserialize(localStorage.getItem('marinemap-camera'));
            return true;
        }
        return false;
    };

    var whenLoaded = function(selector, callback){
        var el = $(selector+':visible');
        if(el.length){
            callback(el);
        }else{
            setTimeout(whenLoaded, 100, selector, callback);
        }
    };

    that.whenLoaded = whenLoaded;

    return that;
})();<commit_msg>removing console.log statement<commit_after>var lingcod = (function(){

    var options = {};
    var that = {};

    that.init = function(opts){
        options = opts;
        that.options = opts;

        $('#sidebar').tabs({
            select: function(event, ui){
                if($(this).hasClass('masked')){
                    event.preventDefault();
                }
            }
        });

        var selectedTab = getStore('selectedTab');
        if(selectedTab){
            $('#sidebar').tabs('select', selectedTab);
        };

        resize();

        $('.marinemap-panel').live('click', function(){
            if(!$(this).hasClass('marinemap-menu-items')){
                lingcod.menu_items.closeAll();
            }
        });

        if(window.google){
            google.earth.createInstance(
                "map",
                function(i){
                    geInit(i);
                },
                function(code){
                    geFailure(code);
                });
            setupListeners();
            lingcod.menu_items.init($('.menu_items'));
            // makes button clicking a lot more reliable!!
        }else{
            geFailure();
        }
        $(document).find('a.button').live('dragstart', function(){
            return false;
        });
    };

    var geInit = function(pluginInstance){
        ge = pluginInstance;
        ge.getWindow().setVisibility(true); // required
        ge.getOptions().setStatusBarVisibility(true);
        gex = new GEarthExtensions(ge);

        // that.googleLayers = new lingcod.map.googleLayers(ge,
        //     $('#ge_options'), $('#ge_layers'));
        that.geocoder = new lingcod.map.geocoder(gex, $('#flyToLocation'));
        that.measureTool = new lingcod.measureTool();

        $('#measure_distance').click(function(){
            that.measureTool.clear();
            that.measureTool.measureDistance(gex, "measureAmount");
            $('#measure_clear').removeClass('disabled');
            $('#measureAmountHolder').show();
        });
        $('#measure_area').click(function(){
            that.measureTool.clear();
            that.measureTool.measureArea(gex, "measureAmount");
            $('#measure_clear').removeClass('disabled');
            $('#measureAmountHolder').show();
        });
        $('#measure_clear').click(function(){
            that.measureTool.clear();
            $(this).addClass('disabled');
            $('#measureAmountHolder').hide();
        });
        $('#measure_units').change(function(){
            that.measureTool.setUnits($(this).val());
        });

        $('#datalayerstree').append('

');

        var studyRegion = lingcod.kmlTree({
            url: window.studyregion,
            ge: ge,
            gex: gex,
            animate: false,
            map_div: $('#map'),
            element: $('#study_region'),
            trans: options.media_url + 'common/images/transparent.gif',
            title: true,
            restoreState: true
        });
        if(!setCameraFromLocalStorage()){
            $(studyRegion).bind('kmlLoaded', function(){
                $('#study_region').find('li').dblclick();
            });
        }
        studyRegion.load();

        var publicData = lingcod.kmlTree({
            url: window.public_data_layers,
            ge: ge,
            gex: gex,
            animate: false,
            map_div: $('#map'),
            element: $('#public_data'),
            trans: options.media_url + 'common/images/transparent.gif',
            title: true,
            restoreState: true
        });
        publicData.load();

        var googleLayers = lingcod.kmlTree({
            url: options.media_url + 'common/fixtures/earthLayers.kml',
            ge: ge,
            gex: gex,
            animate: false,
            map_div: $('#map'),
            element: $('#googlelayers'),
            trans: options.media_url + 'common/images/transparent.gif',
            title: true,
            restoreState: true,
            supportItemIcon: true,
            fireEvents: function(){
                return true;
            }
        });

        var updateGoogleLayers = function(tree){
            $('#googlelayers li').each(function(){
                var item = $(this);
                var name = item.find('span.name').text();
                switch(name){
                    case 'Grid':
                        ge.getOptions().setGridVisibility(item.hasClass('visible'));
                        break;
                    case '3d Buildings':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS, item.hasClass('visible'));
                        break;
                    case 'Grey 3d Buildings':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS_LOW_RESOLUTION, item.hasClass('visible'));
                        break;
                    case 'Roads':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, item.hasClass('visible'));
                        break;
                    case 'Borders and Labels':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, item.hasClass('visible'));
                        break;
                }
            });
        }

        $(googleLayers).bind('kmlLoaded', function(){
            updateGoogleLayers(googleLayers);
        });

        $(googleLayers).bind('toggleItem', function(){
            updateGoogleLayers(googleLayers);
        });

        googleLayers.load();

        var panel = lingcod.panel({appendTo: $('#panel-holder'),
            showCloseButton: false});

        that.client = lingcod.rest.client(gex, panel);

        if(typeof options.form_shown === 'function'){
            $(that.client).bind('form_shown', options.form_shown);
        }

        if(options.ecotrust){
            var ecotrustData = lingcod.kmlTree({
                url: options.ecotrust,
                ge: ge,
                gex: gex,
                animate: false,
                map_div: $('#map'),
                element: $('#ecotrust_data'),
                trans: options.media_url + 'common/images/transparent.gif',
                title: true,
                restoreState: true
            });
            ecotrustData.load();
        }

        var editors = [];

        if(options.myshapes){
            for(var i=0;i<options.myshapes.length; i++){
                var url = options.myshapes[i].url;
                var callback = options.myshapes[i]['callback'];
                var editor = lingcod.rest.kmlEditor({
                    ge: ge,
                    gex: gex,
                    appendTo: '#myshapestree',
                    div: '#map',
                    url: options.myshapes[i].url,
                    client: that.client,
                    shared: false,
                    allow_copy: options.allow_copy
                });
                if(callback){
                    $(editor).bind('kmlLoaded', function(event, original_event, kmlObject){
                        callback(this, this.el, kmlObject)
                    });
                }
                $(editor.tree).bind('copyDone', function(e,location) {
                    this.refresh();
                    this.clearSelection();
                    var node = this.getNodesById(location);
                    if(node.length === 1) {
                        this.selectNode(node, this.lookup(node));
                    } else {
                        alert("No node found with Id " + location);
                    }
                });
                editors.push(editor);
            }
        }

        $('a.myshapes-link').live('click', function(e){
            e.preventDefault();
            $('.marinemap-panel:visible a.close').click();
            var href = $(this).attr('href');
            for(var i=0;i<editors.length;i++){
                var editor = editors[0];
                var nodes = editor.tree.getNodesById(href);
                if(nodes.length === 1){
                    editor.tree.selectNode(nodes);
                    nodes.trigger('dblclick');
                    return false;
                }
            }
            return false;
        });

        that.editors = editors;

        if(options.sharedshapes){
            for(var i=0;i<options.sharedshapes.length; i++){
                var editor = lingcod.rest.kmlEditor({
                    ge: ge,
                    gex: gex,
                    appendTo: '#sharedshapestree',
                    div: '#map',
                    url: options.sharedshapes[i],
                    client: that.client,
                    shared: true,
                    allow_copy: options.allow_copy
                });
                $(editor.tree).bind('copyDone', function(e, location) {
                    var myshapesEditor = that.editors[0];
                    myshapesEditor.tree.refresh();
                    myshapesEditor.tree.clearSelection();
                    var node = myshapesEditor.tree.getNodesById(location);
                    if(node.length === 1) {
                        myshapesEditor.tree.selectNode(node); //, this.lookup(node));
                    } else {
                        alert("No node found with Id " + location);
                    }

                    // MP TODO switch to myshapes panel
                });
                editors.push(editor);
            }
        }

        $('#sidebar, #meta-navigation').click(function(e){
            if(e.target === this || e.target === $('#MyShapes')[0]){
                for(var i=0;i<editors.length;i++){
                    editors[i].clearSelection();
                }
            }
        });

        $('#news').click(function(e){
            opts = {};
            opts['load_msg'] = 'Loading News';
            opts['showClose'] = true;
            panel.showUrl(that.options.news_url, opts);
            e.preventDefault();
        });

        $('#about').click(function(e){
            opts = {};
            opts['load_msg'] = 'Loading Intro';
            opts['showClose'] = true;
            panel.showUrl(that.options.about_url, opts);
            e.preventDefault();
        });

        if (options.show_panel){
            opts = {};
            opts['showClose'] = true;
            if (options.show_panel == 'about') {
                panel.showUrl(that.options.about_url, opts);
            } else if (options.show_panel == 'news') {
                panel.showUrl(that.options.news_url, opts);
            }
        }

        var url = that.options.media_url + 'common/kml/shadow.kmz';
        google.earth.fetchKml(ge, url, function(k){
            ge.getFeatures().appendChild(k);
        });

        var setEarthOptions = function(){
            $('#earthOptions li').each(function(){
                var li = $(this);
                switch(li.attr('id')){
                    case 'nav':
                        if(li.hasClass('visible')){
                            ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
                        }else{
                            ge.getNavigationControl().setVisibility(ge.VISIBILITY_HIDE);
                        }
                        break;
                    case 'overview':
                        ge.getOptions().setOverviewMapVisibility(li.hasClass('visible'));
                        break;
                    case 'scale':
                        ge.getOptions().setScaleLegendVisibility(li.hasClass('visible'));
                        break;
                    case 'atm':
                        ge.getOptions().setAtmosphereVisibility(li.hasClass('visible'));
                        break;
                    case 'terrain':
                        ge.getLayerRoot().enableLayerById(ge.LAYER_TERRAIN, li.hasClass('visible'));
                        break;
                }
            });
        }

        $('#earthOptions li').click(function(e){
            $(this).toggleClass('visible');
            setEarthOptions();
        });

        setEarthOptionsFromLocalStore();
        setEarthOptions();

        var unload = function(){
            setCameraToLocalStorage();
            saveEarthOptionsToLocalStore();
            setStore('selectedTab', $('#sidebar > ul > .ui-tabs-selected a').attr('href'));
            $(window).die('beforunload', unload);
        }

        $(window).bind('beforeunload', unload);
    };

    var studyRegionLoaded = function(kmlObject, node){
        // Reorder so studyRegion is on top of the list
        $('#datalayerstree').prepend(node);
        if (kmlObject.getAbstractView()){
            ge.getView().setAbstractView(kmlObject.getAbstractView());
        }
    };

    var setStore = function(key, value){
        if(!!window.localStorage){
            localStorage.setItem(key, value);
        }
    };

    var getStore = function(key){
        if(!!window.localStorage){
            return localStorage.getItem(key);
        }else{
            return false;
        }
    }

    var setEarthOptionsFromLocalStore = function(){
        if(!!window.localStorage && localStorage.getItem('earthOptions')){
            var json = JSON.parse(localStorage.getItem('earthOptions'));
            for(key in json){
                $('#earthOptions').find('#'+key).toggleClass('visible', json[key]);
            }
        }else{
            return false;
        }
    };

    var saveEarthOptionsToLocalStore = function(){
        if(!!window.localStorage){
            var json = {};
            $('#earthOptions li').each(function(){
                json[$(this).attr('id')] = $(this).hasClass('visible');
            });
            localStorage.setItem('earthOptions', JSON.stringify(json));
        }
    };

    var geFailure = function(errorCode){
        // alert("Failure loading the Google Earth Plugin: " + errorCode);
    }

    var setupListeners = function(){
        $(window).smartresize(function(){
            resize();
        });
        $('#meta-navigation').click(function(){
            lingcod.menu_items.closeAll();
        });
        $('#sidebar').bind('mouseup', function(e){
            lingcod.menu_items.closeAll();
            // return false;
        });
        $('#sidebar-mask').click(function(){
            lingcod.menu_items.closeAll();
        });
        $('#panel-holder').click(function(e){
            if(e.originalTarget === this){
                lingcod.menu_items.closeAll();
            }
        });
    };

    var resize = function(){
        var mh = $('#meta-navigation').outerHeight();
        var h = $(document.body).height() - mh;
        $('#sidebar').css({top: mh, height: h});
        $('#panel-holder').css({top: mh, height: h});

        var w = $(document.body).width() - $('#sidebar').width();
        $('#map_container').height(h).width(w);
    };

    that.maskSidebar = function(){
        $('#panel-holder').show();
        $('#sidebar').addClass('masked');
    };

    that.unmaskSidebar = function(){
        $('#panel-holder').hide();
        $('#sidebar').removeClass('masked');
    };

    that.showLoadingMask = function(msg){
        var msg = msg || 'Loading';
        var lmsg = $('#sidebar-mask').find('span.loadingMsg');
        lmsg.text(msg);
        lmsg.show();
        lingcod.menu_items.disable();
        $('#sidebar').addClass('masked');
    };

    that.hideLoadingMask = function(){
        $('#sidebar-mask').find('span.loadingMsg').hide();
        lingcod.menu_items.enable();
        that.unmaskSidebar();
    }

    var panels = [];

    that.addPanel = function(panel){
        panels.push(panel);
        $(panel).bind('panelshow', onPanelShown);
        $(panel).bind('panelhide', onPanelHide);
        $(panel).bind('panelclose', onPanelHide);
    },

    that.removePanel = function(panel){
        panels.remove(panel);
        $(panel).unbind('panelshow', onPanelShown);
        $(panel).unbind('panelhide', onPanelHide);
        $(panel).unbind('panelclose', onPanelHide);
    };

    var onPanelShown = function(e, panel){
        that.maskSidebar();
    };

    var onPanelHide = function(e, panel){
        var count = 0;
        for(var i=0; i<panels.length; i++){
            var p = panels[i];
            if(p.shown){
                count++;
            }
        }
        if(count <= 0){
            that.unmaskSidebar();
        }
    };

    var setCameraToLocalStorage = function(){
        if(!!window.localStorage){
            localStorage.setItem('marinemap-camera', gex.view.serialize());
        }
    };

    var setCameraFromLocalStorage = function(){
        if(!!window.localStorage && localStorage.getItem('marinemap-camera')){
            gex.view.deserialize(localStorage.getItem('marinemap-camera'));
            return true;
        }
        return false;
    };

    var whenLoaded = function(selector, callback){
        var el = $(selector+':visible');
        if(el.length){
            callback(el);
        }else{
            setTimeout(whenLoaded, 100, selector, callback);
        }
    };

    that.whenLoaded = whenLoaded;

    return that;
})();<|endoftext|>


<commit_before>/**
 * VclController
 *
 * @description :: Server-side logic for managing vcls
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */
var child_process = require('child_process');
var fs = require('fs');
var path = require('path');
var temp = require('temp');
var url = require('url');

function completeRun(err, fiddle, allRequests) {

  var completedData = { completedAt: new Date() };

  function writeCompletedData(err) {
    if (err instanceof Error) {
      completedData.error = err.message;
    } else if (err) {
      completedData.error = err.toString();
    }
    fs.writeFile(path.join(fiddle.path, 'completed'), JSON.stringify(completedData), { encoding: 'utf8' }, function (err) {
      if (err) sails.log.error(err);
    });
  }

  if (err) {
    sails.log.error('Run container error: ' + err);
    return writeCompletedData(err);
  }

  ContainerService.readOutputFiles(fiddle.path, function (err, output) {
    if (err) return writeCompletedData(err);
    if (output.runlog.length > 0) return writeCompletedData('Error: ' + output.runlog);

    var parsedNcsa = RequestMetadataService.parseVarnish4NCSA(output.varnishncsa);

    var results = RequestMetadataService.correlateResults(allRequests.includedRequests, output.responses, parsedNcsa, null);
    results = results.concat(allRequests.excludedRequests.map(function (r) { return { request: r }; }));

    completedData.log = output.varnishlog;
    completedData.results = results;
    writeCompletedData();
  });

}

module.exports = {
	index: function (req, res) {
    const defaultVcl = 'vcl 4.0; backend default { .host = "www.vclfiddle.net"; .port = "80"; }';
    const defaultHar = "curl http://www.vclfiddle.net --header 'User-Agent: vclFiddle'";

    var fiddleid = req.params.fiddleid || '';
    var runindex = req.params.runindex || '0';

    if (!fiddleid) {
      return res.view({
        fiddleid: '',
        vcl: defaultVcl,
        har: defaultHar,
        log: ''
      });
    }

    FiddlePersistenceService.getFiddleRun(fiddleid, runindex, function (err, fiddle) {

      if (err) return res.serverError(err);

      if (fiddle === null) return res.notFound();

      FiddlePersistenceService.loadViewState(fiddle, function (err, viewState) {
        if (err) return res.serverError(err);

        return res.view({
          fiddleid: fiddle.id,
          vcl: viewState.vcl,
          har: viewState.har,
          log: viewState.log,
          results: viewState.results
        })

      });

    });

  },

  result: function (req, res) {
    var fiddleid = req.query.fiddleid || '';
    var runindex = req.query.runindex || '0';
    if (!fiddleid) return res.badRequest();

    FiddlePersistenceService.getFiddleRun(fiddleid, runindex, function (err, fiddle) {

      if (err) return res.serverError(err);

      if (fiddle === null) return res.notFound();

      ContainerService.getReplayResult(fiddle.path, function (err, completedData) {
        if (err) return res.serverError(err);

        if (!completedData.completedAt) {
          // not complete yet
          // TODO timeout if too long to complete
          // TODO instruct client to cache only briefly if at all
          return res.ok({});
        }

        FiddlePersistenceService.loadViewState(fiddle, function (err, viewState) {
          if (err) return res.serverError(err);

          viewState.log = completedData.error || completedData.log,
          viewState.results = completedData.results

          FiddlePersistenceService.saveViewState(fiddle, viewState, function (err) {
            if (err) return res.serverError(err);

            return res.ok({
              log: viewState.log,
              results: viewState.results
            });

          });
        });
      });

    });
  },

  run: function (req, res) {
    var fiddleid = req.body.fiddleid || '';
    var vcl = req.body.vcl;
    var rawRequests = req.body.har;
    var dockerImage = req.body.image || 'varnish4';

    const supportedImages = ['varnish4', 'varnish3', 'varnish2'];
    if (supportedImages.indexOf(dockerImage) < 0) {
      sails.log.warn('Invalid image parameter:' + dockerImage);
      return res.badRequest();
    }

    if (typeof vcl !== 'string' || typeof rawRequests !== 'string') return res.badRequest();

    RequestMetadataService.parseInputRequests(rawRequests, function (err, _ignored, allRequests) {

      if (err) {
        return res.ok({
          fiddleid: fiddleid,
          vcl: vcl,
          har: rawRequests,
          log: err.toString()
        }, 'vcl/index');
      }

      if (allRequests.includedRequests.length == 0) {
        return res.ok({
          fiddleid: fiddleid,
          vcl: vcl,
          har: rawRequests,
          log: 'HAR does not contain any supported requests.'
        }, 'vcl/index');
      }

      if (!!req.body.dbl) {
        allRequests.includedRequests = allRequests.includedRequests.concat(allRequests.includedRequests);
      }

      FiddlePersistenceService.prepareFiddle(fiddleid, function (err, fiddle) {
        if (err) return res.serverError(err);

        // TODO persist state of 'replay requests twice' option

        ContainerService.beginReplay(fiddle.path, allRequests.includedRequests, vcl, dockerImage, function (err) {
          // started

          var viewState = {
            image: dockerImage,
            vcl: vcl,
            har: rawRequests
          };
          if (err) {
            viewState.log = 'Error: ' + err;
          }

          FiddlePersistenceService.saveViewState(fiddle, viewState, function (err) {
            if (err) return res.serverError(err);

            return res.ok({
              fiddleid: fiddle.id,
              runindex: fiddle.runIndex,
              vcl: viewState.vcl,
              har: viewState.har,
              log: viewState.log
            });

          });

        }, function (err) {
          // completed
          return completeRun(err, fiddle, allRequests);
        });

      });

    });

  }

};

<commit_msg>Set the default varnish version<commit_after>/**
 * VclController
 *
 * @description :: Server-side logic for managing vcls
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */
var child_process = require('child_process');
var fs = require('fs');
var path = require('path');
var temp = require('temp');
var url = require('url');

function completeRun(err, fiddle, allRequests) {

  var completedData = { completedAt: new Date() };

  function writeCompletedData(err) {
    if (err instanceof Error) {
      completedData.error = err.message;
    } else if (err) {
      completedData.error = err.toString();
    }
    fs.writeFile(path.join(fiddle.path, 'completed'), JSON.stringify(completedData), { encoding: 'utf8' }, function (err) {
      if (err) sails.log.error(err);
    });
  }

  if (err) {
    sails.log.error('Run container error: ' + err);
    return writeCompletedData(err);
  }

  ContainerService.readOutputFiles(fiddle.path, function (err, output) {
    if (err) return writeCompletedData(err);
    if (output.runlog.length > 0) return writeCompletedData('Error: ' + output.runlog);

    var parsedNcsa = RequestMetadataService.parseVarnish4NCSA(output.varnishncsa);

    var results = RequestMetadataService.correlateResults(allRequests.includedRequests, output.responses, parsedNcsa, null);
    results = results.concat(allRequests.excludedRequests.map(function (r) { return { request: r }; }));

    completedData.log = output.varnishlog;
    completedData.results = results;
    writeCompletedData();
  });

}

module.exports = {
	index: function (req, res) {
    const defaultVcl = 'vcl 4.0; backend default { .host = "www.vclfiddle.net"; .port = "80"; }';
    const defaultHar = "curl http://www.vclfiddle.net --header 'User-Agent: vclFiddle'";
    const defaultImage = 'varnish4';

    var fiddleid = req.params.fiddleid || '';
    var runindex = req.params.runindex || '0';

    if (!fiddleid) {
      return res.view({
        fiddleid: '',
        vcl: defaultVcl,
        har: defaultHar,
        log: ''
      });
    }

    FiddlePersistenceService.getFiddleRun(fiddleid, runindex, function (err, fiddle) {

      if (err) return res.serverError(err);

      if (fiddle === null) return res.notFound();

      FiddlePersistenceService.loadViewState(fiddle, function (err, viewState) {
        if (err) return res.serverError(err);

        return res.view({
          fiddleid: fiddle.id,
          vcl: viewState.vcl,
          har: viewState.har,
          log: viewState.log,
          results: viewState.results
        })

      });

    });

  },

  result: function (req, res) {
    var fiddleid = req.query.fiddleid || '';
    var runindex = req.query.runindex || '0';
    if (!fiddleid) return res.badRequest();

    FiddlePersistenceService.getFiddleRun(fiddleid, runindex, function (err, fiddle) {

      if (err) return res.serverError(err);

      if (fiddle === null) return res.notFound();

      ContainerService.getReplayResult(fiddle.path, function (err, completedData) {
        if (err) return res.serverError(err);

        if (!completedData.completedAt) {
          // not complete yet
          // TODO timeout if too long to complete
          // TODO instruct client to cache only briefly if at all
          return res.ok({});
        }

        FiddlePersistenceService.loadViewState(fiddle, function (err, viewState) {
          if (err) return res.serverError(err);

          viewState.log = completedData.error || completedData.log,
          viewState.results = completedData.results

          FiddlePersistenceService.saveViewState(fiddle, viewState, function (err) {
            if (err) return res.serverError(err);

            return res.ok({
              log: viewState.log,
              results: viewState.results
            });

          });
        });
      });

    });
  },

  run: function (req, res) {
    var fiddleid = req.body.fiddleid || '';
    var vcl = req.body.vcl;
    var rawRequests = req.body.har;
    var dockerImage = req.body.image || 'varnish4';

    const supportedImages = ['varnish4', 'varnish3', 'varnish2'];
    if (supportedImages.indexOf(dockerImage) < 0) {
      sails.log.warn('Invalid image parameter:' + dockerImage);
      return res.badRequest();
    }

    if (typeof vcl !== 'string' || typeof rawRequests !== 'string') return res.badRequest();

    RequestMetadataService.parseInputRequests(rawRequests, function (err, _ignored, allRequests) {

      if (err) {
        return res.ok({
          fiddleid: fiddleid,
          vcl: vcl,
          har: rawRequests,
          log: err.toString()
        }, 'vcl/index');
      }

      if (allRequests.includedRequests.length == 0) {
        return res.ok({
          fiddleid: fiddleid,
          vcl: vcl,
          har: rawRequests,
          log: 'HAR does not contain any supported requests.'
        }, 'vcl/index');
      }

      if (!!req.body.dbl) {
        allRequests.includedRequests = allRequests.includedRequests.concat(allRequests.includedRequests);
      }

      FiddlePersistenceService.prepareFiddle(fiddleid, function (err, fiddle) {
        if (err) return res.serverError(err);

        // TODO persist state of 'replay requests twice' option

        ContainerService.beginReplay(fiddle.path, allRequests.includedRequests, vcl, dockerImage, function (err) {
          // started

          var viewState = {
            image: dockerImage,
            vcl: vcl,
            har: rawRequests
          };
          if (err) {
            viewState.log = 'Error: ' + err;
          }

          FiddlePersistenceService.saveViewState(fiddle, viewState, function (err) {
            if (err) return res.serverError(err);

            return res.ok({
              fiddleid: fiddle.id,
              runindex: fiddle.runIndex,
              vcl: viewState.vcl,
              har: viewState.har,
              log: viewState.log
            });

          });

        }, function (err) {
          // completed
          return completeRun(err, fiddle, allRequests);
        });

      });

    });

  }

};

<|endoftext|>


<commit_before>import React from 'react'
import 'spectrum-colorpicker'
import 'spectrum-colorpicker/spectrum.css'
export default React.createClass({
  componentDidMount: function () {
    let that = this
    $("#colorpicker").spectrum({
      color: this.props.currentStyle,
      showAlpha: true,
      showInput: true,
      allowEmpty: true,
      change: function (tinycolor) {
        that.props.updateStyle({background: tinycolor && tinycolor.toRgbString()})
      },
    })
  },
  componentDidUpdate: function () {
    $("#colorpicker").spectrum("set", this.props.currentStyle)
  },
  render: function () {
    let type
    if (this.props.currentStyle) {
      if (this.props.currentStyle.match(/^radial-gradient/)) {
        type = 'radio-gradient'
      }
      else if (this.props.currentStyle.match(/^linear-gradient/)) {
        type = 'linear-gradient'
      }
      else if (this.props.currentStyle.match(/^(rgba?\(|transparent)/)) {
        type = 'color'
      }
    }
    return

                <input type="radio" onChange={(evt)=> {
                  this.props.updateStyle({background: 'rgb()'})
                }} checked={type === 'color'}></input>color:

              <input id='colorpicker'/>

                <input type="radio" onChange={(evt)=> {
                  this.props.updateStyle({background: 'linear-gradient()'})
                }}
                       checked={type === 'linear-gradient'}/>linear gradient

2

                <input type="radio" onChange={(evt)=> {
                  this.props.updateStyle({background: 'radio-gradient()'})
                }}
                       checked={type === 'radio-gradient'}/>radio gradient

              <svg width="32" height="32" fill="red">
                <defs>
                  <filter id="f1" x="0" y="0" width="150%" height="150%">
                    <feOffset result="offOut" in="SourceAlpha" dx="3" dy="3"/>
                    <feGaussianBlur result="blurOut" in="offOut" stdDeviation="2"/>
                    <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
                  </filter>
                </defs>
                <path id="marker-up" filter="url(#f1)" d="M 8 0 L 16 16 L 0 16 z"></path>
              </svg>

  }
})
<commit_msg>use accordion to display color patterns<commit_after>import React from 'react'
import 'spectrum-colorpicker'
import 'spectrum-colorpicker/spectrum.css'
export default React.createClass({
  componentDidMount: function () {
    let that = this
    $("#colorpicker").spectrum({
      color: this.props.currentStyle,
      showAlpha: true,
      showInput: true,
      allowEmpty: true,
      change: function (tinycolor) {
        that.props.updateStyle({background: tinycolor && tinycolor.toRgbString()})
      },
    })
  },
  componentDidUpdate: function () {
    $("#colorpicker").spectrum("set", this.props.currentStyle)
  },
  render: function () {
    let type
    if (this.props.currentStyle) {
      if (this.props.currentStyle.match(/^radial-gradient/)) {
        type = 'radial-gradient'
      }
      else if (this.props.currentStyle.match(/^linear-gradient/)) {
        type = 'linear-gradient'
      }
      else if (this.props.currentStyle.match(/^(rgba?\(|transparent)/)) {
        type = 'color'
      }
    }
    return

              <input type="radio" readOnly checked={type === 'color'}></input>
               {
                this.props.updateStyle({background: 'rgb()'})
                return true
              }}>
                color

              <input id='colorpicker'/>

              <input type="radio" readOnly checked={type === 'linear-gradient'}/>
               {
                this.props.updateStyle({background: 'linear-gradient()'})
              }}>
                linear gradient

2

              <input type="radio" readOnly checked={type === 'radial-gradient'}/>
               {
                this.props.updateStyle({background: 'radial-gradient()'})
              }}>radial gradient

              <svg width="32" height="32" fill="red">
                <defs>
                  <filter id="f1" x="0" y="0" width="150%" height="150%">
                    <feOffset result="offOut" in="SourceAlpha" dx="3" dy="3"/>
                    <feGaussianBlur result="blurOut" in="offOut" stdDeviation="2"/>
                    <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
                  </filter>
                </defs>
                <path id="marker-up" filter="url(#f1)" d="M 8 0 L 16 16 L 0 16 z"></path>
              </svg>

  }
})
<|endoftext|>


<commit_before>Box = {};

// For now, might add more fields later
Box.whitelistedFields = ['id', 'login', 'name', 'given_name'];

OAuth.registerService('box', 2, null, function(query) {

  var response = getTokens(query);
  var accessToken = response.accessToken;
  var identity = getIdentity(accessToken);

  var serviceData = {
    accessToken: accessToken,
    expiresAt: (+new Date) + (1000 * response.expiresIn)
  };

  var fields = _.pick(identity, Box.whitelistedFields);
  _.extend(serviceData, fields);

  // only set the token in serviceData if it's there. this ensures
  // that we don't lose old ones (since we only get this on the first
  // log in attempt)
  if (response.refreshToken)
    serviceData.refreshToken = response.refreshToken;

  return {
    serviceData: serviceData,
    options: {profile: {name: identity.name}}
  };
});

// returns an object containing:
// - accessToken
// - expiresIn: lifetime of token in seconds
// - refreshToken, if this is the first authorization request
var getTokens = function (query) {
  var config = ServiceConfiguration.configurations.findOne({service: 'box'});
  if (!config)
    throw new ServiceConfiguration.ConfigError();

  var response;
  try {
    response = HTTP.post(
      "https://app.box.com/api/oauth2/token", {params: {
        code: query.code,
        client_id: config.clientId,
        client_secret: OAuth.openSecret(config.secret),
        redirect_uri: OAuth._redirectUri('box', config, {}, {secure: true}),
        grant_type: 'authorization_code'
      }});
  } catch (err) {
    throw _.extend(new Error("Failed to complete OAuth handshake with Box. " + err.message),
                   {response: err.response});
  }

  if (response.data.error) { // if the http response was a json object with an error attribute
    throw new Error("Failed to complete OAuth handshake with Box. " + response.data.error);
  } else {
    return {
      accessToken: response.data.access_token,
      refreshToken: response.data.refresh_token,
      expiresIn: response.data.expires_in
    };
  }
};

var getIdentity = function (accessToken) {
  try {
    return HTTP.get(
      "https://www.box.com/api/2.0/users/me",
      {params: {access_token: accessToken}}).data;
  } catch (err) {
    throw _.extend(new Error("Failed to fetch identity from Box. " + err.message),
                   {response: err.response});
  }
};

Box.retrieveCredential = function(credentialToken, credentialSecret) {
  return OAuth.retrieveCredential(credentialToken, credentialSecret);
};
<commit_msg>Add a proxy field for the email address<commit_after>Box = {};

// For now, might add more fields later
Box.whitelistedFields = ['id', 'login', 'name', 'given_name'];

OAuth.registerService('box', 2, null, function(query) {

  var response = getTokens(query);
  var accessToken = response.accessToken;
  var identity = getIdentity(accessToken);

  var serviceData = {
    accessToken: accessToken,
    expiresAt: (+new Date) + (1000 * response.expiresIn)
  };

  var fields = _.pick(identity, Box.whitelistedFields);
  _.extend(serviceData, fields);

  // Add a proxy for the email address to match other accounts-oauth packages
  serviceData.email = serviceData.login;

  // only set the token in serviceData if it's there. this ensures
  // that we don't lose old ones (since we only get this on the first
  // log in attempt)
  if (response.refreshToken)
    serviceData.refreshToken = response.refreshToken;

  return {
    serviceData: serviceData,
    options: {profile: {name: identity.name}}
  };
});

// returns an object containing:
// - accessToken
// - expiresIn: lifetime of token in seconds
// - refreshToken, if this is the first authorization request
var getTokens = function (query) {
  var config = ServiceConfiguration.configurations.findOne({service: 'box'});
  if (!config)
    throw new ServiceConfiguration.ConfigError();

  var response;
  try {
    response = HTTP.post(
      "https://app.box.com/api/oauth2/token", {params: {
        code: query.code,
        client_id: config.clientId,
        client_secret: OAuth.openSecret(config.secret),
        redirect_uri: OAuth._redirectUri('box', config, {}, {secure: true}),
        grant_type: 'authorization_code'
      }});
  } catch (err) {
    throw _.extend(new Error("Failed to complete OAuth handshake with Box. " + err.message),
                   {response: err.response});
  }

  if (response.data.error) { // if the http response was a json object with an error attribute
    throw new Error("Failed to complete OAuth handshake with Box. " + response.data.error);
  } else {
    return {
      accessToken: response.data.access_token,
      refreshToken: response.data.refresh_token,
      expiresIn: response.data.expires_in
    };
  }
};

var getIdentity = function (accessToken) {
  try {
    return HTTP.get(
      "https://www.box.com/api/2.0/users/me",
      {params: {access_token: accessToken}}).data;
  } catch (err) {
    throw _.extend(new Error("Failed to fetch identity from Box. " + err.message),
                   {response: err.response});
  }
};

Box.retrieveCredential = function(credentialToken, credentialSecret) {
  return OAuth.retrieveCredential(credentialToken, credentialSecret);
};
<|endoftext|>


<commit_before>/**
* Lumberjack
* A logging library for Sails
*/
(function() {
    var winston = require('winston');
    var useFile = true
    var logging = sails.config.logging
    if (typeof(logging) === 'undefined') {
        useFile = false;
    } else {
        if (typeof(logging.logFilePath) == 'undefined') {
            useFile = false;
        }
    }
    var transports = [
        new (winston.transports.Console)({
            colorize: true
        })
    ];
    if (useFile) {
        transports.push(
            new (winston.transports.File)({
                filename: sails.config.logging.logFilePath,
                maxsize: 10000000,
                maxFiles: 10,
                level: 'info',
                json: false
            })
        );
    }
    var logger = new (winston.Logger)({
        transports: transports
    });
    sails.log = new Object
    sails.log.debug = exports.debug = logger.debug
    sails.log.info = exports.info = logger.info
    sails.log.warn = exports.warn = logger.warn
    sails.log.error= exports.error = logger.error
})();
<commit_msg>Added some semicolons.  Added ability to call sails.log() directly<commit_after>/**
* Lumberjack
* A logging library for Sails
*/
(function() {
    var winston = require('winston');
    var useFile = true;
    var logging = sails.config.logging;
    if (typeof(logging) === 'undefined') {
        useFile = false;
    } else {
        if (typeof(logging.logFilePath) == 'undefined') {
            useFile = false;
        }
    }
    var transports = [
        new (winston.transports.Console)({
            colorize: true
        })
    ];
    if (useFile) {
        transports.push(
            new (winston.transports.File)({
                filename: sails.config.logging.logFilePath,
                maxsize: 10000000,
                maxFiles: 10,
                level: 'info',
                json: false
            })
        );
    }
    var logger = new (winston.Logger)({
        transports: transports
    });
    sails.log = logger.debug;
    sails.log.debug = exports.debug = logger.debug;
    sails.log.info = exports.info = logger.info;
    sails.log.warn = exports.warn = logger.warn;
    sails.log.error= exports.error = logger.error;
})();
<|endoftext|>


<commit_before>'use strict';

(function() {
	var WHEREABOUTS = [
		'working on his personal brand',
		'at home writing medium posts',
		'fuck knows!',
		'project managing',
		'having a cigarette',
		'having a coffee and quinoa in a startup restaurant',
                'watching an art house film in a rooftop cinema',
                'in Dalston seeing a band he read about in Pitchfork Media',
                'writing Ruby',
                'in Brooklyn eating a ramen burger',
                'at a pop-up restaurant in a bathroom in Walthamstow',
                'at Lidl buying ironically unethical Brussels sprouts',
                'in Peckham, like everybody else'
	];

	function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min)) + min;
    }

    function getRandomLocation() {
        return WHEREABOUTS[getRandomInt(0, WHEREABOUTS.length)];
    }

	document.querySelector('.js-whereabouts').innerHTML = getRandomLocation();
})();
<commit_msg> Contemporary cantlin locale<commit_after>'use strict';

(function() {
	var WHEREABOUTS = [
		'working on his personal brand',
		'at home writing medium posts',
		'fuck knows!',
		'project managing',
		'having a cigarette',
		'having a coffee and quinoa in a startup restaurant',
                'watching an art house film in a rooftop cinema',
                'in Dalston seeing a band he read about in Pitchfork Media',
                'writing Ruby',
                'in Brooklyn eating a ramen burger',
                'at a pop-up restaurant in a bathroom in Walthamstow',
                'at Lidl buying ironically unethical Brussels sprouts',
                'in Peckham, like everybody else',
                'wearing a suit and tie in the office'
	];

	function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min)) + min;
    }

    function getRandomLocation() {
        return WHEREABOUTS[getRandomInt(0, WHEREABOUTS.length)];
    }

	document.querySelector('.js-whereabouts').innerHTML = getRandomLocation();
})();
<|endoftext|>