<commit_before>(function(Smb2, Constants, Debug, Protocol, Packet) {
    "use strict";

    // Constructor

    var ClientImpl = function(client) {
        this.protocol_ = new Protocol();

        this.client_ = client;
        this.comm_ = client.getCommunication();
    };

    // Public functions

    ClientImpl.prototype.handleNegotiateResponse = function(packet, onSuccess, onError) {
        var session = this.client_.getSession();
        var header = packet.getHeader();
        if (checkError.call(this, header, onError)) {
            var negotiateResponse =
                    this.protocol_.parseNegotiateResponse(packet);
            if (negotiateResponse.getDialectRevision() !== Constants.DIALECT_SMB_2_002_REVISION) {
                onError("Supported dialect not found");
            } else {
                session.setMaxBufferSize(
                    negotiateResponse.getMaxReadSize());
                onSuccess(header, negotiateResponse);
            }
        }
    };

    ClientImpl.prototype.sessionSetup = function(negotiateResponse, userName, password, domainName, onSuccess, onError) {
        sendType1Message.call(this, negotiateResponse, function(
            header, sessionSetupResponse) {

            var type2Message = sessionSetupResponse.getType2Message();
            Debug.outputType2MessageFlags(type2Message);

            sendType3Message.call(this, userName, password, domainName, negotiateResponse, sessionSetupResponse, function() {
                onSuccess();
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    /*jslint bitwise: true */
    ClientImpl.prototype.getSharedResourceList = function(onSuccess, onError) {
        var errorHandler = function(error) {
            console.log(error);
            onError(error);
        }.bind(this);

        connectTree.call(this, "IPC$", function(
            treeConnectResponseHeader, treeConnectResponse) {
            Debug.log(treeConnectResponseHeader);
            Debug.log(treeConnectResponse);
            var options = {
                desiredAccess:
                    Constants.GENERIC_WRITE | Constants.GENERIC_READ,
                fileAttributes:
                    Constants.SMB2_FILE_ATTRIBUTE_NORMAL,
                shareAccess:
                    Constants.FILE_SHARE_READ |
                    Constants.FILE_SHARE_WRITE,
                createDisposition: Constants.FILE_OPEN,
                name: "\\srvsvc",
                createContexts: [
                    this.protocol_.createCreateContext(0, Constants.SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST, null)
                ]
            };
            create.call(this, options, function(
                createResponseHeader, createResponse) {
                Debug.log(createResponseHeader);
                Debug.log(createResponse);
                var fid = createResponse.getFileId();
                dceRpcBind.call(this, fid, function(
                    dceRpcBindResponseHeader, dceRpcBindAck) {
                    Debug.log(dceRpcBindResponseHeader);
                    Debug.log(dceRpcBindAck);
                    netShareEnumAll.call(this, fid, function(
                        dceRpcNetShareEnumAllResponseHeader, dceRpcNetShareEnumAllResponse) {
                        Debug.log(dceRpcNetShareEnumAllResponseHeader);
                        Debug.log(dceRpcNetShareEnumAllResponse);
                        close.call(this, fid, function(closeResponseHeader) {
                            Debug.log(closeResponseHeader);
                            onSuccess(dceRpcNetShareEnumAllResponse.getNetShareEnums());
                        }.bind(this), errorHandler);
                    }.bind(this), errorHandler);
                }.bind(this), errorHandler);
            }.bind(this), errorHandler);
        }.bind(this), errorHandler);
    };

    // Private functions

    var checkError = function(header, onError, expected) {
        var errorCode = header.getStatus();
        if (expected) {
            if (errorCode === expected) {
                return true;
            } else {
                onError(Number(errorCode).toString(16) + ": " + Debug.getNtStatusMessage(errorCode));
                return false;
            }
        } else {
            if (errorCode === Constants.NT_STATUS_OK) {
                return true;
            } else if (errorCode === Constants.STATUS_BUFFER_OVERFLOW) {
                // Normal for DCERPC named pipes
                Debug.info("0x80000005: STATUS_BUFFER_OVERFLOW: Normal for DCERPC named pipes. Ignore.");
                return true;
            } else {
                onError(Number(errorCode).toString(16) + ": " + Debug.getNtStatusMessage(errorCode));
                return false;
            }
        }
    };

    var sendType1Message = function(negotiateResponse, onSuccess, onError) {
        var session = this.client_.getSession();
        var sessionSetupRequestPacket =
                this.protocol_.createSessionSetupRequestType1Packet(
                    session, negotiateResponse);
        Debug.log(sessionSetupRequestPacket);
        this.comm_.writePacket(sessionSetupRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                Debug.log(header);
                if (checkError.call(this, header, onError,
                                    Constants.NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                    var sessionSetupResponse =
                            this.protocol_.parseSessionSetupResponse(packet);
                    session.setUserId(header.getSessionId());
                    onSuccess(header, sessionSetupResponse);
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    var sendType3Message = function(userName, password, domainName, negotiateResponse, sessionSetupResponse, onSuccess, onError) {
        var session = this.client_.getSession();
        var sessionSetupRequestPacket =
                this.protocol_.createSessionSetupRequestType3Packet(
                    session, userName, password, domainName, negotiateResponse,
                    sessionSetupResponse.getType2Message());
        Debug.log(sessionSetupRequestPacket);
        this.comm_.writePacket(sessionSetupRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                if (checkError.call(this, header, onError)) {
                    onSuccess();
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    var connectTree = function(name, onSuccess, onError) {
        var session = this.client_.getSession();
        var treeConnectRequestPacket =
                this.protocol_.createTreeConnectRequestPacket(
                    session, name);
        Debug.log(treeConnectRequestPacket);
        this.comm_.writePacket(treeConnectRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                if (checkError.call(this, header, onError)) {
                    session.setTreeId(header.getTreeId());
                    var treeConnectResponse =
                            this.protocol_.parseTreeConnectResponse(packet);
                    onSuccess(header, treeConnectResponse);
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    var create = function(options, onSuccess, onError) {
        var session = this.client_.getSession();
        var createRequestPacket = this.protocol_.createCreateRequestPacket(
            session, options);
        Debug.log(createRequestPacket);
        this.comm_.writePacket(createRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                if (checkError.call(this, header, onError)) {
                    var createResponse =
                            this.protocol_.parseCreateResponse(packet);
                    onSuccess(header, createResponse);
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    var dceRpcBind = function(fid, onSuccess, onError) {
        var session = this.client_.getSession();
        var dceRpcBindRequestPacket = this.protocol_.createDceRpcBindRequestPacket(session, fid);
        Debug.log(dceRpcBindRequestPacket);
        this.comm_.writePacket(dceRpcBindRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                if (checkError.call(this, header, onError)) {
                    var dceRpcBindAck = this.protocol_.parseDceRpcBindAckPacket(packet);
                    onSuccess(header, dceRpcBindAck);
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    // Export

    Smb2.ClientImpl = ClientImpl;

})(SmbClient.Smb2,
   SmbClient.Constants,
   SmbClient.Debug,
   SmbClient.Smb2.Protocol,
   SmbClient.Packet);
<commit_msg>Fixed the problem reported by jshint.<commit_after>(function(Smb2, Constants, Debug, Protocol, Packet) {
    "use strict";

    // Constructor

    var ClientImpl = function(client) {
        this.protocol_ = new Protocol();

        this.client_ = client;
        this.comm_ = client.getCommunication();
    };

    // Public functions

    ClientImpl.prototype.handleNegotiateResponse = function(packet, onSuccess, onError) {
        var session = this.client_.getSession();
        var header = packet.getHeader();
        if (checkError.call(this, header, onError)) {
            var negotiateResponse =
                    this.protocol_.parseNegotiateResponse(packet);
            if (negotiateResponse.getDialectRevision() !== Constants.DIALECT_SMB_2_002_REVISION) {
                onError("Supported dialect not found");
            } else {
                session.setMaxBufferSize(
                    negotiateResponse.getMaxReadSize());
                onSuccess(header, negotiateResponse);
            }
        }
    };

    ClientImpl.prototype.sessionSetup = function(negotiateResponse, userName, password, domainName, onSuccess, onError) {
        sendType1Message.call(this, negotiateResponse, function(
            header, sessionSetupResponse) {

            var type2Message = sessionSetupResponse.getType2Message();
            Debug.outputType2MessageFlags(type2Message);

            sendType3Message.call(this, userName, password, domainName, negotiateResponse, sessionSetupResponse, function() {
                onSuccess();
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    /*jslint bitwise: true */
    ClientImpl.prototype.getSharedResourceList = function(onSuccess, onError) {
        var errorHandler = function(error) {
            console.log(error);
            onError(error);
        }.bind(this);

        connectTree.call(this, "IPC$", function(
            treeConnectResponseHeader, treeConnectResponse) {
            Debug.log(treeConnectResponseHeader);
            Debug.log(treeConnectResponse);
            var options = {
                desiredAccess:
                    Constants.GENERIC_WRITE | Constants.GENERIC_READ,
                fileAttributes:
                    Constants.SMB2_FILE_ATTRIBUTE_NORMAL,
                shareAccess:
                    Constants.FILE_SHARE_READ |
                    Constants.FILE_SHARE_WRITE,
                createDisposition: Constants.FILE_OPEN,
                name: "\\srvsvc",
                createContexts: [
                    this.protocol_.createCreateContext(0, Constants.SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST, null)
                ]
            };
            create.call(this, options, function(
                createResponseHeader, createResponse) {
                Debug.log(createResponseHeader);
                Debug.log(createResponse);
                var fid = createResponse.getFileId();
                dceRpcBind.call(this, fid, function(
                    dceRpcBindResponseHeader, dceRpcBindAck) {
                    Debug.log(dceRpcBindResponseHeader);
                    Debug.log(dceRpcBindAck);
                    /*
                    netShareEnumAll.call(this, fid, function(
                        dceRpcNetShareEnumAllResponseHeader, dceRpcNetShareEnumAllResponse) {
                        Debug.log(dceRpcNetShareEnumAllResponseHeader);
                        Debug.log(dceRpcNetShareEnumAllResponse);
                        close.call(this, fid, function(closeResponseHeader) {
                            Debug.log(closeResponseHeader);
                            onSuccess(dceRpcNetShareEnumAllResponse.getNetShareEnums());
                        }.bind(this), errorHandler);
                    }.bind(this), errorHandler);
                    */
                }.bind(this), errorHandler);
            }.bind(this), errorHandler);
        }.bind(this), errorHandler);
    };

    // Private functions

    var checkError = function(header, onError, expected) {
        var errorCode = header.getStatus();
        if (expected) {
            if (errorCode === expected) {
                return true;
            } else {
                onError(Number(errorCode).toString(16) + ": " + Debug.getNtStatusMessage(errorCode));
                return false;
            }
        } else {
            if (errorCode === Constants.NT_STATUS_OK) {
                return true;
            } else if (errorCode === Constants.STATUS_BUFFER_OVERFLOW) {
                // Normal for DCERPC named pipes
                Debug.info("0x80000005: STATUS_BUFFER_OVERFLOW: Normal for DCERPC named pipes. Ignore.");
                return true;
            } else {
                onError(Number(errorCode).toString(16) + ": " + Debug.getNtStatusMessage(errorCode));
                return false;
            }
        }
    };

    var sendType1Message = function(negotiateResponse, onSuccess, onError) {
        var session = this.client_.getSession();
        var sessionSetupRequestPacket =
                this.protocol_.createSessionSetupRequestType1Packet(
                    session, negotiateResponse);
        Debug.log(sessionSetupRequestPacket);
        this.comm_.writePacket(sessionSetupRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                Debug.log(header);
                if (checkError.call(this, header, onError,
                                    Constants.NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                    var sessionSetupResponse =
                            this.protocol_.parseSessionSetupResponse(packet);
                    session.setUserId(header.getSessionId());
                    onSuccess(header, sessionSetupResponse);
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    var sendType3Message = function(userName, password, domainName, negotiateResponse, sessionSetupResponse, onSuccess, onError) {
        var session = this.client_.getSession();
        var sessionSetupRequestPacket =
                this.protocol_.createSessionSetupRequestType3Packet(
                    session, userName, password, domainName, negotiateResponse,
                    sessionSetupResponse.getType2Message());
        Debug.log(sessionSetupRequestPacket);
        this.comm_.writePacket(sessionSetupRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                if (checkError.call(this, header, onError)) {
                    onSuccess();
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    var connectTree = function(name, onSuccess, onError) {
        var session = this.client_.getSession();
        var treeConnectRequestPacket =
                this.protocol_.createTreeConnectRequestPacket(
                    session, name);
        Debug.log(treeConnectRequestPacket);
        this.comm_.writePacket(treeConnectRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                if (checkError.call(this, header, onError)) {
                    session.setTreeId(header.getTreeId());
                    var treeConnectResponse =
                            this.protocol_.parseTreeConnectResponse(packet);
                    onSuccess(header, treeConnectResponse);
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    var create = function(options, onSuccess, onError) {
        var session = this.client_.getSession();
        var createRequestPacket = this.protocol_.createCreateRequestPacket(
            session, options);
        Debug.log(createRequestPacket);
        this.comm_.writePacket(createRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                if (checkError.call(this, header, onError)) {
                    var createResponse =
                            this.protocol_.parseCreateResponse(packet);
                    onSuccess(header, createResponse);
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    var dceRpcBind = function(fid, onSuccess, onError) {
        var session = this.client_.getSession();
        var dceRpcBindRequestPacket = this.protocol_.createDceRpcBindRequestPacket(session, fid);
        Debug.log(dceRpcBindRequestPacket);
        this.comm_.writePacket(dceRpcBindRequestPacket, function() {
            this.comm_.readPacket(function(packet) {
                var header = packet.getHeader();
                if (checkError.call(this, header, onError)) {
                    var dceRpcBindAck = this.protocol_.parseDceRpcBindAckPacket(packet);
                    onSuccess(header, dceRpcBindAck);
                }
            }.bind(this), function(error) {
                onError(error);
            }.bind(this));
        }.bind(this), function(error) {
            onError(error);
        }.bind(this));
    };

    // Export

    Smb2.ClientImpl = ClientImpl;

})(SmbClient.Smb2,
   SmbClient.Constants,
   SmbClient.Debug,
   SmbClient.Smb2.Protocol,
   SmbClient.Packet);
<|endoftext|>


<commit_before>Meteor.startup(function(){
	Session.set('lsiSuccess',0);
});

Template.contributeLSI.events = {
	'change select[name=language]': function(event,template){
		Session.set('submitLanguage',event.currentTarget.value);
	},
	'click button[name=dismissal]':function(){
		Session.set('lsiSuccess',0);
	},
	'click button[name=submitCode]': function(event,template){
		event.preventDefault();
		var algo = Session.get('lastAlgoSearch');
		var aid = algo.AiD;
		var code = template.find('textarea[name=lsi]').value;
		var language = Session.get('submitLanguage');
		if(!(Match.test(code,String))){
			return;
		}
		code = escapeHTML(code);
		if(_.isBlank(language)){
			Session.set('lsiSuccess',1);
			return;
		}
		if(_.isBlank(code)){
			Session.set('lsiSuccess',3);
			return;
		}
		var makeid = aid+Meteor.user()._id+language+moment().unix();
		var lsiObj = {
			_id: makeid,
			Code: code,
			Contributor: Meteor.user()._id,
			pAiD: aid,
			Approve: [],
			Disapprove: [],
			Language: language,
			When: moment().unix()
		}
		Meteor.call('uploadLSI',lsiObj,Meteor.user()._id);
		Meteor.call('approve',Meteor.user()._id,makeid);
		Session.set('lsiSuccess',2);
		Router.go('lsiSearchRoute',{algo:aid,lang:"showAll",search:makeid},Meteor.user()._id);
		var message = {
			Sender: "Thanks for the code!",
			Text: "The community just got a little better!"
		}
		Meteor.call('sendNotification',Meteor.user().username,message);
	}
}

Template.contributeLSI.language = function(){
	return Languages.find();
}

Template.contributeLSI.selectedLanguage = function(name){
	if(Session.equals('submitLanguage',name)){
		return "selected";
	}
	return "";
}

Template.contributeLSI.Algo = function(){
	return Session.get('lastAlgoSearch');
}

Template.contributeLSI.isError = function(){
	if(Session.equals('lsiSuccess',1)){
		return true;
	}
	if(Session.equals('lsiSuccess',3)){
		return true;
	}
	return false;
}

Template.contributeLSI.getTheError = function(){
	if(Session.equals('lsiSuccess',1)){
		return "Please select a valid language.";
	}
	else{
		return "Please enter code.";
	}
}

function escapeHTML(s) {
	return s.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
}
<commit_msg>don't escape code entries<commit_after>Meteor.startup(function(){
	Session.set('lsiSuccess',0);
});

Template.contributeLSI.events = {
	'change select[name=language]': function(event,template){
		Session.set('submitLanguage',event.currentTarget.value);
	},
	'click button[name=dismissal]':function(){
		Session.set('lsiSuccess',0);
	},
	'click button[name=submitCode]': function(event,template){
		event.preventDefault();
		var algo = Session.get('lastAlgoSearch');
		var aid = algo.AiD;
		var code = template.find('textarea[name=lsi]').value;
		var language = Session.get('submitLanguage');
		if(!(Match.test(code,String))){
			return;
		}
		if(_.isBlank(language)){
			Session.set('lsiSuccess',1);
			return;
		}
		if(_.isBlank(code)){
			Session.set('lsiSuccess',3);
			return;
		}
		var makeid = aid+Meteor.user()._id+language+moment().unix();
		var lsiObj = {
			_id: makeid,
			Code: code,
			Contributor: Meteor.user()._id,
			pAiD: aid,
			Approve: [],
			Disapprove: [],
			Language: language,
			When: moment().unix()
		}
		Meteor.call('uploadLSI',lsiObj,Meteor.user()._id);
		Meteor.call('approve',Meteor.user()._id,makeid);
		Session.set('lsiSuccess',2);
		Router.go('lsiSearchRoute',{algo:aid,lang:"showAll",search:makeid},Meteor.user()._id);
		var message = {
			Sender: "Thanks for the code!",
			Text: "The community just got a little better!"
		}
		Meteor.call('sendNotification',Meteor.user().username,message);
	}
}

Template.contributeLSI.language = function(){
	return Languages.find();
}

Template.contributeLSI.selectedLanguage = function(name){
	if(Session.equals('submitLanguage',name)){
		return "selected";
	}
	return "";
}

Template.contributeLSI.Algo = function(){
	return Session.get('lastAlgoSearch');
}

Template.contributeLSI.isError = function(){
	if(Session.equals('lsiSuccess',1)){
		return true;
	}
	if(Session.equals('lsiSuccess',3)){
		return true;
	}
	return false;
}

Template.contributeLSI.getTheError = function(){
	if(Session.equals('lsiSuccess',1)){
		return "Please select a valid language.";
	}
	else{
		return "Please enter code.";
	}
}
<|endoftext|>


<commit_before>var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
var UglifyJSPlugin = require('uglifyjs-webpack-plugin')

var env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new UglifyJSPlugin({
      sourceMap: true
    }),
    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css')
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: {
        safe: true
      }
    }),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: config.build.index,
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // keep module.id stable when vender modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module, count) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),
    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})

if (config.build.productionGzip) {
  var CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

if (config.build.bundleAnalyzerReport) {
  var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig
<commit_msg>Small fix build<commit_after>var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
var UglifyJSPlugin = require('uglifyjs-webpack-plugin')

var env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new UglifyJSPlugin({
      sourceMap: true
    }),
    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css')
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: {
        safe: true
      }
    }),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: config.build.index,
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // keep module.id stable when vender modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module, count) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),
    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      },
      {
        from: path.resolve(__dirname, '../_redirects'),
        to: config.build.assetsRoot
      }
    ])
  ]
})

if (config.build.productionGzip) {
  var CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

if (config.build.bundleAnalyzerReport) {
  var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig
<|endoftext|>


<commit_before>// Amara, universalsubtitles.org
//
// Copyright (C) 2013 Participatory Culture Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see
// http://www.gnu.org/licenses/agpl-3.0.html.

(function() {

    var root = this;
    var _ = root._.noConflict();
    var $ = root.AmarajQuery;

    var LanguageSelectorController = function($scope, SubtitleStorage, SubtitleListFinder) {
        /**
         * This controller is responsible for the language and version selector
         * widget.  The widget allows the user to select a reference language and
         * version when translating subtitles into another language.
         *
         * The $scope contains 'languages' and 'versions'.  Each list is
         * represented in the UI as a <select> element.  The selected language or
         * version is stored on the $scope as a 'language' and 'version' model.
         *
         * Whenever the language selection is changed, we update the list of
         * versions.  When a new version is selected, we retrieve the subtitles
         * (either from memory or from the API via ajax) and display them in the
         * side panel.
         */

        $scope.languageSelectChanged = function(lang) {
            var vers, language;

            if (lang) {
                language = lang;
            } else {
                language = $scope.language;
            }

            if (!language) {
                return;
            }

            vers =_.sortBy(language.versions, function(item) {
                return item.version_no;
            });

            $scope.versions = vers.reverse();

            if (vers.length && vers.length > 0) {
                $scope.version = $scope.versions[0];
            }
        };
        $scope.setReferenceSubs = function(subtitlesXML) {
            if (!$scope.refSubList) {
                $scope.refSubList = SubtitleListFinder.get('reference-subtitle-set');
            }
            $scope.refSubList.scope.onSubtitlesFetched(subtitlesXML);
        };
        $scope.versionChanged = function(newVersion) {
            var subtitlesXML;

            if (!newVersion) {
                return;
            }
            subtitlesXML = newVersion.subtitlesXML;

            if (!subtitlesXML) {
                SubtitleStorage.getSubtitles($scope.language.code,
                                             newVersion.version_no,
                                             function(subtitlesXML) {
                    $scope.version.subtitlesXML = subtitlesXML;
                    $scope.setReferenceSubs(subtitlesXML);
                });
            } else {
                $scope.setReferenceSubs(subtitlesXML);
            }
        };

        SubtitleStorage.getLanguages(function(languages) {
            $scope.languages = languages;
            $scope.language = _.find(languages, function(item) {
                return item.editingLanguage;
            });
            $scope.languageSelectChanged($scope.language);
        });

        $scope.$watch('version', $scope.versionChanged);
    };
    var SaveSessionButtonController = function($scope, SubtitleListFinder) {

        $scope.cancel = function($event) {

            $event.preventDefault();

            // TODO: Need a redirect URL.
        };
        $scope.saveAndExit = function($event) {

            $event.preventDefault();

            $scope.saveSession().then(function(response) {
                if ($scope.status === 'saved') {

                    $scope.$root.$emit('show-loading-modal', 'Subtitles saved! Redirecting…');
                    window.location = response['data']['site_url'];

                } else if ($scope.status === 'error') {
                    window.alert('Sorry, there was an error...');
                }
            });
        };
        $scope.saveSession = function() {
            if ($scope.status !== 'saving') {
                $scope.status = 'saving';

                var promise = SubtitleListFinder.get('working-subtitle-set').scope.saveSubtitles();

                promise.then(function onSuccess(response) {
                    $scope.status = 'saved';
                }, function onError() {
                    $scope.status = 'error';
                });

                return promise;
            }
        };
        $scope.toggleSaveDropdown = function($event) {
            $scope.dropdownOpen = !$scope.dropdownOpen;
            $event.preventDefault();
        };

        $scope.$root.$on('work-done', function() {
            $scope.canSave = '';
            $scope.$digest();
        });
    };
    var SubtitleListController = function($scope, $timeout, SubtitleStorage) {
        /**
         * Responsible for everything that touches subtitles as a group,
         * souch as populating the list with actual data, removing subs,
         * adding subs.
         * @param $scope
         * @param SubtitleStorage
         * @constructor
         */

        $scope.addSubtitle = function(index, attrs, content, focus) {

            // Add the subtitle directly to the DFXP instance.
            var newSubtitle = $scope.parser.addSubtitle(index, attrs, content);

            // If we want to focus the subtitle after it's been added, set
            // the index here.
            if (focus) {
                $scope.focusIndex = $scope.parser.getSubtitleIndex(newSubtitle, $scope.parser.getSubtitles().get());

            // Otherwise, reset the focusIndex.
            } else {
                $scope.focusIndex = null;
            }

            // Update the subtitles on the list scope.
            $scope.updateParserSubtitles();
        };
        $scope.getSubtitleListHeight = function() {
            return $(window).height() - 359;
        };
        $scope.getSubtitles = function(languageCode, versionNumber) {
            // if this version has no default source translation language
            // it will be empty, in which case we want to wait for user
            // interaction to request a reference subtitle set.
            if (!languageCode || !versionNumber) {
                $scope.status = 'idle';
                return;
            }
            $scope.status = 'loading';
            $scope.items = SubtitleStorage.getSubtitles(languageCode, versionNumber, function(subtitlesXML) {
                $scope.onSubtitlesFetched(subtitlesXML);
            });
        };
        $scope.onSubtitlesFetched = function (dfxpXML) {
            /**
             * Once we have the dfxp from the server,
             * massage the data as a simpler object and set it on the
             * template. Angular will pick up the change (from the broadcast)
             * and will re-render the UI.
             * @param dfxpXML
             */

            this.dfxpWrapper = new root.AmaraDFXPParser();
            this.dfxpWrapper.init(dfxpXML);

            $scope.parser = this.dfxpWrapper;
            $scope.subtitles = $scope.parser.getSubtitles().get();

            $scope.status = 'ready';

            // When we have subtitles for an editable set, tell the kids.
            $timeout(function() {
                if ($scope.isEditable) {
                    $scope.$broadcast('subtitlesFetched');
                }
            });
        };
        $scope.removeSubtitle = function(subtitle) {
            $scope.parser.removeSubtitle(subtitle);
            $scope.updateParserSubtitles();
        };
        $scope.saveSubtitles = function() {
            $scope.status = 'saving';
            return SubtitleStorage.saveSubtitles($scope.videoID,
                                          $scope.languageCode,
                                          $scope.parser.xmlToString(true, true));
        };
        $scope.setLanguageCode = function(languageCode) {
            $scope.languageCode = languageCode;
        };
        $scope.setVideoID = function(videoID) {
            $scope.videoID = videoID;
        };
        $scope.updateParserSubtitles = function() {
            $scope.subtitles = $scope.parser.getSubtitles().get();
        };

        $scope.$watch($scope.getSubtitleListHeight, function(newHeight) {
            $($('div.subtitles').height(newHeight));
        });

        window.onresize = function() {
            $scope.$digest();
        };
    };
    var SubtitleListHelperController = function($scope) {

        $scope.isEditingAny = false;

        $scope.$root.$on('editing', function() {
            $scope.isEditingAny = true;
            $scope.$digest();
        });
        $scope.$root.$on('editingDone', function() {
            $scope.isEditingAny = false;
            $scope.$digest();
        });
    };
    var SubtitleListItemController = function($scope) {
        /**
         * Responsible for actions on one subtitle: editing, selecting.
         * @param $scope
         * @constructor
         */

        var initialText;

        $scope.empty = false;
        $scope.isEditing = false;
        $scope.showStartTime = $scope.parser.startTimeFromNode($scope.subtitle) > 0;

        $scope.finishEditingMode = function(newValue) {

            $scope.isEditing = false;

            // Tell the root scope that we're no longer editing, now.
            $scope.$root.$emit('editingDone');

            var content = $scope.parser.content($scope.subtitle, newValue);

            if (content !== initialText) {
                $scope.$root.$emit('work-done');
            }
        };
        $scope.getSubtitleIndex = function() {
            return $scope.parser.getSubtitleIndex($scope.subtitle, $scope.subtitles);
        };
        $scope.startEditingMode = function() {

            initialText = $scope.parser.content($scope.subtitle);

            $scope.isEditing = true;

            // Tell the root scope that we're editing, now.
            $scope.$root.$emit('editing');

            return initialText;
        };

        $scope.$on('subtitlesFetched', function() {
            // When subtitles are first retrieved, we need to set up the amarasubtitle
            // on the video and bind to this scope.
            //
            // This will happen on the video controller. Just throw an event stating that
            // we're ready.

            $scope.$root.$emit('subtitleReady', $scope);
        });
    };

    root.LanguageSelectorController = LanguageSelectorController;
    root.SaveSessionButtonController = SaveSessionButtonController;
    root.SubtitleListController = SubtitleListController;
    root.SubtitleListHelperController = SubtitleListHelperController;
    root.SubtitleListItemController = SubtitleListItemController;

}).call(this);
<commit_msg>Wiring up cancel button on new editor.<commit_after>// Amara, universalsubtitles.org
//
// Copyright (C) 2013 Participatory Culture Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see
// http://www.gnu.org/licenses/agpl-3.0.html.

(function() {

    var root = this;
    var _ = root._.noConflict();
    var $ = root.AmarajQuery;

    var LanguageSelectorController = function($scope, SubtitleStorage, SubtitleListFinder) {
        /**
         * This controller is responsible for the language and version selector
         * widget.  The widget allows the user to select a reference language and
         * version when translating subtitles into another language.
         *
         * The $scope contains 'languages' and 'versions'.  Each list is
         * represented in the UI as a <select> element.  The selected language or
         * version is stored on the $scope as a 'language' and 'version' model.
         *
         * Whenever the language selection is changed, we update the list of
         * versions.  When a new version is selected, we retrieve the subtitles
         * (either from memory or from the API via ajax) and display them in the
         * side panel.
         */

        $scope.languageSelectChanged = function(lang) {
            var vers, language;

            if (lang) {
                language = lang;
            } else {
                language = $scope.language;
            }

            if (!language) {
                return;
            }

            vers =_.sortBy(language.versions, function(item) {
                return item.version_no;
            });

            $scope.versions = vers.reverse();

            if (vers.length && vers.length > 0) {
                $scope.version = $scope.versions[0];
            }
        };
        $scope.setReferenceSubs = function(subtitlesXML) {
            if (!$scope.refSubList) {
                $scope.refSubList = SubtitleListFinder.get('reference-subtitle-set');
            }
            $scope.refSubList.scope.onSubtitlesFetched(subtitlesXML);
        };
        $scope.versionChanged = function(newVersion) {
            var subtitlesXML;

            if (!newVersion) {
                return;
            }
            subtitlesXML = newVersion.subtitlesXML;

            if (!subtitlesXML) {
                SubtitleStorage.getSubtitles($scope.language.code,
                                             newVersion.version_no,
                                             function(subtitlesXML) {
                    $scope.version.subtitlesXML = subtitlesXML;
                    $scope.setReferenceSubs(subtitlesXML);
                });
            } else {
                $scope.setReferenceSubs(subtitlesXML);
            }
        };

        SubtitleStorage.getLanguages(function(languages) {
            $scope.languages = languages;
            $scope.language = _.find(languages, function(item) {
                return item.editingLanguage;
            });
            $scope.languageSelectChanged($scope.language);
        });

        $scope.$watch('version', $scope.versionChanged);
    };
    var SaveSessionButtonController = function($scope, SubtitleListFinder) {

        $scope.cancel = function($event) {

            $event.preventDefault();

            var subtitleListScope = SubtitleListFinder.get('working-subtitle-set').scope;

            $scope.$root.$emit('show-loading-modal', 'Canceled. Redirecting…');
            window.location = '/videos/' + subtitleListScope.videoID;

        };
        $scope.saveAndExit = function($event) {

            $event.preventDefault();

            $scope.saveSession().then(function(response) {
                if ($scope.status === 'saved') {

                    $scope.$root.$emit('show-loading-modal', 'Subtitles saved! Redirecting…');
                    window.location = response['data']['site_url'];

                } else if ($scope.status === 'error') {
                    window.alert('Sorry, there was an error...');
                }
            });
        };
        $scope.saveSession = function() {
            if ($scope.status !== 'saving') {
                $scope.status = 'saving';

                var promise = SubtitleListFinder.get('working-subtitle-set').scope.saveSubtitles();

                promise.then(function onSuccess(response) {
                    $scope.status = 'saved';
                }, function onError() {
                    $scope.status = 'error';
                });

                return promise;
            }
        };
        $scope.toggleSaveDropdown = function($event) {
            $scope.dropdownOpen = !$scope.dropdownOpen;
            $event.preventDefault();
        };

        $scope.$root.$on('work-done', function() {
            $scope.canSave = '';
            $scope.$digest();
        });
    };
    var SubtitleListController = function($scope, $timeout, SubtitleStorage) {
        /**
         * Responsible for everything that touches subtitles as a group,
         * souch as populating the list with actual data, removing subs,
         * adding subs.
         * @param $scope
         * @param SubtitleStorage
         * @constructor
         */

        $scope.addSubtitle = function(index, attrs, content, focus) {

            // Add the subtitle directly to the DFXP instance.
            var newSubtitle = $scope.parser.addSubtitle(index, attrs, content);

            // If we want to focus the subtitle after it's been added, set
            // the index here.
            if (focus) {
                $scope.focusIndex = $scope.parser.getSubtitleIndex(newSubtitle, $scope.parser.getSubtitles().get());

            // Otherwise, reset the focusIndex.
            } else {
                $scope.focusIndex = null;
            }

            // Update the subtitles on the list scope.
            $scope.updateParserSubtitles();
        };
        $scope.getSubtitleListHeight = function() {
            return $(window).height() - 359;
        };
        $scope.getSubtitles = function(languageCode, versionNumber) {
            // if this version has no default source translation language
            // it will be empty, in which case we want to wait for user
            // interaction to request a reference subtitle set.
            if (!languageCode || !versionNumber) {
                $scope.status = 'idle';
                return;
            }
            $scope.status = 'loading';
            $scope.items = SubtitleStorage.getSubtitles(languageCode, versionNumber, function(subtitlesXML) {
                $scope.onSubtitlesFetched(subtitlesXML);
            });
        };
        $scope.onSubtitlesFetched = function (dfxpXML) {
            /**
             * Once we have the dfxp from the server,
             * massage the data as a simpler object and set it on the
             * template. Angular will pick up the change (from the broadcast)
             * and will re-render the UI.
             * @param dfxpXML
             */

            this.dfxpWrapper = new root.AmaraDFXPParser();
            this.dfxpWrapper.init(dfxpXML);

            $scope.parser = this.dfxpWrapper;
            $scope.subtitles = $scope.parser.getSubtitles().get();

            $scope.status = 'ready';

            // When we have subtitles for an editable set, tell the kids.
            $timeout(function() {
                if ($scope.isEditable) {
                    $scope.$broadcast('subtitlesFetched');
                }
            });
        };
        $scope.removeSubtitle = function(subtitle) {
            $scope.parser.removeSubtitle(subtitle);
            $scope.updateParserSubtitles();
        };
        $scope.saveSubtitles = function() {
            $scope.status = 'saving';
            return SubtitleStorage.saveSubtitles($scope.videoID,
                                          $scope.languageCode,
                                          $scope.parser.xmlToString(true, true));
        };
        $scope.setLanguageCode = function(languageCode) {
            $scope.languageCode = languageCode;
        };
        $scope.setVideoID = function(videoID) {
            $scope.videoID = videoID;
        };
        $scope.updateParserSubtitles = function() {
            $scope.subtitles = $scope.parser.getSubtitles().get();
        };

        $scope.$watch($scope.getSubtitleListHeight, function(newHeight) {
            $($('div.subtitles').height(newHeight));
        });

        window.onresize = function() {
            $scope.$digest();
        };
    };
    var SubtitleListHelperController = function($scope) {

        $scope.isEditingAny = false;

        $scope.$root.$on('editing', function() {
            $scope.isEditingAny = true;
            $scope.$digest();
        });
        $scope.$root.$on('editingDone', function() {
            $scope.isEditingAny = false;
            $scope.$digest();
        });
    };
    var SubtitleListItemController = function($scope) {
        /**
         * Responsible for actions on one subtitle: editing, selecting.
         * @param $scope
         * @constructor
         */

        var initialText;

        $scope.empty = false;
        $scope.isEditing = false;
        $scope.showStartTime = $scope.parser.startTimeFromNode($scope.subtitle) > 0;

        $scope.finishEditingMode = function(newValue) {

            $scope.isEditing = false;

            // Tell the root scope that we're no longer editing, now.
            $scope.$root.$emit('editingDone');

            var content = $scope.parser.content($scope.subtitle, newValue);

            if (content !== initialText) {
                $scope.$root.$emit('work-done');
            }
        };
        $scope.getSubtitleIndex = function() {
            return $scope.parser.getSubtitleIndex($scope.subtitle, $scope.subtitles);
        };
        $scope.startEditingMode = function() {

            initialText = $scope.parser.content($scope.subtitle);

            $scope.isEditing = true;

            // Tell the root scope that we're editing, now.
            $scope.$root.$emit('editing');

            return initialText;
        };

        $scope.$on('subtitlesFetched', function() {
            // When subtitles are first retrieved, we need to set up the amarasubtitle
            // on the video and bind to this scope.
            //
            // This will happen on the video controller. Just throw an event stating that
            // we're ready.

            $scope.$root.$emit('subtitleReady', $scope);
        });
    };

    root.LanguageSelectorController = LanguageSelectorController;
    root.SaveSessionButtonController = SaveSessionButtonController;
    root.SubtitleListController = SubtitleListController;
    root.SubtitleListHelperController = SubtitleListHelperController;
    root.SubtitleListItemController = SubtitleListItemController;

}).call(this);
<|endoftext|>


<commit_before>module.exports = function(config) {
    var pkg = require('../package.json');
    var karmaConfig = {
        basePath: '..',
        browsers: ['PhantomJS'],
        frameworks: ['browserify', 'jasmine'],
        reporters: ['progress', 'coverage'],
        preprocessors: {
            'test/**/*.js': ['browserify'],
            '_site/*.html': ['html2js']
        },
        coverageReporter: {
            dir : 'test/coverage/',
            reporters: [
                { type: 'html',
                    subdir: function(browser) {
                        return browser.toLowerCase().split(/[ /-]/)[0];
                    },
                    watermarks: {
                        statements: [75, 85],
                        lines: [75, 85],
                        functions: [75, 85],
                        branches:[75, 85]
                    }},
                { type: 'json-summary', subdir: '.', file: 'summary.json' },
            ]
        },
        files: [
            {pattern: '_site/**/*.*', included: true, served: true, watched: true},
            'test/**/*.spec.js'
        ],
        exclude: [
            '**/*.png',
            '**/*.min.js',
            '**/*.requirejs.js',
            'bower_components/**/*',
            'node_modules/**/*'
        ]
    };
    karmaConfig.browser = pkg.browser || {};
    karmaConfig["browserify-shim"] = pkg["browserify-shim"] || {};
    karmaConfig.browserify = pkg.browserify || {};
    karmaConfig.browserify.transform = (karmaConfig.browserify.transform)
        ? karmaConfig.browserify.transform.push('istanbulify')
        : [ 'istanbulify' ];
    return config.set(karmaConfig);
};<commit_msg>fix karma if statement<commit_after>module.exports = function(config) {
    var pkg = require('../package.json');
    var karmaConfig = {
        basePath: '..',
        browsers: ['PhantomJS'],
        frameworks: ['browserify', 'jasmine'],
        reporters: ['progress', 'coverage'],
        preprocessors: {
            'test/**/*.js': ['browserify'],
            '_site/*.html': ['html2js']
        },
        coverageReporter: {
            dir : 'test/coverage/',
            reporters: [
                { type: 'html',
                    subdir: function(browser) {
                        return browser.toLowerCase().split(/[ /-]/)[0];
                    },
                    watermarks: {
                        statements: [75, 85],
                        lines: [75, 85],
                        functions: [75, 85],
                        branches:[75, 85]
                    }},
                { type: 'json-summary', subdir: '.', file: 'summary.json' },
            ]
        },
        files: [
            {pattern: '_site/**/*.*', included: true, served: true, watched: true},
            'test/**/*.spec.js'
        ],
        exclude: [
            '**/*.png',
            '**/*.min.js',
            '**/*.requirejs.js',
            'bower_components/**/*',
            'node_modules/**/*'
        ]
    };
    karmaConfig.browser = pkg.browser || {};
    karmaConfig["browserify-shim"] = pkg["browserify-shim"] || {};
    karmaConfig.browserify = pkg.browserify || {};
    if (karmaConfig.browserify.transform) {
        karmaConfig.browserify.transform.push('istanbulify'); //browserify-istanbul
    } else {
        karmaConfig.browserify.transform = [ 'istanbulify' ]; //browserify-istanbul
    }
    return config.set(karmaConfig);
};<|endoftext|>


<commit_before>// IDA unicode string view -> <mini>WEAKEST </mini> (there are others for
// strong, awful, etc)
// check the xrefs (should only be one)
// These are the strings we replace and this is the function we intercept.

var isPlayerCheck1 = scan('0F 85 ?? ?? ?? ?? 57 8B CE E8 ?? ?? ?? ?? 84 C0 75 76'); // This is from the function that calls the one we found.
var isPlayerCheck2 = scan('0F 84 ?? ?? ?? ?? 8B CE E8 ?? ?? ?? ?? 84 C0 0F 85 ?? ?? ?? ?? 8B CE E8 ?? ?? ?? ?? 84 C0 0F 85 ?? ?? ?? ?? 8B 06'); // This is in the function we found near the top.
var isLocalPlayerCheck = scan('0F 85 ?? ?? ?? ?? 89 5D F0 C7 45 ?? ?? ?? ?? ?? 89 5D E8'); // this is in the function we found right before the switch.
var switchptr = scan('FF 24 85 ?? ?? ?? ?? 68 ?? ?? ?? ?? EB 1A 68 ?? ?? ?? ?? EB 13 68 ?? ?? ?? ?? EB 0C 68 ?? ?? ?? ?? EB 05 68 ?? ?? ?? ?? 8D 4D F0 E8 ?? ?? ?? ?? 6A 01'); // This is also in the function we found.

patch(isPlayerCheck1, [0x90, 0xE9]);
patch(isPlayerCheck2, Array(6).fill(0x90));
patch(isLocalPlayerCheck, Array(6).fill(0x90));

// Make room for our replacement strings.  We will write the cp to each one.
var strMem = allocateMemory(1000);

var weakestStr = strMem.add(0);
var weakStr = strMem.add(200);
var strongStr = strMem.add(400);
var awfulStr = strMem.add(600);
var bossStr = strMem.add(800);

Memory.protect(switchptr, 1000, 'rwx');

// Overwrite the location of the default strings with our new strings.
Memory.writePointer(switchptr.add(7 + 1), weakestStr);
Memory.writePointer(switchptr.add(7 + 8), weakStr);
Memory.writePointer(switchptr.add(7 + 15), strongStr);
Memory.writePointer(switchptr.add(7 + 22), awfulStr);
Memory.writePointer(switchptr.add(7 + 29), bossStr);

// Fix the jmptable so that people with similar cp show up as weak (otherwise
// they will skip over our strings).
var jmptable = Memory.readPointer(switchptr.add(3));

copy(jmptable.add(8), jmptable.add(4), 4);

Memory.protect(switchptr, 1000, 'r-x');

var createAltNameStr = scan('55 8B EC 6A FF 68 ?? ?? ?? ?? 64 A1 ?? ?? ?? ?? 50 83 EC 18 53 56 57 A1 ?? ?? ?? ?? 33 C5 50 8D 45 F4 64 A3 ?? ?? ?? ?? 8B F1 33 DB 89 5D E0');

Interceptor.attach(createAltNameStr, {
    onEnter(args) {
        // Follow through the execution of the function to find these offsets,
        // they are pretty easy to get.
        var thisPtr = this.context.ecx;
        var entPtr = Memory.readPointer(thisPtr.add(0x90));
        var cp = Memory.readFloat(entPtr.add(0x11c));

        Memory.writeUtf16String(weakestStr, cp.toFixed() + " <mini>WEAKEST </mini>");
        Memory.writeUtf16String(weakStr, cp.toFixed() + " <mini>WEAK </mini>");
        Memory.writeUtf16String(strongStr, cp.toFixed() + " <mini>STRONG </mini>");
        Memory.writeUtf16String(awfulStr, cp.toFixed() + " <mini>AWFUL </mini>");
        Memory.writeUtf16String(bossStr, cp.toFixed() + " <mini>BOSS </mini>");
    }
});

<commit_msg>Updated description<commit_after>// Description:
// Display Combat Power (CP) information when holding down ALT in numerical value as opposed to just ranking. (example: weakest White Spider > 50 weakest White Spider)

// Walkthrough:
// IDA unicode string view -> <mini>WEAKEST </mini> (there are others for
// strong, awful, etc)
// check the xrefs (should only be one)
// These are the strings we replace and this is the function we intercept.

var isPlayerCheck1 = scan('0F 85 ?? ?? ?? ?? 57 8B CE E8 ?? ?? ?? ?? 84 C0 75 76'); // This is from the function that calls the one we found.
var isPlayerCheck2 = scan('0F 84 ?? ?? ?? ?? 8B CE E8 ?? ?? ?? ?? 84 C0 0F 85 ?? ?? ?? ?? 8B CE E8 ?? ?? ?? ?? 84 C0 0F 85 ?? ?? ?? ?? 8B 06'); // This is in the function we found near the top.
var isLocalPlayerCheck = scan('0F 85 ?? ?? ?? ?? 89 5D F0 C7 45 ?? ?? ?? ?? ?? 89 5D E8'); // this is in the function we found right before the switch.
var switchptr = scan('FF 24 85 ?? ?? ?? ?? 68 ?? ?? ?? ?? EB 1A 68 ?? ?? ?? ?? EB 13 68 ?? ?? ?? ?? EB 0C 68 ?? ?? ?? ?? EB 05 68 ?? ?? ?? ?? 8D 4D F0 E8 ?? ?? ?? ?? 6A 01'); // This is also in the function we found.

patch(isPlayerCheck1, [0x90, 0xE9]);
patch(isPlayerCheck2, Array(6).fill(0x90));
patch(isLocalPlayerCheck, Array(6).fill(0x90));

// Make room for our replacement strings.  We will write the cp to each one.
var strMem = allocateMemory(1000);

var weakestStr = strMem.add(0);
var weakStr = strMem.add(200);
var strongStr = strMem.add(400);
var awfulStr = strMem.add(600);
var bossStr = strMem.add(800);

Memory.protect(switchptr, 1000, 'rwx');

// Overwrite the location of the default strings with our new strings.
Memory.writePointer(switchptr.add(7 + 1), weakestStr);
Memory.writePointer(switchptr.add(7 + 8), weakStr);
Memory.writePointer(switchptr.add(7 + 15), strongStr);
Memory.writePointer(switchptr.add(7 + 22), awfulStr);
Memory.writePointer(switchptr.add(7 + 29), bossStr);

// Fix the jmptable so that people with similar cp show up as weak (otherwise
// they will skip over our strings).
var jmptable = Memory.readPointer(switchptr.add(3));

copy(jmptable.add(8), jmptable.add(4), 4);

Memory.protect(switchptr, 1000, 'r-x');

var createAltNameStr = scan('55 8B EC 6A FF 68 ?? ?? ?? ?? 64 A1 ?? ?? ?? ?? 50 83 EC 18 53 56 57 A1 ?? ?? ?? ?? 33 C5 50 8D 45 F4 64 A3 ?? ?? ?? ?? 8B F1 33 DB 89 5D E0');

Interceptor.attach(createAltNameStr, {
    onEnter(args) {
        // Follow through the execution of the function to find these offsets,
        // they are pretty easy to get.
        var thisPtr = this.context.ecx;
        var entPtr = Memory.readPointer(thisPtr.add(0x90));
        var cp = Memory.readFloat(entPtr.add(0x11c));

        Memory.writeUtf16String(weakestStr, cp.toFixed() + " <mini>WEAKEST </mini>");
        Memory.writeUtf16String(weakStr, cp.toFixed() + " <mini>WEAK </mini>");
        Memory.writeUtf16String(strongStr, cp.toFixed() + " <mini>STRONG </mini>");
        Memory.writeUtf16String(awfulStr, cp.toFixed() + " <mini>AWFUL </mini>");
        Memory.writeUtf16String(bossStr, cp.toFixed() + " <mini>BOSS </mini>");
    }
});

<|endoftext|>


<commit_before>;

import angular from 'angular';
import 'ng-redux';
import chatTextFieldModule from './chat-textfield.js';
import postHeaderModule from './post-header.js';
import feedbackGridModule from './feedback-grid.js';
import postSeeksInfoModule from './post-seeks-info.js';
import postIsInfoModule from './post-is-info.js';
import labelledHrModule from './labelled-hr.js';

import {
    selectOpenPostUri,
    selectNeedByConnectionUri,
    selectLastUpdateTime,
} from '../selectors.js';
import {
    connect2Redux,
} from '../won-utils.js';
import {
    relativeTime,
} from '../won-label-utils.js';
import {
    attach,
    getIn,
} from '../utils.js';
import { actionCreators }  from '../actions/actions.js';

const serviceDependencies = ['$ngRedux', '$scope'];

function genComponentConf() {
    let template = `

                <svg style="--local-primary:var(--won-primary-color);"
                     class="post-info__header__icon clickable">
                    <use href="#ico36_close"></use>
                </svg>

            <won-post-header
                need-uri="self.postUriToConnectTo"
                timestamp="self.createdTimestamp"
                hide-image="::false">
            </won-post-header>
            <svg class="post-info__header__icon__small clickable"
                style="--local-primary:#var(--won-secondary-color);"
                ng-show="!self.contextMenuOpen"
                ng-click="self.contextMenuOpen = true">
                    <use href="#ico16_arrow_down"></use>
            </svg>

                      <svg class="post-info__header__icon__small__contextmenu clickable"
                        style="--local-primary:black;"
                        ng-click="self.contextMenuOpen = false">
                            <use href="#ico16_arrow_up"></use>
                      </svg>

                    <button ng-if="self.connection && self.connection.get('isRated')"
                        class="post-info__footer__button won-button--filled black"
                        ng-click="self.closeConnection()">
                            Remove This
                    </button>

                        <svg class="rdflink__small">
                            <use href="#rdf_logo_1"></use>
                        </svg>
                        Show RDF

            <won-gallery ng-show="self.suggestedPost.get('hasImages')">
            </won-gallery>

                Created

                {{ self.friendlyTimestamp }}

                <won-post-is-info is-part="::self.isPart"></won-post-is-info>

                <won-post-seeks-info seeks-part="::self.seeksPart"></won-post-seeks-info>

                    Know someone who might also be interested in this posting? Consider sharing the link below in social media.

                <input class="post-info__footer__link__input" value="{{self.linkToPost}}" disabled type="text">

            <won-labelled-hr label="::'Or'" class="post-info__footer__labelledhr"></won-labelled-hr>

            <won-feedback-grid ng-if="self.connection && !self.connection.get('isRated')" connection-uri="self.connectionUri"></won-feedback-grid>
            <chat-textfield
                placeholder="::'Request Message (optional)'"
                on-input="::self.input(value)"
                on-paste="::self.input(value)"
                on-submit="::self.sendRequest()"
                allow-empty-submit="true"
                submit-button-label="::'Ask to Chat'"
                ng-if="!self.connection || self.connection.get('isRated')"
                >
            </chat-textfield>

                    <svg class="rdflink__small">
                        <use href="#rdf_logo_1"></use>
                    </svg>
                    Show RDF

    `;

    class Controller {
        constructor() {
            attach(this, serviceDependencies, arguments);
            this.maxThumbnails = 9;
            this.message = '';
            this.WON = won.WON;
            window.openMatch4dbg = this;

            const selectFromState = (state) => {
                //const sendAdHocRequest = getIn(state, ['router', 'currentParams', 'sendAdHocRequest']); //if this parameter is set we will not have a connection to send this request to

                const connectionUri = decodeURIComponent(getIn(state, ['router', 'currentParams', 'connectionUri']));
                const ownNeed = connectionUri && selectNeedByConnectionUri(state, connectionUri);
                const connection = ownNeed && ownNeed.getIn(["connections", connectionUri]);
                const postUriToConnectTo = !connection ? selectOpenPostUri(state) : connection && connection.get("remoteNeedUri");

                const suggestedPost = state.getIn(["needs", postUriToConnectTo]);

                const is = suggestedPost? suggestedPost.get('is') : undefined;
                //TODO it will be possible to have more than one seeks
                const seeks = suggestedPost? suggestedPost.get('seeks') : undefined;

                return {
                    connection,
                    connectionUri,
                    ownNeed,
                    isPart: is? {
                        postUri: postUriToConnectTo,
                        is: is,
                        isString: 'is',
                        location: is && is.get('location'),
                        address: is.get('location') && is.get('location').get('address'),
                    }: undefined,
                    seeksPart: seeks? {
                        postUri: postUriToConnectTo,
                        seeks: seeks,
                        seeksString: 'seeks',
                        location: seeks && seeks.get('location'),
                        address: seeks.get('location') && seeks.get('location').get('address'),
                    }: undefined,
                    suggestedPost,
                    lastUpdateTimestamp: connection && connection.get('lastUpdateDate'),
                    connectionUri,
                    postUriToConnectTo,
                    linkToPost: suggestedPost && new URL("/owner/#!/post/?postUri="+encodeURI(suggestedPost.get('uri')), window.location.href).href,
                    friendlyTimestamp: suggestedPost && relativeTime(
                        selectLastUpdateTime(state),
                        suggestedPost.get('creationDate')
                    ),
                    createdTimestamp: suggestedPost && suggestedPost.get('creationDate'),
                }
            };
            connect2Redux(selectFromState, actionCreators, [], this);
        }

        input(userInput) {
            this.chatMessage = userInput;
        }

        sendRequest() {
            message = this.chatMessage;

            if(!this.connection || (this.ownNeed && this.ownNeed.get("isWhatsAround"))){
                if(this.ownNeed && this.ownNeed.get("isWhatsAround")){
                    //Close the connection if there was a present connection for a whatsaround need
                    this.connections__close(this.connectionUri);
                }

                if(this.postUriToConnectTo){
                    this.connections__connectAdHoc(this.postUriToConnectTo, message);
                }

                //this.router__stateGoCurrent({connectionUri: null, sendAdHocRequest: null});
                this.router__stateGoResetParams('connections');
            }else{
                this.needs__connect(
                		this.ownNeed.get("uri"),
                		this.connectionUri,
                		this.ownNeed.getIn(['connections',this.connectionUri]).get("remoteNeedUri"),
                		message);
                this.router__stateGoCurrent({connectionUri: this.connectionUri})
            }
        }

        closeConnection(){
            this.connections__close(this.connectionUri);
            this.router__stateGoCurrent({connectionUri: null});
        }
    }
    Controller.$inject = serviceDependencies;

    return {
        restrict: 'E',
        controller: Controller,
        controllerAs: 'self',
        bindToController: true, //scope-bindings -> ctrl
        scope: {
            includeHeader: '='
        },
        template: template
    }
}

export default angular.module('won.owner.components.sendRequest', [
    postIsInfoModule,
    postSeeksInfoModule,
    postHeaderModule,
    feedbackGridModule,
    labelledHrModule,
    chatTextFieldModule,
])
    .directive('wonSendRequest', genComponentConf)
    .name;

<commit_msg>Update send-request.js<commit_after>;

import angular from 'angular';
import 'ng-redux';
import chatTextFieldModule from './chat-textfield.js';
import postHeaderModule from './post-header.js';
import feedbackGridModule from './feedback-grid.js';
import postSeeksInfoModule from './post-seeks-info.js';
import postIsInfoModule from './post-is-info.js';
import labelledHrModule from './labelled-hr.js';

import {
    selectOpenPostUri,
    selectNeedByConnectionUri,
    selectLastUpdateTime,
} from '../selectors.js';
import {
    connect2Redux,
} from '../won-utils.js';
import {
    relativeTime,
} from '../won-label-utils.js';
import {
    attach,
    getIn,
} from '../utils.js';
import { actionCreators }  from '../actions/actions.js';

const serviceDependencies = ['$ngRedux', '$scope'];

function genComponentConf() {
    let template = `

                <svg style="--local-primary:var(--won-primary-color);"
                     class="post-info__header__icon clickable">
                    <use href="#ico36_close"></use>
                </svg>

            <won-post-header
                need-uri="self.postUriToConnectTo"
                timestamp="self.createdTimestamp"
                hide-image="::false">
            </won-post-header>
            <svg class="post-info__header__icon__small clickable"
                style="--local-primary:#var(--won-secondary-color);"
                ng-show="!self.contextMenuOpen"
                ng-click="self.contextMenuOpen = true">
                    <use href="#ico16_arrow_down"></use>
            </svg>

                      <svg class="post-info__header__icon__small__contextmenu clickable"
                        style="--local-primary:black;"
                        ng-click="self.contextMenuOpen = false">
                            <use href="#ico16_arrow_up"></use>
                      </svg>

                    <button ng-if="self.connection && self.connection.get('isRated')"
                        class="post-info__footer__button won-button--filled black"
                        ng-click="self.closeConnection()">
                            Remove This
                    </button>

                        <svg class="rdflink__small">
                            <use href="#rdf_logo_1"></use>
                        </svg>
                        Show RDF

            <won-gallery ng-show="self.suggestedPost.get('hasImages')">
            </won-gallery>

                Created

                {{ self.friendlyTimestamp }}

                <won-post-is-info is-part="::self.isPart"></won-post-is-info>

                <won-post-seeks-info seeks-part="::self.seeksPart"></won-post-seeks-info>

                    Know someone who might also be interested in this posting? Consider sharing the link below in social media.

                <input class="post-info__footer__link__input" value="{{self.linkToPost}}" disabled type="text">

            <won-labelled-hr label="::'Or'" class="post-info__footer__labelledhr"></won-labelled-hr>

            <won-feedback-grid ng-if="self.connection && !self.connection.get('isRated')" connection-uri="self.connectionUri"></won-feedback-grid>
            <chat-textfield
                placeholder="::'Request Message (optional)'"
                on-input="::self.input(value)"
                on-paste="::self.input(value)"
                on-submit="::self.sendRequest()"
                allow-empty-submit="true"
                submit-button-label="::'Ask to Chat'"
                ng-if="!self.connection || self.connection.get('isRated')"
                >
            </chat-textfield>

                    <svg class="rdflink__small">
                        <use href="#rdf_logo_1"></use>
                    </svg>
                    Show RDF

    `;

    class Controller {
        constructor() {
            attach(this, serviceDependencies, arguments);
            this.maxThumbnails = 9;
            this.message = '';
            this.WON = won.WON;
            window.openMatch4dbg = this;

            const selectFromState = (state) => {
                //const sendAdHocRequest = getIn(state, ['router', 'currentParams', 'sendAdHocRequest']); //if this parameter is set we will not have a connection to send this request to

                const connectionUri = decodeURIComponent(getIn(state, ['router', 'currentParams', 'connectionUri']));
                const ownNeed = connectionUri && selectNeedByConnectionUri(state, connectionUri);
                const connection = ownNeed && ownNeed.getIn(["connections", connectionUri]);
                const postUriToConnectTo = !connection ? selectOpenPostUri(state) : connection && connection.get("remoteNeedUri");

                const suggestedPost = state.getIn(["needs", postUriToConnectTo]);

                const is = suggestedPost? suggestedPost.get('is') : undefined;
                //TODO it will be possible to have more than one seeks
                const seeks = suggestedPost? suggestedPost.get('seeks') : undefined;

                return {
                    connection,
                    connectionUri,
                    ownNeed,
                    isPart: is? {
                        postUri: postUriToConnectTo,
                        is: is,
                        isString: 'is',
                        location: is && is.get('location'),
                        address: is.get('location') && is.get('location').get('address'),
                    }: undefined,
                    seeksPart: seeks? {
                        postUri: postUriToConnectTo,
                        seeks: seeks,
                        seeksString: 'seeks',
                        location: seeks && seeks.get('location'),
                        address: seeks.get('location') && seeks.get('location').get('address'),
                    }: undefined,
                    suggestedPost,
                    lastUpdateTimestamp: connection && connection.get('lastUpdateDate'),
                    connectionUri,
                    postUriToConnectTo,
                    linkToPost: suggestedPost && new URL("/owner/#!post/?postUri="+encodeURI(suggestedPost.get('uri')), window.location.href).href,
                    friendlyTimestamp: suggestedPost && relativeTime(
                        selectLastUpdateTime(state),
                        suggestedPost.get('creationDate')
                    ),
                    createdTimestamp: suggestedPost && suggestedPost.get('creationDate'),
                }
            };
            connect2Redux(selectFromState, actionCreators, [], this);
        }

        input(userInput) {
            this.chatMessage = userInput;
        }

        sendRequest() {
            message = this.chatMessage;

            if(!this.connection || (this.ownNeed && this.ownNeed.get("isWhatsAround"))){
                if(this.ownNeed && this.ownNeed.get("isWhatsAround")){
                    //Close the connection if there was a present connection for a whatsaround need
                    this.connections__close(this.connectionUri);
                }

                if(this.postUriToConnectTo){
                    this.connections__connectAdHoc(this.postUriToConnectTo, message);
                }

                //this.router__stateGoCurrent({connectionUri: null, sendAdHocRequest: null});
                this.router__stateGoResetParams('connections');
            }else{
                this.needs__connect(
                		this.ownNeed.get("uri"),
                		this.connectionUri,
                		this.ownNeed.getIn(['connections',this.connectionUri]).get("remoteNeedUri"),
                		message);
                this.router__stateGoCurrent({connectionUri: this.connectionUri})
            }
        }

        closeConnection(){
            this.connections__close(this.connectionUri);
            this.router__stateGoCurrent({connectionUri: null});
        }
    }
    Controller.$inject = serviceDependencies;

    return {
        restrict: 'E',
        controller: Controller,
        controllerAs: 'self',
        bindToController: true, //scope-bindings -> ctrl
        scope: {
            includeHeader: '='
        },
        template: template
    }
}

export default angular.module('won.owner.components.sendRequest', [
    postIsInfoModule,
    postSeeksInfoModule,
    postHeaderModule,
    feedbackGridModule,
    labelledHrModule,
    chatTextFieldModule,
])
    .directive('wonSendRequest', genComponentConf)
    .name;

<|endoftext|>