<commit_before>// Next.js
const next = require('next')

/// Koa
const Koa = require('koa')
const Router = require('@koa/router')
const reqLogger = require('koa-pino-logger')
const session = require('koa-session')

// GraphQL/Apollo
const { ApolloServer } = require('apollo-server-koa')
const schema = require('./graphql/schema')
const loaders = require('./graphql/loaders')
const acl = require('./middleware/acl')

const routes = require('./routes')

const { valid } = require('./data/session')

module.exports = async function ({ dbPool, logger, serversPool, disableUI = false }) {
  let handle

  if (!disableUI) {
    const dev = process.env.NODE_ENV !== 'production'
    const app = next({ dev })
    handle = app.getRequestHandler()
    await app.prepare()
  }

  const server = new Koa()
  const router = new Router()
  const apolloServer = new ApolloServer(schema({ dbPool, logger, serversPool }))

  server.keys = [process.env.SESSION_KEY]

  server.use(async (ctx, next) => {
    try {
      await next()
    } catch (err) {
      ctx.log.error(err)

      ctx.status = err.status || 500
      ctx.body = { error: (err.exposed || err.expose) ? err.message : 'Internal Server Error' }
      ctx.app.emit('error', err, ctx)
    }
  })
  server.use(async (ctx, next) => {
    ctx.state.dbPool = dbPool
    ctx.state.serversPool = serversPool
    ctx.state.loaders = loaders(ctx)

    ctx.req.loaders = ctx.state.loaders

    return next()
  })
  server.use(reqLogger({ logger }))
  server.use(session({
    key: process.env.SESSION_NAME || 'bm-webui-sess',
    renew: true,
    maxAge: (24 * 60 * 60 * 1000) * 3, // Valid for 3 days
    autoCommit: false,
    httpOnly: true,
    decode (str) {
      const body = Buffer.from(str, 'base64').toString('utf8')
      const json = JSON.parse(body)

      if (json.playerId && json.playerId.type === 'Buffer') json.playerId = Buffer.from(json.playerId.data)

      return json
    },
    sameSite: 'Lax',
    valid (session, data) {
      return valid(data)
    }
  }, server))
  server.use(acl)

  routes(router)
  server.use(router.routes())

  await apolloServer.start()

  router.use(apolloServer.getMiddleware({ path: (process.env.BASTE_PATH || '') + '/graphql' }))

  if (handle) {
    router.all('(.*)', async ctx => {
      if (ctx.session) await ctx.session.manuallyCommit()

      await handle(ctx.req, ctx.res)
      ctx.respond = false
    })
  } else {
    router.all('(.*)', async ctx => {
      if (ctx.session) await ctx.session.manuallyCommit()

      ctx.respond = false
    })
  }

  server.use(router.allowedMethods())
  server.use(async (ctx) => {
    if (ctx.status === 404) {
      ctx.status = 404
      ctx.body = { error: 'Not Found' }
    }
  })

  return server
}
<commit_msg>fix: typo<commit_after>// Next.js
const next = require('next')

/// Koa
const Koa = require('koa')
const Router = require('@koa/router')
const reqLogger = require('koa-pino-logger')
const session = require('koa-session')

// GraphQL/Apollo
const { ApolloServer } = require('apollo-server-koa')
const schema = require('./graphql/schema')
const loaders = require('./graphql/loaders')
const acl = require('./middleware/acl')

const routes = require('./routes')

const { valid } = require('./data/session')

module.exports = async function ({ dbPool, logger, serversPool, disableUI = false }) {
  let handle

  if (!disableUI) {
    const dev = process.env.NODE_ENV !== 'production'
    const app = next({ dev })
    handle = app.getRequestHandler()
    await app.prepare()
  }

  const server = new Koa()
  const router = new Router()
  const apolloServer = new ApolloServer(schema({ dbPool, logger, serversPool }))

  server.keys = [process.env.SESSION_KEY]

  server.use(async (ctx, next) => {
    try {
      await next()
    } catch (err) {
      ctx.log.error(err)

      ctx.status = err.status || 500
      ctx.body = { error: (err.exposed || err.expose) ? err.message : 'Internal Server Error' }
      ctx.app.emit('error', err, ctx)
    }
  })
  server.use(async (ctx, next) => {
    ctx.state.dbPool = dbPool
    ctx.state.serversPool = serversPool
    ctx.state.loaders = loaders(ctx)

    ctx.req.loaders = ctx.state.loaders

    return next()
  })
  server.use(reqLogger({ logger }))
  server.use(session({
    key: process.env.SESSION_NAME || 'bm-webui-sess',
    renew: true,
    maxAge: (24 * 60 * 60 * 1000) * 3, // Valid for 3 days
    autoCommit: false,
    httpOnly: true,
    decode (str) {
      const body = Buffer.from(str, 'base64').toString('utf8')
      const json = JSON.parse(body)

      if (json.playerId && json.playerId.type === 'Buffer') json.playerId = Buffer.from(json.playerId.data)

      return json
    },
    sameSite: 'Lax',
    valid (session, data) {
      return valid(data)
    }
  }, server))
  server.use(acl)

  routes(router)
  server.use(router.routes())

  await apolloServer.start()

  router.use(apolloServer.getMiddleware({ path: (process.env.BASE_PATH || '') + '/graphql' }))

  if (handle) {
    router.all('(.*)', async ctx => {
      if (ctx.session) await ctx.session.manuallyCommit()

      await handle(ctx.req, ctx.res)
      ctx.respond = false
    })
  } else {
    router.all('(.*)', async ctx => {
      if (ctx.session) await ctx.session.manuallyCommit()

      ctx.respond = false
    })
  }

  server.use(router.allowedMethods())
  server.use(async (ctx) => {
    if (ctx.status === 404) {
      ctx.status = 404
      ctx.body = { error: 'Not Found' }
    }
  })

  return server
}
<|endoftext|>


<commit_before>function(args) {
/*
is_app(true)
control_type("VB")
display_name("Vertical scrollbar control")
description("This will return the Vertical scrollbar control")
base_component_id("vert_scroll_control")
load_once_from_file(true)
visibility("PRIVATE")
read_only(true)
properties(
    [
        {
            id:     "text",
            name:   "Text",
            type:   "String"
        }
        ,
        {
            id:     "background_color",
            name:   "Background color",
            type:   "String"
        }
        ,
        {
            id:     "changed_event",
            name:   "Changed event",
            type:   "Event"
        }
        ]
)//properties
logo_url("/driver_icons/vert_scroll_bar.png")
*/

    Vue.component("vert_scroll_control",{
        props: ["args","refresh"]
        ,

        template:

`<div v-bind:style='"height:100%;width:100%; border: 0px;" +
                    "background-color: "+    args["background_color"]  +  ";"'>

    <input  type="range"
            v-on:change='changedFn();runEventHandler()'
            v-on:input='changedFn();runEventHandler()'
            v-model='value'
            min="1"
            max="100"
            value="50"
            step="1"
            v-bind:style='"position:absolute;transform: rotate(90deg);width: " + (args.height - 20) + ";top: " + ((args.height / 2) - 0) + "px;left: -" + ((args.height / 2) - 20) + "px;"'
            >

    </input>

</div>`
        ,

        data: function() {
            return {
                msg:               "...",
                value:             null
            }
        }
        ,
        watch: {
          refresh: function(newValue, oldValue) {
              if (isValidObject(this.args)) {
                  this.value = this.args.value
              }
          }
        }
        ,
        mounted: function() {
            if (isValidObject(this.args)) {
                this.items = this.args.items
                if (isValidObject(this.args.value)) {
                   this.value = this.args.value
                }
            }
        }
        ,
        methods: {
              changedFn: function() {
                  if (isValidObject(this.args)) {
                      this.args.value = this.value
                  }
              }
              ,

              runEventHandler: function() {
                  this.$emit('send', {
                                                  type:               "subcomponent_event",
                                                  control_name:        this.args.name,
                                                  sub_type:           "changed",
                                                  code:                this.args.changed_event
                                              })
              }
        }

    })
}
<commit_msg>When changing scrollbar the value is updated<commit_after>function(args) {
/*
is_app(true)
control_type("VB")
display_name("Vertical scrollbar control")
description("This will return the Vertical scrollbar control")
base_component_id("vert_scroll_control")
load_once_from_file(true)
visibility("PRIVATE")
read_only(true)
properties(
    [
        {
            id:     "text",
            name:   "Text",
            type:   "String"
        }
        ,
        {
            id:     "background_color",
            name:   "Background color",
            type:   "String"
        }
        ,
        {
            id:     "value",
            name:   "Value",
            type:   "Number"
        }
        ,
        {
            id:     "changed_event",
            name:   "Changed event",
            type:   "Event"
        }
        ]
)//properties
logo_url("/driver_icons/vert_scroll_bar.png")
*/

    Vue.component("vert_scroll_control",{
        props: ["args","refresh"]
        ,

        template:

`<div v-bind:style='"height:100%;width:100%; border: 0px;" +
                    "background-color: "+    args["background_color"]  +  ";"'>

    <input  type="range"
            v-on:change='changedFn();runEventHandler()'
            v-on:input='changedFn();runEventHandler()'
            v-model='value'
            min="1"
            max="100"
            value="50"
            step="1"
            v-bind:style='"position:absolute;transform: rotate(90deg);width: " + (args.height - 20) + ";top: " + ((args.height / 2) - 0) + "px;left: -" + ((args.height / 2) - 20) + "px;"'
            >

    </input>

</div>`
        ,

        data: function() {
            return {
                msg:               "...",
                value:              null
            }
        }
        ,
        watch: {
          refresh: function(newValue, oldValue) {
              if (isValidObject(this.args)) {
                  this.value = this.args.value
              }
          }
        }
        ,
        mounted: function() {
            if (isValidObject(this.args)) {
                this.items = this.args.items
                if (isValidObject(this.args.value)) {
                   this.value = this.args.value
                }
            }
        }
        ,
        methods: {
              changedFn: function() {
                  debugger
                  if (isValidObject(this.args)) {
                      this.args.value = this.value
                  }
              }
              ,

              runEventHandler: function() {
                  this.$emit('send', {
                                                  type:               "subcomponent_event",
                                                  control_name:        this.args.name,
                                                  sub_type:           "changed",
                                                  code:                this.args.changed_event
                                              })
              }
        }

    })
}
<|endoftext|>


<commit_before>import { ClassroomResource } from 'kolibri.resources';
import logger from 'kolibri.lib.logging';
import { pageNameToModuleMap, PageNames } from '../constants';
import { LessonsPageNames } from '../constants/lessonsConstants';
import examCreation from './examCreation';
import examReport from './examReport';
import examReportDetail from './examReportDetail';
import examsRoot from './examsRoot';
import exerciseDetail from './exerciseDetail';
import groups from './groups';
import lessonSummary from './lessonSummary';
import lessonsRoot from './lessonsRoot';
import classSummary from './classSummary';
import coachNotifications from './coachNotifications';
import questionDetail from './questionDetail';
import questionList from './questionList';

const logging = logger.getLogger(__filename);

export default {
  state: {
    busy: false,
    classList: [],
    pageName: '',
    toolbarRoute: {},
    toolbarTitle: '',
    reportRefreshInterval: 30000,
  },
  mutations: {
    SET_PAGE_NAME(state, pageName) {
      state.pageName = pageName;
    },
    SET_CLASS_LIST(state, classList) {
      state.classList = classList;
    },
    SET_TOOLBAR_TITLE(state, title) {
      state.toolbarTitle = title;
    },
    SET_TOOLBAR_ROUTE(state, toolbarRoute) {
      state.toolbarRoute = toolbarRoute;
    },
  },
  getters: {
    classListPageEnabled(state) {
      // If the number of classes is exactly 1, then redirect to its home page,
      // otherwise show the whole class list
      return state.classList.length !== 1;
    },
  },
  actions: {
    setClassList(store) {
      return ClassroomResource.fetchCollection({ getParams: { role: 'coach' } })
        .then(classrooms => {
          store.commit('SET_CLASS_LIST', classrooms);
        })
        .catch(error => store.dispatch('handleApiError', error));
    },
    /**
      * Handle coach page errors.
      * The status code errors that's related to the authentication issue, most not show
        in coach page beacuse there's an `auth-message` that explain the error.
      **/
    handleCoachPageError(store, errorObject) {
      const authErrorCodes = [401, 403, 404, 407];
      logging.error(errorObject);
      if (
        errorObject.status &&
        errorObject.status.code &&
        authErrorCodes.includes(errorObject.status.code)
      ) {
        store.dispatch('handleError', '');
      } else {
        store.dispatch('handleError', errorObject);
      }
    },
    resetModuleState(store, { toRoute, fromRoute }) {
      // If going from Lesson Summary to something other than Resource Selection, reset
      if (
        fromRoute.name === LessonsPageNames.SUMMARY &&
        toRoute.name !== LessonsPageNames.SELECTION_ROOT
      ) {
        return store.dispatch('lessonSummary/resetLessonSummaryState');
      }
      if (toRoute.name === PageNames.EXAMS) {
        return store.dispatch('examCreation/resetExamCreationState');
      }
      const moduleName = pageNameToModuleMap[fromRoute.name];
      if (moduleName) {
        store.commit(`${moduleName}/RESET_STATE`);
      }
    },
    initClassInfo(store, classId) {
      store.dispatch('clearError');
      // only wait around for the results if the class is switching
      if (store.state.classSummary.id !== classId) {
        store.dispatch('loading');
        return Promise.all([
          // Make sure we load any class list data, so that we know
          // whether this user has access to multiple classes or not.
          store.dispatch('setClassList'),
          store.dispatch('classSummary/loadClassSummary', classId),
          store.dispatch('coachNotifications/fetchNotificationsForClass', classId),
        ]);
      }
      // otherwise refresh but don't block
      store
        .dispatch('classSummary/loadClassSummary', classId)
        .catch(error => this.store.dispatch('handleApiError', error));
      Promise.resolve();
    },
  },
  modules: {
    classSummary,
    coachNotifications,
    examCreation,
    examReport,
    examReportDetail,
    examsRoot,
    exerciseDetail,
    groups,
    lessonSummary,
    lessonsRoot,
    questionDetail,
    questionList,
  },
};
<commit_msg>initClassInfo always returns a Promise<commit_after>import { ClassroomResource } from 'kolibri.resources';
import logger from 'kolibri.lib.logging';
import { pageNameToModuleMap, PageNames } from '../constants';
import { LessonsPageNames } from '../constants/lessonsConstants';
import examCreation from './examCreation';
import examReport from './examReport';
import examReportDetail from './examReportDetail';
import examsRoot from './examsRoot';
import exerciseDetail from './exerciseDetail';
import groups from './groups';
import lessonSummary from './lessonSummary';
import lessonsRoot from './lessonsRoot';
import classSummary from './classSummary';
import coachNotifications from './coachNotifications';
import questionDetail from './questionDetail';
import questionList from './questionList';

const logging = logger.getLogger(__filename);

export default {
  state: {
    busy: false,
    classList: [],
    pageName: '',
    toolbarRoute: {},
    toolbarTitle: '',
    reportRefreshInterval: 30000,
  },
  mutations: {
    SET_PAGE_NAME(state, pageName) {
      state.pageName = pageName;
    },
    SET_CLASS_LIST(state, classList) {
      state.classList = classList;
    },
    SET_TOOLBAR_TITLE(state, title) {
      state.toolbarTitle = title;
    },
    SET_TOOLBAR_ROUTE(state, toolbarRoute) {
      state.toolbarRoute = toolbarRoute;
    },
  },
  getters: {
    classListPageEnabled(state) {
      // If the number of classes is exactly 1, then redirect to its home page,
      // otherwise show the whole class list
      return state.classList.length !== 1;
    },
  },
  actions: {
    setClassList(store) {
      return ClassroomResource.fetchCollection({ getParams: { role: 'coach' } })
        .then(classrooms => {
          store.commit('SET_CLASS_LIST', classrooms);
        })
        .catch(error => store.dispatch('handleApiError', error));
    },
    /**
      * Handle coach page errors.
      * The status code errors that's related to the authentication issue, most not show
        in coach page beacuse there's an `auth-message` that explain the error.
      **/
    handleCoachPageError(store, errorObject) {
      const authErrorCodes = [401, 403, 404, 407];
      logging.error(errorObject);
      if (
        errorObject.status &&
        errorObject.status.code &&
        authErrorCodes.includes(errorObject.status.code)
      ) {
        store.dispatch('handleError', '');
      } else {
        store.dispatch('handleError', errorObject);
      }
    },
    resetModuleState(store, { toRoute, fromRoute }) {
      // If going from Lesson Summary to something other than Resource Selection, reset
      if (
        fromRoute.name === LessonsPageNames.SUMMARY &&
        toRoute.name !== LessonsPageNames.SELECTION_ROOT
      ) {
        return store.dispatch('lessonSummary/resetLessonSummaryState');
      }
      if (toRoute.name === PageNames.EXAMS) {
        return store.dispatch('examCreation/resetExamCreationState');
      }
      const moduleName = pageNameToModuleMap[fromRoute.name];
      if (moduleName) {
        store.commit(`${moduleName}/RESET_STATE`);
      }
    },
    initClassInfo(store, classId) {
      store.dispatch('clearError');
      // only wait around for the results if the class is switching
      if (store.state.classSummary.id !== classId) {
        store.dispatch('loading');
        return Promise.all([
          // Make sure we load any class list data, so that we know
          // whether this user has access to multiple classes or not.
          store.dispatch('setClassList'),
          store.dispatch('classSummary/loadClassSummary', classId),
          store.dispatch('coachNotifications/fetchNotificationsForClass', classId),
        ]);
      }
      // otherwise refresh but don't block
      store
        .dispatch('classSummary/loadClassSummary', classId)
        .catch(error => this.store.dispatch('handleApiError', error));
      return Promise.resolve();
    },
  },
  modules: {
    classSummary,
    coachNotifications,
    examCreation,
    examReport,
    examReportDetail,
    examsRoot,
    exerciseDetail,
    groups,
    lessonSummary,
    lessonsRoot,
    questionDetail,
    questionList,
  },
};
<|endoftext|>


<commit_before>angular.module('meus-contatos')
    .factory('contatoService', ['$resource', function ($resource) {

        return $resource($SERVICES_CONTEXT + 'contato/:params', {}, {
            update: {
                method: "PUT"
            },

            tipos: {
                method: 'GET',
                params: {params: 'tipo'},
                isArray: true
            }

        });

    }]);<commit_msg>melhorando o service<commit_after>angular.module('meus-contatos')
    .factory('contatoService', ['$resource', function ($resource) {

        return $resource($SERVICES_CONTEXT + 'contato/:params', {}, {
            update: {
                method: "PUT"
            },

            tipos: {
                method: 'GET',
                params: {params: 'tipo'},
                isArray: true
            }
        });

    }]);<|endoftext|>


<commit_before>
/*global define */
define(["jquery", "underscore", "backbone", "../collections/edge-collection", "../collections/node-collection", "../models/node-model", "../models/edge-model"], function($, _, Backbone, BaseEdgeCollection, BaseNodeCollection){
  var pvt = {};

  pvt.alwaysTrue = function(){return true;};

  pvt.setEdgeId = function (edge) {
    var src,
        tar,
        needsServerId;

    if (edge.set) {
      // edge is a backbone model
      src = edge.get("source");
      tar = edge.get("target");
      edge.set("id", String(src.id) + String(tar.id));
      edge.set("needsServerId",!src.hasServerId || !tar.hasServerId);
    } else {
      src = edge.source;
      tar = edge.target;
      edge.id = String(src.id) + String(tar.id);
      edge.needsServerId = !src.hasServerId || !tar.hasServerId;
    }
  };

  return Backbone.Model.extend({
    defaults: function(){
      return {
        leafs: [], // TODO perhaps this should be stored in the nodes
        edges: new BaseEdgeCollection(),
        nodes: new BaseNodeCollection()
      };
    },

    initialize: function(){
      var thisModel = this;
      thisModel.edgeModel = thisModel.get("edges").model;
      thisModel.nodeModel = thisModel.get("nodes").model;
      thisModel.get("nodes").on("setFocusNode", function(id){
        thisModel.trigger("setFocusNode", id);
      });
      thisModel.get("nodes").on("toggleNodeScope", function(id){
        thisModel.trigger("toggleNodeScope", id);
      });

      thisModel.postinitialize();
    },

    // override in subclass
    postinitialize: function(){},

    /**
     * Export this graph to a simple json representation
     *
     * @return {json object}: simple json object representation of this graph
     *   that can be directly converted into a string
     */
    toJSON: function() {
      // returning nodes AND edges is redundant, since nodes contain dep info
      return {
        id: this.get("id"),
        title: this.get("title"),
        concepts: this.get("nodes").toJSON()
      };
    },

    /**
     * Make/extend this graph from a json object, but terminating at leaf node with id leafId
     */
    addJsonSubGraphToGraph: function (jsonNodeArr, leafId) {
      // create an id to node obj for DFS:
      var thisGraph = this,
          idObj = {},
          i;

      i = jsonNodeArr.length;
      while( i -- ){
        idObj[jsonNodeArr[i].id] = jsonNodeArr[i];
      }

      if (!idObj.hasOwnProperty(leafId)) {
        throw new Error("input node array does not have node with id: " + leafId);
      }

      var subgraph = [],
          visitedNodeIds = {},
          curDepSrc;

      // recursively add the nodes to the graph
      dfsVisitNodes(idObj[leafId]);

      function dfsVisitNodes (node) {
        var depLen= node.dependencies.length;
        subgraph.push(node);
        visitedNodeIds[node.id] = 1;
        while( depLen -- ){
          curDepSrc = node.dependencies[depLen].source;
          if (!visitedNodeIds.hasOwnProperty(curDepSrc)) {
            dfsVisitNodes(idObj[curDepSrc]);
          }
        }
      }

      // add the subgraph to the graph
      thisGraph.addJsonNodesToGraph(subgraph);
    },

    /**
     * Make/extend this graph from a json obj
     *
     * @param {json object} jsonObj: json string with attribute:
     *   nodes: array of objects: each contains at least node title and id (optional coordinates) and dependencies
     * @return {backbone model} this model altered by the jsonObj (allows chaining)
     */
    addJsonNodesToGraph: function(jsonNodeArr) {
      var thisGraph = this,
          tmpEdges = [];

      jsonNodeArr.forEach(function(node) {
        node.dependencies.forEach(function(dep) {
          var tEdge = {source: dep.source, target: node.id, isContracted: dep.isContracted};
          if (dep.reason) tEdge.reason = dep.reason;
          if (dep.middlePts) tEdge.middlePts = dep.middlePts;
          if (dep.id) tEdge.id = dep.id;
          if (dep.id) tEdge.id = dep.id;

          tmpEdges.push(tEdge);
        });
        node.dependencies = undefined;
        thisGraph.addNode(node);
      });

      // add edges
      tmpEdges.forEach(function(edge){
        thisGraph.addEdge.call(thisGraph, edge);
      });

      return this;
    },

    /**
     * @return <boolean> true if the graph is populated
     */
    isPopulated: function(){
      return this.getEdges().length > 0 || this.getNodes().length > 0;
    },

    /**
     * @param stNode: the start node
     * @param endNode: the end node
     * @param checkFun: an optional function that dermines whether an edge
     * is valid (e.g. an "is visible" function --defaults to a tautological function)
     * @return <boolean> - true if there is a directed path from stNode to endNode (follows outlinks from stNode)
     */
    isPathBetweenNodes: function (stNode, endNode, checkFun) {
      var thisGraph = this,
          outlinks = stNode.get("outlinks");
      checkFun = checkFun || pvt.alwaysTrue;
      // DFS recursive search
      return outlinks.length > 0
        && outlinks.any(function(ol){
          var olTar = ol.get("target");
          return checkFun(ol) && (olTar.id === endNode.id || thisGraph.isPathBetweenNodes(olTar, endNode, checkFun));
        });
    },

    /**
     * Checks if an edge is transitive by performing a DFS on it's source
     *
     * @param edge: the edge to be checked
     * @param checkFun: a function that returns a boolean value indiciating
     * whether a given edge should be counted in the traversal
     * (e.g. an "is visible" function --defaults to a tautological function)
     * @return <boolean> true if the edge is transitive
     */
    checkIfTransitive: function(edge, checkFun){
      var thisGraph = this,
          edgeSource = edge.get("source"),
          edgeTarget = edge.get("target");
      checkFun = checkFun || pvt.alwaysTrue;
      return edgeSource.get("outlinks").any(
        function(ol){
          return edge.id !== ol.id && thisGraph.isPathBetweenNodes(ol.get("target"), edgeTarget, checkFun);
        });
    },

    /**
     * Get a nodes from the graph
     *
     * @return {node collection} the node collection of the model
     */
    getNodes: function() {
      return this.get("nodes");
    },

    /**
     * Get a edges from the graph
     *
     * @return {edge collection} the edge collection of the model
     */
    getEdges: function() {
      return this.get("edges");
    },

    /**
     * Get a node from the graph with the given id
     *
     * @param {node id} nodeId: the node id of the desired node
     * @return {node} the desired node object or undefined if not present
     */
    getNode: function(nodeId) {
      return this.get("nodes").get(nodeId);
    },

    /**
     * Get an edge from the graph with the given id
     *
     * @param {edge id} edgeId: the edge id of the desired edge
     * @return {edge} the desired edge object or undefined if not present
     */
    getEdge: function(edgeId) {
      return this.get("edges").get(edgeId);
    },

    /**
     * Add an edge to the graph: adds the edge to the edge collection and
     * outlinks/dependencies properties in the appropriate nodes
     *
     * @param {edge object} edge: the edge to be added to the model
     */
    addEdge: function(edge) {
      var thisGraph = this,
          // check if source/target are ids and switch to nodes if necessary
          source =  edge.source instanceof thisGraph.nodeModel ? edge.source : this.getNode(edge.source),
          target = edge.target instanceof thisGraph.nodeModel ? edge.target : this.getNode(edge.target);

      if (!source  || !target) {
        throw new Error("source or target was not given correctly for input or does not exist in graph: " + edge.source + " -> " + edge.target );
      }

      edge.source = source;
      edge.target = target;

      if (edge.source.id === edge.target.id){
        console.log("warning: loop edge detected and not added to graph, node: " + edge.source.id);
        return;
      }

      if (edge.id === undefined) {
        pvt.setEdgeId(edge);
      }

      // check if this edge is transitive
      // (will be transitive if there is already a path from the edge source to the edge target)
      edge.isTransitive = thisGraph.isPathBetweenNodes(edge.source, edge.target);

      //
      var edges = thisGraph.getEdges();
      edges.add(edge);
      var mEdge = edges.get(edge.id);
      edge.source.get("outlinks").add(mEdge);
      edge.target.get("dependencies").add(mEdge);

      // check if the new edge changes transitivity of other edges
      if (!edge.isTransitive) {
        thisGraph.getEdges().filter(function(e){return !e.get("isTransitive");}).forEach(function(notTransEdge){
          var isTrans = thisGraph.checkIfTransitive(notTransEdge);
          if (isTrans) {
            notTransEdge.set("isTransitive", true);
          }
        });
      }
    },

    /**
     * Add a node to the graph
     * Note:
     * new nodes that should be synced with a server
     * should not have an id specified and should have a defined "url"
     * in the node backbone model or they should have the property
     * "syncWithServer" set to a non-falsey value
     *
     * @param {node object} node: the node to be added to the model
     */
    addNode: function(node) {
      var thisGraph = this,
          isNewNode = false;
      if (!(node instanceof thisGraph.nodeModel )){
        var nodeId = node.id;
        if (nodeId === undefined || nodeId === null || nodeId === "") {
          isNewNode = true;
          node.id = "-new-" + Math.random().toString(36).substring(3);
        }
        node = new thisGraph.nodeModel(node, {parse: true});
      }
      this.get("nodes").add(node);

      if (node.url && (isNewNode || node.get("syncWithServer"))) {
        node.hasServerId = false;

        node.save(["id", "tag"], {
          parse  : false, // NB must check for parse == false in model's parse method
          success: function (model, xhr) {
            node.set("id", xhr.id);
            node.set("tag", xhr.tag);
            node.hasServerId = true;

            // set edge ids that were waiting for the server
            thisGraph.getEdges().filter(function (edge) {
              return edge.get("needsServerId");
            }).forEach(pvt.setEdgeId);
          },
          error: function (model, xhr) {
            console.log("error response text:" + xhr.responseText);
          }
        });
      } else {
        node.hasServerId = true;
      }
    },

    /**
     * Removes an edge from the graph: removes the edge from the edge collection
     * and appropriate outlinks/dependencies properties in the appropriate nodes
     *
     * @param {edge-id or edge object} edge: the edge id or edge object
     */
    removeEdge: function(edge) {
      var thisGraph = this,
          edges = thisGraph.get("edges");

      edge = edge instanceof thisGraph.edgeModel ? edge : edges.get(edge);
      edge.get("source").get("outlinks").remove(edge);
      edge.get("target").get("dependencies").remove(edge);
      edges.remove(edge);

      // possibly change transitivity relationships of transitive edges
      edges.filter(function(e){return e.get("isTransitive");}).forEach(function(transEdge){
        var isTrans = thisGraph.checkIfTransitive(transEdge);
        if (!isTrans){
          transEdge.set("isTransitive", false);
        }
      });
    },

    /**
     * Removes the node from the graph and all edges that were in its dependencies/outlinks attributes
     *
     * @param {node id or node object} node: the node id or node object to be removed
     */
    removeNode: function(node){
      var thisGraph = this,
          nodes = this.get("nodes");
      node =  node instanceof thisGraph.nodeModel ? node : nodes.get(node);
      node.get("dependencies").pluck("id").forEach(function(edgeId){ thisGraph.removeEdge(edgeId);});
      node.get("outlinks").pluck("id").forEach(function(edgeId){ thisGraph.removeEdge(edgeId);});
      nodes.remove(node);
    },

    /**
     * Compute the learning view ordering (topological sort)
     * TODO write tests for getTopoSort FIXME
     */
    getTopoSort: function(){
      var thisGraph = this;
      if (!thisGraph.topoSort || !thisGraph.topoSort.length){
        thisGraph.doTopoSort();
      }
      return thisGraph.topoSort;
    },

    /**
     * Perform a depth first topological sort of the graph
     *
     * @return {list} - sorted ids of the nodes in the graph
     */
    doTopoSort: function () {
      // TODO cache the sort
      var thisGraph = this,
          nodes = thisGraph.getNodes(),
          traversedNodes = {}, // keep track of traversed nodes
          startLeafNodes;

      // init: obtain node tags with 0 outlinks (root nodes)
      startLeafNodes = _.map(nodes.filter(function(mdl){
        return mdl.get("outlinks").length == 0;
      }), function(itm){
        return itm.get("id");
      });

      thisGraph.topoSort = dfsTopSort(startLeafNodes);

      // recursive dfs topological sort
      // TODO this should be defined in pvt?
      function dfsTopSort (leafNodeTags){
        var curLeafNodeTagDepth,
            returnArr = [],
            curLeafNodeTag,
            directDeps,
            curNode;

        // recurse on the input leaf node tags
        // -- use edge weight to do the ordering if available
        for(curLeafNodeTagDepth = 0; curLeafNodeTagDepth < leafNodeTags.length; curLeafNodeTagDepth++){
          curLeafNodeTag = leafNodeTags[curLeafNodeTagDepth];
          curNode = nodes.get(curLeafNodeTag);

          if (!traversedNodes.hasOwnProperty(curLeafNodeTag)) {
            directDeps = curNode.getDirectDeps();
            traversedNodes[curLeafNodeTag] = 1;
            if (directDeps.length > 0){
              returnArr = returnArr.concat(dfsTopSort(directDeps.map(function (dep) {
                return dep.get("source").id;
              })));
            }
            returnArr.push(curLeafNodeTag);

          }
        }
        return returnArr;
      };
    },

    // /**
    //  * Contract all nodes that are not part of the dep graph for the input node id
    //  */
    // showSubgraphFromNodeId: function (nodeId) {
    //   var thisGraph = this;
    //   thisGraph.expandGraph();
    //   var visNodes = {};
    //   var traceDepGraph = function traceDepGraph(node) {
    //     visNodes[node.id] = 1;
    //     node.get("dependencies").each(function (dep) {
    //       var nextNode = dep.get("source");
    //       if (!visNodes.hasOwnProperty(nextNode.id)) {
    //         traceDepGraph(nextNode);
    //       }
    //     });
    //   };

    //   traceDepGraph(thisGraph.getNode(nodeId));

    //   thisGraph.getNodes().each(function (node) {
    //     if (!visNodes.hasOwnProperty(node.id)) {
    //       node.set("isContracted", true);
    //     }
    //   });
    // },

    expandGraph: function () {
      var thisGraph = this;
      thisGraph.getEdges().each(function (edge) {
        edge.set("isContracted", false);
      });

      thisGraph.getNodes().each(function (node) {
        node.set("isContracted", false);
      });
    },

    /**
     * Check if the input edge is present in the topological sort
     * (sheel function - not currently working)
     */
    isEdgeInTopoSort: function(edge){
      var thisGraph = this;
      // make sure we've done a topological sort
      if (!thisGraph.topoSort){
        thisGraph.doTopoSort();
      }
      return edge.isTopoEdge;
    }
  });
});
<commit_msg>generalized edgemodel and nodemodel assignments in initialize<commit_after>
/*global define */
define(["jquery", "underscore", "backbone", "../collections/edge-collection", "../collections/node-collection", "../models/node-model", "../models/edge-model"], function($, _, Backbone, BaseEdgeCollection, BaseNodeCollection){
  var pvt = {};

  pvt.alwaysTrue = function(){return true;};

  pvt.setEdgeId = function (edge) {
    var src,
        tar,
        needsServerId;

    if (edge.set) {
      // edge is a backbone model
      src = edge.get("source");
      tar = edge.get("target");
      edge.set("id", String(src.id) + String(tar.id));
      edge.set("needsServerId",!src.hasServerId || !tar.hasServerId);
    } else {
      src = edge.source;
      tar = edge.target;
      edge.id = String(src.id) + String(tar.id);
      edge.needsServerId = !src.hasServerId || !tar.hasServerId;
    }
  };

  return Backbone.Model.extend({
    defaults: function(){
      return {
        leafs: [], // TODO perhaps this should be stored in the nodes
        edges: new BaseEdgeCollection(),
        nodes: new BaseNodeCollection()
      };
    },

    initialize: function(){
      var thisModel = this;
      thisModel.edgeModel = thisModel.edgeModel || thisModel.get("edges").model;
      thisModel.nodeModel = thisModel.nodeModel || thisModel.get("nodes").model;
      thisModel.get("nodes").on("setFocusNode", function(id){
        thisModel.trigger("setFocusNode", id);
      });
      thisModel.get("nodes").on("toggleNodeScope", function(id){
        thisModel.trigger("toggleNodeScope", id);
      });

      thisModel.postinitialize();
    },

    // override in subclass
    postinitialize: function(){},

    /**
     * Export this graph to a simple json representation
     *
     * @return {json object}: simple json object representation of this graph
     *   that can be directly converted into a string
     */
    toJSON: function() {
      // returning nodes AND edges is redundant, since nodes contain dep info
      return {
        id: this.get("id"),
        title: this.get("title"),
        concepts: this.get("nodes").toJSON()
      };
    },

    /**
     * Make/extend this graph from a json object, but terminating at leaf node with id leafId
     */
    addJsonSubGraphToGraph: function (jsonNodeArr, leafId) {
      // create an id to node obj for DFS:
      var thisGraph = this,
          idObj = {},
          i;

      i = jsonNodeArr.length;
      while( i -- ){
        idObj[jsonNodeArr[i].id] = jsonNodeArr[i];
      }

      if (!idObj.hasOwnProperty(leafId)) {
        throw new Error("input node array does not have node with id: " + leafId);
      }

      var subgraph = [],
          visitedNodeIds = {},
          curDepSrc;

      // recursively add the nodes to the graph
      dfsVisitNodes(idObj[leafId]);

      function dfsVisitNodes (node) {
        var depLen= node.dependencies.length;
        subgraph.push(node);
        visitedNodeIds[node.id] = 1;
        while( depLen -- ){
          curDepSrc = node.dependencies[depLen].source;
          if (!visitedNodeIds.hasOwnProperty(curDepSrc)) {
            dfsVisitNodes(idObj[curDepSrc]);
          }
        }
      }

      // add the subgraph to the graph
      thisGraph.addJsonNodesToGraph(subgraph);
    },

    /**
     * Make/extend this graph from a json obj
     *
     * @param {json object} jsonObj: json string with attribute:
     *   nodes: array of objects: each contains at least node title and id (optional coordinates) and dependencies
     * @return {backbone model} this model altered by the jsonObj (allows chaining)
     */
    addJsonNodesToGraph: function(jsonNodeArr) {
      var thisGraph = this,
          tmpEdges = [];

      jsonNodeArr.forEach(function(node) {
        node.dependencies.forEach(function(dep) {
          var tEdge = {source: dep.source, target: node.id, isContracted: dep.isContracted};
          if (dep.reason) tEdge.reason = dep.reason;
          if (dep.middlePts) tEdge.middlePts = dep.middlePts;
          if (dep.id) tEdge.id = dep.id;
          if (dep.id) tEdge.id = dep.id;

          tmpEdges.push(tEdge);
        });
        node.dependencies = undefined;
        thisGraph.addNode(node);
      });

      // add edges
      tmpEdges.forEach(function(edge){
        thisGraph.addEdge.call(thisGraph, edge);
      });

      return this;
    },

    /**
     * @return <boolean> true if the graph is populated
     */
    isPopulated: function(){
      return this.getEdges().length > 0 || this.getNodes().length > 0;
    },

    /**
     * @param stNode: the start node
     * @param endNode: the end node
     * @param checkFun: an optional function that dermines whether an edge
     * is valid (e.g. an "is visible" function --defaults to a tautological function)
     * @return <boolean> - true if there is a directed path from stNode to endNode (follows outlinks from stNode)
     */
    isPathBetweenNodes: function (stNode, endNode, checkFun) {
      var thisGraph = this,
          outlinks = stNode.get("outlinks");
      checkFun = checkFun || pvt.alwaysTrue;
      // DFS recursive search
      return outlinks.length > 0
        && outlinks.any(function(ol){
          var olTar = ol.get("target");
          return checkFun(ol) && (olTar.id === endNode.id || thisGraph.isPathBetweenNodes(olTar, endNode, checkFun));
        });
    },

    /**
     * Checks if an edge is transitive by performing a DFS on it's source
     *
     * @param edge: the edge to be checked
     * @param checkFun: a function that returns a boolean value indiciating
     * whether a given edge should be counted in the traversal
     * (e.g. an "is visible" function --defaults to a tautological function)
     * @return <boolean> true if the edge is transitive
     */
    checkIfTransitive: function(edge, checkFun){
      var thisGraph = this,
          edgeSource = edge.get("source"),
          edgeTarget = edge.get("target");
      checkFun = checkFun || pvt.alwaysTrue;
      return edgeSource.get("outlinks").any(
        function(ol){
          return edge.id !== ol.id && thisGraph.isPathBetweenNodes(ol.get("target"), edgeTarget, checkFun);
        });
    },

    /**
     * Get a nodes from the graph
     *
     * @return {node collection} the node collection of the model
     */
    getNodes: function() {
      return this.get("nodes");
    },

    /**
     * Get a edges from the graph
     *
     * @return {edge collection} the edge collection of the model
     */
    getEdges: function() {
      return this.get("edges");
    },

    /**
     * Get a node from the graph with the given id
     *
     * @param {node id} nodeId: the node id of the desired node
     * @return {node} the desired node object or undefined if not present
     */
    getNode: function(nodeId) {
      return this.get("nodes").get(nodeId);
    },

    /**
     * Get an edge from the graph with the given id
     *
     * @param {edge id} edgeId: the edge id of the desired edge
     * @return {edge} the desired edge object or undefined if not present
     */
    getEdge: function(edgeId) {
      return this.get("edges").get(edgeId);
    },

    /**
     * Add an edge to the graph: adds the edge to the edge collection and
     * outlinks/dependencies properties in the appropriate nodes
     *
     * @param {edge object} edge: the edge to be added to the model
     */
    addEdge: function(edge) {
      var thisGraph = this,
          // check if source/target are ids and switch to nodes if necessary
          source =  typeof edge.source === "string"  ? this.getNode(edge.source) : edge.source,
          target = typeof edge.target === "string" ? this.getNode(edge.target) :  edge.target;

      if (!source  || !target) {
        throw new Error("source or target was not given correctly for input or does not exist in graph: " + edge.source + " -> " + edge.target );
      }

      edge.source = source;
      edge.target = target;

      if (edge.source.id === edge.target.id){
        console.log("warning: loop edge detected and not added to graph, node: " + edge.source.id);
        return;
      }

      if (edge.id === undefined) {
        pvt.setEdgeId(edge);
      }

      // check if this edge is transitive
      // (will be transitive if there is already a path from the edge source to the edge target)
      edge.isTransitive = thisGraph.isPathBetweenNodes(edge.source, edge.target);

      //
      var edges = thisGraph.getEdges();
      edges.add(edge);
      var mEdge = edges.get(edge.id);
      edge.source.get("outlinks").add(mEdge);
      edge.target.get("dependencies").add(mEdge);

      // check if the new edge changes transitivity of other edges
      if (!edge.isTransitive) {
        thisGraph.getEdges().filter(function(e){return !e.get("isTransitive");}).forEach(function(notTransEdge){
          var isTrans = thisGraph.checkIfTransitive(notTransEdge);
          if (isTrans) {
            notTransEdge.set("isTransitive", true);
          }
        });
      }
    },

    /**
     * Add a node to the graph
     * Note:
     * new nodes that should be synced with a server
     * should not have an id specified and should have a defined "url"
     * in the node backbone model or they should have the property
     * "syncWithServer" set to a non-falsey value
     *
     * @param {node object} node: the node to be added to the model
     */
    addNode: function(node) {
      var thisGraph = this,
          isNewNode = false;
      if (!(node.set )){
        var nodeId = node.id;
        if (nodeId === undefined || nodeId === null || nodeId === "") {
          isNewNode = true;
          node.id = "-new-" + Math.random().toString(36).substring(3);
        }
        node = new thisGraph.nodeModel(node, {parse: true});
      }
      thisGraph.getNodes().add(node);

//!!!!      PROBLEM: nodeModel is defined in init (perhaps check if its defined here)

      if (node.url && (isNewNode || node.get("syncWithServer"))) {
        node.hasServerId = false;

        node.save(["id", "tag"], {
          parse  : false, // NB must check for parse == false in model's parse method
          success: function (model, xhr) {
            node.set("id", xhr.id);
            node.set("tag", xhr.tag);
            node.hasServerId = true;

            // set edge ids that were waiting for the server
            thisGraph.getEdges().filter(function (edge) {
              return edge.get("needsServerId");
            }).forEach(pvt.setEdgeId);
          },
          error: function (model, xhr) {
            console.log("error response text:" + xhr.responseText);
          }
        });
      } else {
        node.hasServerId = true;
      }
    },

    /**
     * Removes an edge from the graph: removes the edge from the edge collection
     * and appropriate outlinks/dependencies properties in the appropriate nodes
     *
     * @param {edge-id or edge object} edge: the edge id or edge object
     */
    removeEdge: function(edge) {
      var thisGraph = this,
          edges = thisGraph.get("edges");

      edge = edge instanceof thisGraph.edgeModel ? edge : edges.get(edge);
      edge.get("source").get("outlinks").remove(edge);
      edge.get("target").get("dependencies").remove(edge);
      edges.remove(edge);

      // possibly change transitivity relationships of transitive edges
      edges.filter(function(e){return e.get("isTransitive");}).forEach(function(transEdge){
        var isTrans = thisGraph.checkIfTransitive(transEdge);
        if (!isTrans){
          transEdge.set("isTransitive", false);
        }
      });
    },

    /**
     * Removes the node from the graph and all edges that were in its dependencies/outlinks attributes
     *
     * @param {node id or node object} node: the node id or node object to be removed
     */
    removeNode: function(node){
      var thisGraph = this,
          nodes = this.get("nodes");
      node =  node instanceof thisGraph.nodeModel ? node : nodes.get(node);
      node.get("dependencies").pluck("id").forEach(function(edgeId){ thisGraph.removeEdge(edgeId);});
      node.get("outlinks").pluck("id").forEach(function(edgeId){ thisGraph.removeEdge(edgeId);});
      nodes.remove(node);
    },

    /**
     * Compute the learning view ordering (topological sort)
     * TODO write tests for getTopoSort FIXME
     */
    getTopoSort: function(){
      var thisGraph = this;
      if (!thisGraph.topoSort || !thisGraph.topoSort.length){
        thisGraph.doTopoSort();
      }
      return thisGraph.topoSort;
    },

    /**
     * Perform a depth first topological sort of the graph
     *
     * @return {list} - sorted ids of the nodes in the graph
     */
    doTopoSort: function () {
      // TODO cache the sort
      var thisGraph = this,
          nodes = thisGraph.getNodes(),
          traversedNodes = {}, // keep track of traversed nodes
          startLeafNodes;

      // init: obtain node tags with 0 outlinks (root nodes)
      startLeafNodes = _.map(nodes.filter(function(mdl){
        return mdl.get("outlinks").length == 0;
      }), function(itm){
        return itm.get("id");
      });

      thisGraph.topoSort = dfsTopSort(startLeafNodes);

      // recursive dfs topological sort
      // TODO this should be defined in pvt?
      function dfsTopSort (leafNodeTags){
        var curLeafNodeTagDepth,
            returnArr = [],
            curLeafNodeTag,
            directDeps,
            curNode;

        // recurse on the input leaf node tags
        // -- use edge weight to do the ordering if available
        for(curLeafNodeTagDepth = 0; curLeafNodeTagDepth < leafNodeTags.length; curLeafNodeTagDepth++){
          curLeafNodeTag = leafNodeTags[curLeafNodeTagDepth];
          curNode = nodes.get(curLeafNodeTag);

          if (!traversedNodes.hasOwnProperty(curLeafNodeTag)) {
            directDeps = curNode.getDirectDeps();
            traversedNodes[curLeafNodeTag] = 1;
            if (directDeps.length > 0){
              returnArr = returnArr.concat(dfsTopSort(directDeps.map(function (dep) {
                return dep.get("source").id;
              })));
            }
            returnArr.push(curLeafNodeTag);

          }
        }
        return returnArr;
      };
    },

    // /**
    //  * Contract all nodes that are not part of the dep graph for the input node id
    //  */
    // showSubgraphFromNodeId: function (nodeId) {
    //   var thisGraph = this;
    //   thisGraph.expandGraph();
    //   var visNodes = {};
    //   var traceDepGraph = function traceDepGraph(node) {
    //     visNodes[node.id] = 1;
    //     node.get("dependencies").each(function (dep) {
    //       var nextNode = dep.get("source");
    //       if (!visNodes.hasOwnProperty(nextNode.id)) {
    //         traceDepGraph(nextNode);
    //       }
    //     });
    //   };

    //   traceDepGraph(thisGraph.getNode(nodeId));

    //   thisGraph.getNodes().each(function (node) {
    //     if (!visNodes.hasOwnProperty(node.id)) {
    //       node.set("isContracted", true);
    //     }
    //   });
    // },

    expandGraph: function () {
      var thisGraph = this;
      thisGraph.getEdges().each(function (edge) {
        edge.set("isContracted", false);
      });

      thisGraph.getNodes().each(function (node) {
        node.set("isContracted", false);
      });
    },

    /**
     * Check if the input edge is present in the topological sort
     * (sheel function - not currently working)
     */
    isEdgeInTopoSort: function(edge){
      var thisGraph = this;
      // make sure we've done a topological sort
      if (!thisGraph.topoSort){
        thisGraph.doTopoSort();
      }
      return edge.isTopoEdge;
    }
  });
});
<|endoftext|>


<commit_before>/* ***********************************************************************************************

    Unify Project

    Homepage: unify-project.org
    License: MIT + Apache (V2)
    Copyright: 2012 Deutsche Telekom AG, Germany, http://telekom.com

*********************************************************************************************** */

(function() {

  /**
   * The ID of the CLOSE button. (The one in the right upper corner)
   */
  var BTN_CLOSE = "CLOSE";

  /**
   * The ID of the default OK button
   */
  var BTN_OK = "OK";

  /**
   * Generic modular dialog
   */
  core.Class("unify.ui.dialog.GenericDialog", {
    include: [
              unify.ui.container.Composite,
              unify.ui.core.MChildControl,
              unify.ui.core.MRemoteChildrenHandling
             ],
    implement : [unify.ui.core.IPopOver],

    /*
     *****************************************************************************
       EVENTS
     *****************************************************************************
     */

    events: {
      /** This event is fired when the dialog is closed by pressing a button */
      "execute": lowland.events.DataEvent
    },

    /**
     * Creates a new generic dialog
     *
     * @param title {String} Title of dialog
     * @param buttons {Array} Array of buttons
     */
    construct: function(title, buttons) {
      unify.ui.container.Composite.call(this, new unify.ui.layout.VBox());
      unify.ui.core.MChildControl.call(this);
      unify.ui.core.MRemoteChildrenHandling.call(this);

      this.__createUI(title, buttons);
    },

    /*
     *****************************************************************************
       PROPERTIES
     *****************************************************************************
     */
    properties : {
      // overridden
      appearance : {
        init: "dialog"
      }
    },

    /*
     *****************************************************************************
       MEMBERS
     *****************************************************************************
     */
    members : {

      // TODO:
      indexOf : function() {
        return unify.ui.core.MRemoteChildrenHandling.prototype.indexOf.apply(this, arguments);
      },
      add : function() {
        unify.ui.core.MRemoteChildrenHandling.prototype.add.apply(this, arguments);
      },
      getChildren : function() {
        return unify.ui.core.MRemoteChildrenHandling.prototype.getChildren.apply(this, arguments);
      },
      setStyle : function() {
        unify.ui.core.MRemoteChildrenHandling.prototype.setStyle.apply(this, arguments);
      },
      // TODO DONE

      getModal : function() {
        return true;
      },

      /**
       * Get children container that is accessed via remote child handling
       *
       * @return {unify.ui.core.Widget} Container
       */
      getChildrenContainer : function() {
        return this.getChildControl("content");
      },

      /**
       * Creates child controls
       *
       * @param id {String} ID of control
       * @return {unify.ui.core.Widget} Widget
       */
      _createChildControlImpl : function(id) {
        var control;

        if (id == "X") {
          // close button (right upper corner)
          control = new unify.ui.form.Button("Close");
          this._add(control);
        } else if (id == "title") {
          control = new unify.ui.basic.Label();
          control.set({
            alignX: "center",
            alignY: "bottom"
          });
          this._add(control);
        } else if (id == "content") {
          control = new unify.ui.container.Composite(new unify.ui.layout.VBox());
          control.set({
            allowGrowX: true,
            allowGrowY: true,
            allowShrinkX: true,
            allowShrinkY: true
          });
          this._add(control, { flex: 1 });
        } else if (id == "buttons") {
          control = new unify.ui.container.Composite(new unify.ui.layout.HBox(10));
          control.set({
            allowGrowX: true,
            allowGrowY: false,
            allowShrinkX: true,
            allowShrinkY: false
          });
          this._add(control);
        }

        return control; // || this.base(arguments, id);
      },

      /**
       * Creates UI
       *
       * @param title {String} Title of UI
       * @param buttons {Array} Array of buttons to show
       */
      __createUI : function(title, buttons) {
        var X = this._showChildControl("X");
        X.addListener("execute", this.__onButtonExecute, this);
        X.setUserData("id", BTN_CLOSE);

        this._showChildControl("title").setValue(title);
        this._showChildControl("content");
        var buttonContainer = this._showChildControl("buttons");

        this.__createButtons(buttonContainer, buttons);
      },

      /**
       * Creates buttons in UI
       *
       * @param buttonContainer {unify.ui.core.Widget} Container to add buttons to
       * @param buttons {Array} Array of button configurations to add to buttonContainer
       */
      __createButtons : function(buttonContainer, buttons) {
        var leftButtonContainer_layout = new unify.ui.layout.HBox();
        leftButtonContainer_layout.setAlignX("left");
        leftButtonContainer_layout.setSpacing(10);
        var leftButtonContainer = new unify.ui.container.Composite(leftButtonContainer_layout);

        var centerButtonContainer_layout = new unify.ui.layout.HBox();
        centerButtonContainer_layout.setAlignX("center");
        centerButtonContainer_layout.setSpacing(10);
        var centerButtonContainer = new unify.ui.container.Composite(centerButtonContainer_layout);

        var rightButtonContainer_layout = new unify.ui.layout.HBox();
        rightButtonContainer_layout.setAlignX("right");
        rightButtonContainer_layout.setSpacing(10);
        var rightButtonContainer = new unify.ui.container.Composite(rightButtonContainer_layout);

        buttonContainer.add(leftButtonContainer, {flex: 2});
        buttonContainer.add(centerButtonContainer, {flex: 1});
        buttonContainer.add(rightButtonContainer, {flex: 2});

        if (!buttons || (buttons.length <= 0)) {
          // No buttons are specified. Create a default Button

          var okBtn = this.__okBtn = new unify.ui.form.Button("OK");
          okBtn.setAppearance("dialog.button");
          okBtn.set({
            allowGrowX: true,
            allowGrowY: false,
            alignY: "middle"
          });

          okBtn.addListener("execute", function() {
            this.fireEvent("execute", BTN_OK);
          }, this);

          centerButtonContainer.add(okBtn);

        } else  {
          // generate buttons

          var btnCount = buttons.length;

          if (btnCount > 4) {
            this.warn("Too much buttons. Maximal 4 buttons are supported.");
            btnCount = 4;
          }

          for (var i=0; i<btnCount; i++) {
            var button = buttons[i];

            //error handling
            if (!button.label) {
              this.warn("Button #"+i+" has no label.");
              continue;
            }
            if (!button.id) {
              this.warn("Button #"+i+" has no id.");
              continue;
            }
            if (!button.align) {
              this.warn("Button #"+i+" has no align. Using default align");
              button.align = "right";
            }

            // create new button
            var userBtn = new unify.ui.form.Button(button.label);
            userBtn.setUserData("id", button.id);
            userBtn.setAppearance("dialog.button");
            userBtn.set({
              allowGrowX: true,
              allowGrowY: false,
              alignY: "middle"
            });

            userBtn.addListener("execute", this.__onButtonExecute, this);

            // add the new button to the right alignment container
            switch (button.align.toUpperCase()) {
              case "LEFT":
                leftButtonContainer.add(userBtn);
                break;
              case "CENTER":
                centerButtonContainer.add(userBtn);
                break;
              default:
                this.warn("Button #"+i+": align \""+button.align+"\" is invalid. Using default align");
              case "RIGHT":
                rightButtonContainer.add(userBtn);
            }

          }
        }

        return buttonContainer;
      },

      /**
       * Handler for tap on buttons
       * @param e {qx.event.type.Event} Event
       */
      __onButtonExecute : function(e) {
        this.fireEvent("execute", e.getTarget().getUserData("id"));
      }

    }
  });

})();<commit_msg>Add getStyle<commit_after>/* ***********************************************************************************************

    Unify Project

    Homepage: unify-project.org
    License: MIT + Apache (V2)
    Copyright: 2012 Deutsche Telekom AG, Germany, http://telekom.com

*********************************************************************************************** */

(function() {

  /**
   * The ID of the CLOSE button. (The one in the right upper corner)
   */
  var BTN_CLOSE = "CLOSE";

  /**
   * The ID of the default OK button
   */
  var BTN_OK = "OK";

  /**
   * Generic modular dialog
   */
  core.Class("unify.ui.dialog.GenericDialog", {
    include: [
              unify.ui.container.Composite,
              unify.ui.core.MChildControl,
              unify.ui.core.MRemoteChildrenHandling
             ],
    implement : [unify.ui.core.IPopOver],

    /*
     *****************************************************************************
       EVENTS
     *****************************************************************************
     */

    events: {
      /** This event is fired when the dialog is closed by pressing a button */
      "execute": lowland.events.DataEvent
    },

    /**
     * Creates a new generic dialog
     *
     * @param title {String} Title of dialog
     * @param buttons {Array} Array of buttons
     */
    construct: function(title, buttons) {
      unify.ui.container.Composite.call(this, new unify.ui.layout.VBox());
      unify.ui.core.MChildControl.call(this);
      unify.ui.core.MRemoteChildrenHandling.call(this);

      this.__createUI(title, buttons);
    },

    /*
     *****************************************************************************
       PROPERTIES
     *****************************************************************************
     */
    properties : {
      // overridden
      appearance : {
        init: "dialog"
      }
    },

    /*
     *****************************************************************************
       MEMBERS
     *****************************************************************************
     */
    members : {

      // TODO:
      indexOf : function() {
        return unify.ui.core.MRemoteChildrenHandling.prototype.indexOf.apply(this, arguments);
      },
      add : function() {
        unify.ui.core.MRemoteChildrenHandling.prototype.add.apply(this, arguments);
      },
      getChildren : function() {
        return unify.ui.core.MRemoteChildrenHandling.prototype.getChildren.apply(this, arguments);
      },
      setStyle : function() {
        unify.ui.core.MRemoteChildrenHandling.prototype.setStyle.apply(this, arguments);
      },
      getStyle : function() {
        return unify.ui.core.MRemoteChildrenHandling.prototype.getStyle.apply(this, arguments);
      },
      // TODO DONE

      getModal : function() {
        return true;
      },

      /**
       * Get children container that is accessed via remote child handling
       *
       * @return {unify.ui.core.Widget} Container
       */
      getChildrenContainer : function() {
        return this.getChildControl("content");
      },

      /**
       * Creates child controls
       *
       * @param id {String} ID of control
       * @return {unify.ui.core.Widget} Widget
       */
      _createChildControlImpl : function(id) {
        var control;

        if (id == "X") {
          // close button (right upper corner)
          control = new unify.ui.form.Button("Close");
          this._add(control);
        } else if (id == "title") {
          control = new unify.ui.basic.Label();
          control.set({
            alignX: "center",
            alignY: "bottom"
          });
          this._add(control);
        } else if (id == "content") {
          control = new unify.ui.container.Composite(new unify.ui.layout.VBox());
          control.set({
            allowGrowX: true,
            allowGrowY: true,
            allowShrinkX: true,
            allowShrinkY: true
          });
          this._add(control, { flex: 1 });
        } else if (id == "buttons") {
          control = new unify.ui.container.Composite(new unify.ui.layout.HBox(10));
          control.set({
            allowGrowX: true,
            allowGrowY: false,
            allowShrinkX: true,
            allowShrinkY: false
          });
          this._add(control);
        }

        return control; // || this.base(arguments, id);
      },

      /**
       * Creates UI
       *
       * @param title {String} Title of UI
       * @param buttons {Array} Array of buttons to show
       */
      __createUI : function(title, buttons) {
        var X = this._showChildControl("X");
        X.addListener("execute", this.__onButtonExecute, this);
        X.setUserData("id", BTN_CLOSE);

        this._showChildControl("title").setValue(title);
        this._showChildControl("content");
        var buttonContainer = this._showChildControl("buttons");

        this.__createButtons(buttonContainer, buttons);
      },

      /**
       * Creates buttons in UI
       *
       * @param buttonContainer {unify.ui.core.Widget} Container to add buttons to
       * @param buttons {Array} Array of button configurations to add to buttonContainer
       */
      __createButtons : function(buttonContainer, buttons) {
        var leftButtonContainer_layout = new unify.ui.layout.HBox();
        leftButtonContainer_layout.setAlignX("left");
        leftButtonContainer_layout.setSpacing(10);
        var leftButtonContainer = new unify.ui.container.Composite(leftButtonContainer_layout);

        var centerButtonContainer_layout = new unify.ui.layout.HBox();
        centerButtonContainer_layout.setAlignX("center");
        centerButtonContainer_layout.setSpacing(10);
        var centerButtonContainer = new unify.ui.container.Composite(centerButtonContainer_layout);

        var rightButtonContainer_layout = new unify.ui.layout.HBox();
        rightButtonContainer_layout.setAlignX("right");
        rightButtonContainer_layout.setSpacing(10);
        var rightButtonContainer = new unify.ui.container.Composite(rightButtonContainer_layout);

        buttonContainer.add(leftButtonContainer, {flex: 2});
        buttonContainer.add(centerButtonContainer, {flex: 1});
        buttonContainer.add(rightButtonContainer, {flex: 2});

        if (!buttons || (buttons.length <= 0)) {
          // No buttons are specified. Create a default Button

          var okBtn = this.__okBtn = new unify.ui.form.Button("OK");
          okBtn.setAppearance("dialog.button");
          okBtn.set({
            allowGrowX: true,
            allowGrowY: false,
            alignY: "middle"
          });

          okBtn.addListener("execute", function() {
            this.fireEvent("execute", BTN_OK);
          }, this);

          centerButtonContainer.add(okBtn);

        } else  {
          // generate buttons

          var btnCount = buttons.length;

          if (btnCount > 4) {
            this.warn("Too much buttons. Maximal 4 buttons are supported.");
            btnCount = 4;
          }

          for (var i=0; i<btnCount; i++) {
            var button = buttons[i];

            //error handling
            if (!button.label) {
              this.warn("Button #"+i+" has no label.");
              continue;
            }
            if (!button.id) {
              this.warn("Button #"+i+" has no id.");
              continue;
            }
            if (!button.align) {
              this.warn("Button #"+i+" has no align. Using default align");
              button.align = "right";
            }

            // create new button
            var userBtn = new unify.ui.form.Button(button.label);
            userBtn.setUserData("id", button.id);
            userBtn.setAppearance("dialog.button");
            userBtn.set({
              allowGrowX: true,
              allowGrowY: false,
              alignY: "middle"
            });

            userBtn.addListener("execute", this.__onButtonExecute, this);

            // add the new button to the right alignment container
            switch (button.align.toUpperCase()) {
              case "LEFT":
                leftButtonContainer.add(userBtn);
                break;
              case "CENTER":
                centerButtonContainer.add(userBtn);
                break;
              default:
                this.warn("Button #"+i+": align \""+button.align+"\" is invalid. Using default align");
              case "RIGHT":
                rightButtonContainer.add(userBtn);
            }

          }
        }

        return buttonContainer;
      },

      /**
       * Handler for tap on buttons
       * @param e {qx.event.type.Event} Event
       */
      __onButtonExecute : function(e) {
        this.fireEvent("execute", e.getTarget().getUserData("id"));
      }

    }
  });

})();<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')
const inquirer = require('inquirer')

const { FsUtils } = require('../shared/fs.utils')
const { LogUtils } = require('../shared/log.utils')
const { GitUtils } = require('../shared/git.utils')

const { InitStopedByUser } = require('./init-stop-by-user.error')
const { FolderNotEmpty } = require('../shared/folder-not-empty.error')
const { FileNotDirectory } = require('../shared/file-not-directory.error')

const URL_REGEX = /^((?:(https?):\/\/)?((?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]|[0-9])\.(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]|[0-9])\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]|[0-9])\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]|[0-9]))|(?:(?:(?:\w+\.){1,2}[\w]{2,3})))(?::(\d+))?((?:\/[\w]+)*)(?:\/|(\/[\w]+\.[\w]{3,4})|(\?(?:([\w]+=[\w]+)&)*([\w]+=[\w]+))?|\?(?:(wsdl|wadl))))$/
const PATH_REGEX = /^(?:(?:~|\.{1,2})?\/)+(?:[a-zA-Z\.\-\_]+\/?)*$/

module.exports = exports = configService => options => {
  const userForceOverwrite = options.force || false
  const questions = [
    {
      name: 'overwrite_file',
      message: 'A configuration file already exist. Do you want to continue ?',
      type: 'confirm',
      when: () => configService.configFileExist() && !userForceOverwrite
    },
    {
      name: 'repo_url',
      message: 'Repository url:',
      type: 'input',
      validate: url => URL_REGEX.test(url),
      when: data => !configService.configFileExist() || data.overwrite_file || userForceOverwrite
    },
    {
      name: 'folder_path',
      message: 'Folder path:',
      type: 'input',
      validate: path => PATH_REGEX.test(path),
      when: data => !configService.configFileExist() || data.overwrite_file || userForceOverwrite
    }
  ]

  inquirer.prompt(questions)
    .then(({ repo_url = null, folder_path, overwrite_file = true }) => {
      if (!overwrite_file) {
        throw new InitStopedByUser('You stopped the command. Nothing has be made.')
      }

      folder_path = folder_path.replace('~', process.env.HOME)
      folder_path = path.resolve(folder_path)

      configService.repoUrl = repo_url
      configService.folderPath = folder_path
    })
    .then(() => {
      const folderPath  = configService.folderPath
      if (!FsUtils.fileExist(folderPath)) {
        LogUtils.log({ type: 'info', message: 'Folder does not exist. It will be created.' })
        fs.mkdirSync(folderPath)
      }

      const isDirectory = fs.statSync(folderPath).isDirectory()
      if (!isDirectory) {
        throw new FileNotDirectory()
      }

      const folderIsEmpty = fs.readdirSync(folderPath).length < 1
      if (!folderIsEmpty) {
        throw new FolderNotEmpty()
      }
    })
    .then(() => {
      if (configService.repoUrl == null) {
        LogUtils.log({ type: 'warn', message: 'Impossible to cloned git repository. Need repository URL.' })
        return
      }

      return GitUtils.clone(configService.repoUrl, configService.folderPath)
        .then(repo => {
          LogUtils.log({ type: 'info', message: 'Git repository cloned successuly.' })
          return
        })
    })
    .catch(error => {
      if (error instanceof InitStopedByUser) {
        LogUtils.log({ message: error.message })
        return
      }

      if (error instanceof FolderNotEmpty) {
        LogUtils.log({ type: 'error', message: error.message })
        return
      }

      if (error instanceof FileNotDirectory) {
        LogUtils.log({ type: 'error', message: error.message })
        return
      }

      LogUtils.log({ type: 'error', message: 'An error occured.', prefix: ' Fail ' })
    })
}
<commit_msg>Add default value support on init command<commit_after>const fs = require('fs')
const path = require('path')
const inquirer = require('inquirer')

const { FsUtils } = require('../shared/fs.utils')
const { LogUtils } = require('../shared/log.utils')
const { GitUtils } = require('../shared/git.utils')

const { InitStopedByUser } = require('./init-stop-by-user.error')
const { FolderNotEmpty } = require('../shared/folder-not-empty.error')
const { FileNotDirectory } = require('../shared/file-not-directory.error')

const URL_REGEX = /^((?:(https?):\/\/)?((?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]|[0-9])\.(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]|[0-9])\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]|[0-9])\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]|[0-9]))|(?:(?:(?:\w+\.){1,2}[\w]{2,3})))(?::(\d+))?((?:\/[\w]+)*)(?:\/|(\/[\w]+\.[\w]{3,4})|(\?(?:([\w]+=[\w]+)&)*([\w]+=[\w]+))?|\?(?:(wsdl|wadl))))$/
const PATH_REGEX = /^(?:(?:~|\.{1,2})?\/)+(?:[a-zA-Z\.\-\_]+\/?)*$/

module.exports = exports = configService => options => {
  const userForceOverwrite = options.force || false
  const questions = [
    {
      name: 'overwrite_file',
      message: 'A configuration file already exist. Do you want to continue ?',
      type: 'confirm',
      when: () => configService.configFileExist() && !userForceOverwrite
    },
    {
      name: 'repo_url',
      message: 'Repository url:',
      type: 'input',
      validate: url => URL_REGEX.test(url),
      default: () => {
        if (configService.configFileExist()) {
          return configService.repoUrl
        }
      },
      when: data => !configService.configFileExist() || data.overwrite_file || userForceOverwrite
    },
    {
      name: 'folder_path',
      message: 'Folder path:',
      type: 'input',
      validate: path => PATH_REGEX.test(path),
      default: () => {
        if (configService.configFileExist()) {
          return configService.folderPath
        }
      },
      when: data => !configService.configFileExist() || data.overwrite_file || userForceOverwrite
    }
  ]

  inquirer.prompt(questions)
    .then(({ repo_url = null, folder_path, overwrite_file = true }) => {
      if (!overwrite_file) {
        throw new InitStopedByUser('You stopped the command. Nothing has be made.')
      }

      folder_path = folder_path.replace('~', process.env.HOME)
      folder_path = path.resolve(folder_path)

      configService.repoUrl = repo_url
      configService.folderPath = folder_path
    })
    .then(() => {
      const folderPath  = configService.folderPath
      if (!FsUtils.fileExist(folderPath)) {
        LogUtils.log({ type: 'info', message: 'Folder does not exist. It will be created.' })
        fs.mkdirSync(folderPath)
      }

      const isDirectory = fs.statSync(folderPath).isDirectory()
      if (!isDirectory) {
        throw new FileNotDirectory()
      }

      const folderIsEmpty = fs.readdirSync(folderPath).length < 1
      if (!folderIsEmpty) {
        throw new FolderNotEmpty()
      }
    })
    .then(() => {
      if (configService.repoUrl == null) {
        LogUtils.log({ type: 'warn', message: 'Impossible to cloned git repository. Need repository URL.' })
        return
      }

      return GitUtils.clone(configService.repoUrl, configService.folderPath)
        .then(repo => {
          LogUtils.log({ type: 'info', message: 'Git repository cloned successuly.' })
          return
        })
    })
    .catch(error => {
      if (error instanceof InitStopedByUser) {
        LogUtils.log({ message: error.message })
        return
      }

      if (error instanceof FolderNotEmpty) {
        LogUtils.log({ type: 'error', message: error.message })
        return
      }

      if (error instanceof FileNotDirectory) {
        LogUtils.log({ type: 'error', message: error.message })
        return
      }

      LogUtils.log({ type: 'error', message: 'An error occured.', prefix: ' Fail ' })
    })
}
<|endoftext|>


<commit_before>/**
 * Strider
 * Github Game-Off 2015 Entry
 * by Petar Petrov / github.com/petarov
 *
 * (A fork of) Octocat Jump
 * A Github Game Off 2012 Entry
 * @copyright Omer Goshen <gershon@goosemoose.com>
 */
(function(Crafty) {
    document.addEventListener('DOMContentLoaded', function () {

    var isSafari = !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/);
    console.log(navigator.userAgent);
    var STAGE_WIDTH = 400,
        STAGE_HEIGHT = 640,
        screen = document.getElementById('game'),
        skipIntro = false;

    Crafty.init(STAGE_WIDTH, STAGE_HEIGHT, screen).canvas.init();
    Crafty.viewport.init(STAGE_WIDTH, STAGE_HEIGHT, screen);
    Crafty.viewport.bounds = {
        min: { x:-100, y: -Infinity },
        max: { x: STAGE_WIDTH + 50, y: STAGE_HEIGHT }
    };
    // Crafty.viewport.clampToEntities = true;
    Crafty.settings.modify('autoPause', true);

    /**
     * Octicons font component
     * @see https://github.com/styleguide/css/7.0
     */
    Crafty.c("Octicons", {
        init: function () {
            this.requires("2D, DOM, Text");
            this.css({
                "font-family": "Octicons",
                "font-size": "48px",
                "font-weight": "normal",
                'textShadow': '0px 2px 4px rgba(0,0,0,.5)'
                // 'textShadow': '0px 0px 8px rgba(0,0,0,.5), -1px -1px 0 #444,1px -1px 0 #444,-1px 1px 0 #444,1px 1px 0 #444'
                // 'textShadow': '0px 0px 8px rgba(0,0,0,.5), -1px -1px 0 #fc0,1px -1px 0 #fc0,-1px 1px 0 #fc0,1px 1px 0 #fc0'
            });
            // .text("&#xF220");
        }
    });
    Crafty.c('SpaceFont', {
        init: function () {
            this.requires('2D, DOM, Text');
            this.textFont({ family: 'Jura', size: '11px', weight: 'normal' })
            this.textColor('white')
            this.css({
                // "font-family": "Jura",
                // "font-size": "18px",
                // "font-weight": "normal",
                'textShadow': '0px 2px 4px rgba(0,0,0,.5)'
            });
        }
    });

    /************************************************************************
     * Loading Scene
     */
    Crafty.scene("loading", function () {
        Crafty.background('#005564');

        var text = Crafty.e('2D, DOM, Text, SpaceFont')
        .attr({x: 85, y: 150, w: Crafty.viewport.width })
        .textFont({size: '20px'})
        .textColor('white')
        .text('Establishing secure com...');

        var percent = Crafty.e('2D, DOM, Text, SpaceFont')
        .attr({x: 180, y: 180, w: 150 })
        .textFont({size: '20px'})
        .textColor('white')
        .text('0%');

        var bgovr = Crafty.e('2D, Canvas, Color, Tween, Delay').attr({
            x: 0,
            y: 0,
            z: -1,
            w: Crafty.viewport.width,
            h: Crafty.viewport.height,
            alpha: 0
        }).color('white');

        Crafty.paths({ audio: "assets/sfx/", images: "assets/images/" });
        var assets = {
            images: ['splash_screen.jpg', 'cratfy_logo.png', 'gameoff.jpg', 'wall01.png', 'backgrounds.png', 'starsky.png',
                'audioOn.png', 'audioOff.png', 'musicOn.png', 'musicOff.png'],
            sprites: {
                'ui_energy.png': {
                    tile: 72,
                    tileh: 19,
                    map: {HUDEnergy: [0, 0]}
                },
                'ui_health.png': {
                    tile: 69,
                    tileh: 19,
                    map: {HUDHealth4: [0, 0], HUDHealth3: [0, 1], HUDHealth2: [0, 2], HUDHealth1: [0, 3], HUDHealth0: [0, 4]}
                },
                'smoke_jump.png': {
                    tile: 64,
                    tileh: 64,
                    map: {SmokeJump: [0, 0]}
                },
                'platform.png': {
                    tile: 50,
                    tileh: 26,
                    map: {PlatformBlue: [0, 0], PlatformGreen: [1, 0]}
                },
                'platform_big.png': {
                    tile: 150,
                    tileh: 26,
                    map: {PlatformBlueBig: [0, 0], PlatformGreenBig: [0, 1]}
                },
                'door_anim.png': {
                    tile: 50,
                    tileh: 54,
                    paddingX: 3,
                    paddingY: 0,
                    map: {DoorAnim: [0, 0]}
                },
                'gunner.png': {
                    tile: 50,
                    tileh: 57,
                    map: {Gunner: [0, 0]}
                },
                'spikes.png': {
                    tile: 50,
                    tileh: 23,
                    map: {Spikes01: [0, 0], Spikes02: [1, 0]}
                },
                'bloodanim.png': {
                    tile: 76,
                    tileh: 45,
                    map: {Splatter: [0, 0]}
                },
                'spaceship.png': {
                    tile: 88,
                    tileh: 86,
                    map: {Spaceship: [0, 0]}
                },
               'spaceship_engine.png': {
                    tile: 18,
                    tileh: 18,
                    map: {SpaceshipEngine: [0, 0]}
                },
               'flares.png': {
                    tile: 18,
                    tileh: 17,
                    map: {Flares: [0, 0]}
                },
                'powerups.png': {
                    tile: 19,
                    tileh: 19,
                    map: {HealthRed: [0, 1], HealthGray: [1, 1], EnergyOrange: [0, 0], EnergyBlue: [3, 0]}
                },
                'enemy_turret.png': {
                    tile: 50,
                    tileh: 26,
                    map: {EnemyTurretGreen: [0, 0], EnemyTurretRed: [0, 1], EnemyTurretPurple: [0, 2]}
                },
                'enemy_bullet.png': {
                    tile: 10,
                    tileh: 10,
                    map: {EnemyBullet: [0, 0], EnemyBulletBlue: [0, 1], EnemyBulletGlow: [0, 2]}
                },
                'enemy_drone.png': {
                    tile: 50,
                    tileh: 50,
                    paddingX: 1,
                    paddingY: 1,
                    map: {EnemyDrone: [0, 0], EnemyDroneAdvanced: [2, 0], EnemyDroneDestroyer: [0, 1], EnemyDrone2: [2, 1]}
                },
                'xhair.png': {
                    tile: 46,
                    tileh: 46,
                    map: {Xhair: [0, 0]}
                },
                'explo01.png': {
                    tile: 34,
                    tileh: 30,
                    map: {ExplosionsYB: [0, 0]}
                },
                'explo02.png': {
                    tile: 33,
                    tileh: 31,
                    map: {ExplosionHit: [0, 0]}
                }
            },
            audio: {
                jump: ['land.ogg', 'land.m4a'],
                jumpboost: ['jumpboost.ogg', 'jumpboost.m4a'],
                land: ['landfeet.ogg', 'landfeet.m4a'],
                hurt: ['hurt.ogg', 'hurt.m4a'],
                death: ['death.ogg', 'death.m4a'],
                deathsplat: ['deathsplat.ogg', 'deathsplat.m4a'],
                turretshot1: ['turretshot.ogg', 'turretshot.m4a'],
                turretshot2: ['turretshot2.ogg', 'turretshot2.m4a'],
                explode1: ['explode.ogg', 'explode.m4a'],
                explode2: ['explode2.ogg', 'explode2.m4a'],
                droneshot1: ['droneshot.ogg', 'droneshot.m4a'],
                droneshot2: ['droneshot2.ogg', 'droneshot2.m4a'],
                gun1: ['gun01.ogg', 'gun01.m4a'],
                gun2: ['gun02.ogg', 'gun02.m4a'],
                gun3: ['gun03.ogg', 'gun03.m4a'],
                gunclip: ['gunclip.ogg', 'gunclip.m4a'],
                rico1: ['rico01.ogg', 'rico01.m4a'],
                rico2: ['rico02.ogg', 'rico02.m4a'],
                rico3: ['rico03.ogg', 'rico03.m4a'],
                warning: ['warning.ogg', 'warning.m4a'],
                doorshut: ['doorshut.ogg', 'doorshut.m4a'],
                powerup01: ['pup01.ogg', 'pup01.m4a'],
                powerup02: ['pup02.ogg', 'pup02.m4a'],
                overcharge: ['overcharge.ogg', 'overcharge.m4a'],
                movin: ['movin.ogg', 'movin.m4a'],
                liftoff: ['liftoff.ogg', 'liftoff.m4a'],
                liftoff2: ['liftoff2.ogg', 'liftoff2.m4a'],
                wait4mom: ['wait4urmom.ogg', 'wait4urmom.m4a'],
                music1: ['2ndtlegion.ogg']
            }
        };
        if (isSafari) {
            // disable sound under Safari, because Crafty has no m4a/mp4 support yet! :(
            console.log(isSafari);
            assets.audio = {};
            document.getElementsByClassName('sorry')[0].style.visibility = 'visible';
        }
        Crafty.load(assets, function() {
            if (skipIntro) {
                Crafty.scene('main');
            }
            bgovr.tween({alpha: 1.0}, 1800)
            .bind('TweenEnd', function () {
                Crafty.scene('intro');
            })
            .delay(function() {
                text.visible = false;
                percent.visible = false;
            }, 1000);
        }, function (e) {
            // console.log(e);
            percent.text(~~(e.percent) + '%');
        }, function (e) {
            console.log('ya blew it!');
            console.error(e);
        });
    });

    }); //eof-ready
}(Crafty));<commit_msg>Fix instrunctions screen not preloaded<commit_after>/**
 * Strider
 * Github Game-Off 2015 Entry
 * by Petar Petrov / github.com/petarov
 *
 * (A fork of) Octocat Jump
 * A Github Game Off 2012 Entry
 * @copyright Omer Goshen <gershon@goosemoose.com>
 */
(function(Crafty) {
    document.addEventListener('DOMContentLoaded', function () {

    var isSafari = !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/);
    console.log(navigator.userAgent);
    var STAGE_WIDTH = 400,
        STAGE_HEIGHT = 640,
        screen = document.getElementById('game'),
        skipIntro = false;

    Crafty.init(STAGE_WIDTH, STAGE_HEIGHT, screen).canvas.init();
    Crafty.viewport.init(STAGE_WIDTH, STAGE_HEIGHT, screen);
    Crafty.viewport.bounds = {
        min: { x:-100, y: -Infinity },
        max: { x: STAGE_WIDTH + 50, y: STAGE_HEIGHT }
    };
    // Crafty.viewport.clampToEntities = true;
    Crafty.settings.modify('autoPause', true);

    /**
     * Octicons font component
     * @see https://github.com/styleguide/css/7.0
     */
    Crafty.c("Octicons", {
        init: function () {
            this.requires("2D, DOM, Text");
            this.css({
                "font-family": "Octicons",
                "font-size": "48px",
                "font-weight": "normal",
                'textShadow': '0px 2px 4px rgba(0,0,0,.5)'
                // 'textShadow': '0px 0px 8px rgba(0,0,0,.5), -1px -1px 0 #444,1px -1px 0 #444,-1px 1px 0 #444,1px 1px 0 #444'
                // 'textShadow': '0px 0px 8px rgba(0,0,0,.5), -1px -1px 0 #fc0,1px -1px 0 #fc0,-1px 1px 0 #fc0,1px 1px 0 #fc0'
            });
            // .text("&#xF220");
        }
    });
    Crafty.c('SpaceFont', {
        init: function () {
            this.requires('2D, DOM, Text');
            this.textFont({ family: 'Jura', size: '11px', weight: 'normal' })
            this.textColor('white')
            this.css({
                // "font-family": "Jura",
                // "font-size": "18px",
                // "font-weight": "normal",
                'textShadow': '0px 2px 4px rgba(0,0,0,.5)'
            });
        }
    });

    /************************************************************************
     * Loading Scene
     */
    Crafty.scene("loading", function () {
        Crafty.background('#005564');

        var text = Crafty.e('2D, DOM, Text, SpaceFont')
        .attr({x: 85, y: 150, w: Crafty.viewport.width })
        .textFont({size: '20px'})
        .textColor('white')
        .text('Establishing secure com...');

        var percent = Crafty.e('2D, DOM, Text, SpaceFont')
        .attr({x: 180, y: 180, w: 150 })
        .textFont({size: '20px'})
        .textColor('white')
        .text('0%');

        var bgovr = Crafty.e('2D, Canvas, Color, Tween, Delay').attr({
            x: 0,
            y: 0,
            z: -1,
            w: Crafty.viewport.width,
            h: Crafty.viewport.height,
            alpha: 0
        }).color('white');

        Crafty.paths({ audio: "assets/sfx/", images: "assets/images/" });
        var assets = {
            images: ['splash_screen.jpg', 'splash_screen_blurred.jpg', 'cratfy_logo.png', 'gameoff.jpg', 'wall01.png',
                'backgrounds.png', 'starsky.png', 'audioOn.png', 'audioOff.png', 'musicOn.png', 'musicOff.png'],
            sprites: {
                'ui_energy.png': {
                    tile: 72,
                    tileh: 19,
                    map: {HUDEnergy: [0, 0]}
                },
                'ui_health.png': {
                    tile: 69,
                    tileh: 19,
                    map: {HUDHealth4: [0, 0], HUDHealth3: [0, 1], HUDHealth2: [0, 2], HUDHealth1: [0, 3], HUDHealth0: [0, 4]}
                },
                'smoke_jump.png': {
                    tile: 64,
                    tileh: 64,
                    map: {SmokeJump: [0, 0]}
                },
                'platform.png': {
                    tile: 50,
                    tileh: 26,
                    map: {PlatformBlue: [0, 0], PlatformGreen: [1, 0]}
                },
                'platform_big.png': {
                    tile: 150,
                    tileh: 26,
                    map: {PlatformBlueBig: [0, 0], PlatformGreenBig: [0, 1]}
                },
                'door_anim.png': {
                    tile: 50,
                    tileh: 54,
                    paddingX: 3,
                    paddingY: 0,
                    map: {DoorAnim: [0, 0]}
                },
                'gunner.png': {
                    tile: 50,
                    tileh: 57,
                    map: {Gunner: [0, 0]}
                },
                'spikes.png': {
                    tile: 50,
                    tileh: 23,
                    map: {Spikes01: [0, 0], Spikes02: [1, 0]}
                },
                'bloodanim.png': {
                    tile: 76,
                    tileh: 45,
                    map: {Splatter: [0, 0]}
                },
                'spaceship.png': {
                    tile: 88,
                    tileh: 86,
                    map: {Spaceship: [0, 0]}
                },
               'spaceship_engine.png': {
                    tile: 18,
                    tileh: 18,
                    map: {SpaceshipEngine: [0, 0]}
                },
               'flares.png': {
                    tile: 18,
                    tileh: 17,
                    map: {Flares: [0, 0]}
                },
                'powerups.png': {
                    tile: 19,
                    tileh: 19,
                    map: {HealthRed: [0, 1], HealthGray: [1, 1], EnergyOrange: [0, 0], EnergyBlue: [3, 0]}
                },
                'enemy_turret.png': {
                    tile: 50,
                    tileh: 26,
                    map: {EnemyTurretGreen: [0, 0], EnemyTurretRed: [0, 1], EnemyTurretPurple: [0, 2]}
                },
                'enemy_bullet.png': {
                    tile: 10,
                    tileh: 10,
                    map: {EnemyBullet: [0, 0], EnemyBulletBlue: [0, 1], EnemyBulletGlow: [0, 2]}
                },
                'enemy_drone.png': {
                    tile: 50,
                    tileh: 50,
                    paddingX: 1,
                    paddingY: 1,
                    map: {EnemyDrone: [0, 0], EnemyDroneAdvanced: [2, 0], EnemyDroneDestroyer: [0, 1], EnemyDrone2: [2, 1]}
                },
                'xhair.png': {
                    tile: 46,
                    tileh: 46,
                    map: {Xhair: [0, 0]}
                },
                'explo01.png': {
                    tile: 34,
                    tileh: 30,
                    map: {ExplosionsYB: [0, 0]}
                },
                'explo02.png': {
                    tile: 33,
                    tileh: 31,
                    map: {ExplosionHit: [0, 0]}
                }
            },
            audio: {
                jump: ['land.ogg', 'land.m4a'],
                jumpboost: ['jumpboost.ogg', 'jumpboost.m4a'],
                land: ['landfeet.ogg', 'landfeet.m4a'],
                hurt: ['hurt.ogg', 'hurt.m4a'],
                death: ['death.ogg', 'death.m4a'],
                deathsplat: ['deathsplat.ogg', 'deathsplat.m4a'],
                turretshot1: ['turretshot.ogg', 'turretshot.m4a'],
                turretshot2: ['turretshot2.ogg', 'turretshot2.m4a'],
                explode1: ['explode.ogg', 'explode.m4a'],
                explode2: ['explode2.ogg', 'explode2.m4a'],
                droneshot1: ['droneshot.ogg', 'droneshot.m4a'],
                droneshot2: ['droneshot2.ogg', 'droneshot2.m4a'],
                gun1: ['gun01.ogg', 'gun01.m4a'],
                gun2: ['gun02.ogg', 'gun02.m4a'],
                gun3: ['gun03.ogg', 'gun03.m4a'],
                gunclip: ['gunclip.ogg', 'gunclip.m4a'],
                rico1: ['rico01.ogg', 'rico01.m4a'],
                rico2: ['rico02.ogg', 'rico02.m4a'],
                rico3: ['rico03.ogg', 'rico03.m4a'],
                warning: ['warning.ogg', 'warning.m4a'],
                doorshut: ['doorshut.ogg', 'doorshut.m4a'],
                powerup01: ['pup01.ogg', 'pup01.m4a'],
                powerup02: ['pup02.ogg', 'pup02.m4a'],
                overcharge: ['overcharge.ogg', 'overcharge.m4a'],
                movin: ['movin.ogg', 'movin.m4a'],
                liftoff: ['liftoff.ogg', 'liftoff.m4a'],
                liftoff2: ['liftoff2.ogg', 'liftoff2.m4a'],
                wait4mom: ['wait4urmom.ogg', 'wait4urmom.m4a'],
                music1: ['2ndtlegion.ogg']
            }
        };
        if (isSafari) {
            // disable sound under Safari, because Crafty has no m4a/mp4 support yet! :(
            console.log(isSafari);
            assets.audio = {};
            document.getElementsByClassName('sorry')[0].style.visibility = 'visible';
        }
        Crafty.load(assets, function() {
            if (skipIntro) {
                Crafty.scene('main');
            }
            bgovr.tween({alpha: 1.0}, 1800)
            .bind('TweenEnd', function () {
                Crafty.scene('intro');
            })
            .delay(function() {
                text.visible = false;
                percent.visible = false;
            }, 1000);
        }, function (e) {
            // console.log(e);
            percent.text(~~(e.percent) + '%');
        }, function (e) {
            console.log('ya blew it!');
            console.error(e);
        });
    });

    }); //eof-ready
}(Crafty));<|endoftext|>