<commit_before>var inherit = require('..');

exports.testIsFunction = function(test) {
    test.equal(typeof inherit, 'function');
    test.done();
};

exports.testInstanceProperties = function(test) {
    var A = inherit({
        __constructor : function(val) {
            this.prop = val;
        }
    });

    test.equal(new A('test').prop, 'test');
    test.equal(new A('other').prop, 'other');
    test.done();
};

exports.testInstanceOf = function(test) {
    var A = inherit({}),
        B = inherit(A, {});

    test.ok(new A() instanceof A);
    test.ok(!(new A() instanceof B));
    test.ok(new B() instanceof A);
    test.ok(new B() instanceof B);
    test.done();
};

exports.testInstanceOfConstructorResult = function(test) {
    var A = inherit({}),
        B = inherit({
            __constructor : function(val) {
                return new A();
            }
        });

    test.ok(new B() instanceof A);
    test.done();
};

exports.testSelf = function(test) {
    var A = inherit({}),
        B = inherit(A, {});

    test.strictEqual(new A().__self, A);
    test.strictEqual(new B().__self, B);
    test.done();
};

exports.testInherit = function(test) {
    var A = inherit({
            method1 : function() {
                return 'A';
            }
        }),
        B = inherit(A, {
            method2 : function() {
                return 'B';
            }
        });

    test.equal(typeof new A().method2, 'undefined');
    test.equal(new B().method1(), 'A');
    test.done();
};

exports.testInheritFromPlaneFunction = function(test) {
    var A = function(val) {
            this.prop = val;
        },
        B = inherit(A, {});

    test.ok(new B() instanceof A);
    test.equal(new B('val').prop, 'val');
    test.done();
};

exports.testInheritAndBaseCallFromPlaneFunction = function(test) {
    var A = function(val) {
            this.prop = val;
        },
        B = inherit(A, {
            __constructor : function() {
                this.__base('fromB');
            }
        });

    test.ok(new B() instanceof A);
    test.equal(new B().prop, 'fromB');
    test.done();
};

exports.testStaticInherit = function(test) {
    var A = inherit({}, {
            method1 : function() {
                return 'A';
            }
        }),
        B = inherit(A, {}, {
            method2 : function() {
                return 'B';
            }
        });

    test.equal(typeof A.method2, 'undefined');
    test.equal(B.method1(), 'A');
    test.done();
};

exports.testOverride = function(test) {
    var A = inherit({
            method : function() {
                return 'A';
            }
        }),
        B = inherit(A, {
            method : function() {
                return 'B';
            }
        });

    test.equal(new A().method(), 'A');
    test.equal(new B().method(), 'B');
    test.done();
};

exports.testStaticOverride = function(test) {
    var A = inherit({}, {
            method : function() {
                return 'A';
            }
        }),
        B = inherit(A, {}, {
            method : function() {
                return 'B';
            }
        });

    test.equal(A.method(), 'A');
    test.equal(B.method(), 'B');
    test.done();
};

exports.testBase = function(test) {
    var A = inherit({
            method1 : function() {
                return 'A';
            }
        }),
        B = inherit(A, {
            method1 : function() {
                return this.__base() + 'B';
            },
            method2 : function() {
                return this.__base() + 'B2';
            }
        });

    test.equal(new B().method1(), 'AB');
    test.equal(new B().method2(), 'undefinedB2');
    test.done();
};

exports.testStaticBase = function(test) {
    var A = inherit({}, {
            staticMethod : function() {
                return 'A';
            }
        }),
        B = inherit(A, {}, {
            staticMethod : function() {
                return this.__base() + 'B';
            }
        });

    test.equal(B.staticMethod(), 'AB');
    test.done();
};

exports.testObjectMixin = function(test) {
    var A = inherit(),
        M = {
            methodM : function() {
                return 'M';
            }
        },
        B = inherit([A, M]);

    test.equal(new B().methodM(), 'M');
    test.done();
};

exports.testFunctionMixin = function(test) {
    var A = inherit(),
        M = inherit({
            methodM : function() {
                return 'M';
            }
        }),
        B = inherit([A, M]);

    test.equal(new B().methodM(), 'M');
    test.strictEqual(new B().__self, B);
    test.done();
};

exports.testFunctionMixinStatic = function(test) {
    var A = inherit(),
        M = inherit({}, {
            staticMethodM : function() {
                return 'M';
            }
        }),
        B = inherit([A, M]);

    test.equal(B.staticMethodM(), 'M');
    test.done();
};

exports.testBaseMocking = function(test) {
     var A = inherit({
            m : function() {
                return 'A';
            }
        }),
        B = inherit(A, {
            m : function() {
                return this.__base() + 'B';
            }
        });

     B.prototype.m.__base = function() { return 'C'; };

     var b = new B();

     test.equal(b.m(), 'CB');
     test.done();
};
<commit_msg>Add test coverage for inherit.self<commit_after>var inherit = require('..');

exports.testIsFunction = function(test) {
    test.equal(typeof inherit, 'function');
    test.done();
};

exports.testInstanceProperties = function(test) {
    var A = inherit({
        __constructor : function(val) {
            this.prop = val;
        }
    });

    test.equal(new A('test').prop, 'test');
    test.equal(new A('other').prop, 'other');
    test.done();
};

exports.testInstanceOf = function(test) {
    var A = inherit({}),
        B = inherit(A, {});

    test.ok(new A() instanceof A);
    test.ok(!(new A() instanceof B));
    test.ok(new B() instanceof A);
    test.ok(new B() instanceof B);
    test.done();
};

exports.testInstanceOfConstructorResult = function(test) {
    var A = inherit({}),
        B = inherit({
            __constructor : function(val) {
                return new A();
            }
        });

    test.ok(new B() instanceof A);
    test.done();
};

exports.testInstanceOfSelf = function(test) {
    var A = inherit({
        method : function () {
            return 'b';
        }
    });
    var B = inherit({
        propB : 'a'
    });
    var C = {
        propC : 'z'
    };
    var D = inherit.self([A, B, C], {
        method : function () {
            return this.__base() + this.propB + this.propC;
        }
    });

    test.equal(new D().method(), 'baz');
    test.done();
};

exports.testSelf = function(test) {
    var A = inherit({}),
        B = inherit(A, {});

    test.strictEqual(new A().__self, A);
    test.strictEqual(new B().__self, B);
    test.done();
};

exports.testInherit = function(test) {
    var A = inherit({
            method1 : function() {
                return 'A';
            }
        }),
        B = inherit(A, {
            method2 : function() {
                return 'B';
            }
        });

    test.equal(typeof new A().method2, 'undefined');
    test.equal(new B().method1(), 'A');
    test.done();
};

exports.testInheritFromPlaneFunction = function(test) {
    var A = function(val) {
            this.prop = val;
        },
        B = inherit(A, {});

    test.ok(new B() instanceof A);
    test.equal(new B('val').prop, 'val');
    test.done();
};

exports.testInheritAndBaseCallFromPlaneFunction = function(test) {
    var A = function(val) {
            this.prop = val;
        },
        B = inherit(A, {
            __constructor : function() {
                this.__base('fromB');
            }
        });

    test.ok(new B() instanceof A);
    test.equal(new B().prop, 'fromB');
    test.done();
};

exports.testStaticInherit = function(test) {
    var A = inherit({}, {
            method1 : function() {
                return 'A';
            }
        }),
        B = inherit(A, {}, {
            method2 : function() {
                return 'B';
            }
        });

    test.equal(typeof A.method2, 'undefined');
    test.equal(B.method1(), 'A');
    test.done();
};

exports.testOverride = function(test) {
    var A = inherit({
            method : function() {
                return 'A';
            }
        }),
        B = inherit(A, {
            method : function() {
                return 'B';
            }
        });

    test.equal(new A().method(), 'A');
    test.equal(new B().method(), 'B');
    test.done();
};

exports.testStaticOverride = function(test) {
    var A = inherit({}, {
            method : function() {
                return 'A';
            }
        }),
        B = inherit(A, {}, {
            method : function() {
                return 'B';
            }
        });

    test.equal(A.method(), 'A');
    test.equal(B.method(), 'B');
    test.done();
};

exports.testBase = function(test) {
    var A = inherit({
            method1 : function() {
                return 'A';
            }
        }),
        B = inherit(A, {
            method1 : function() {
                return this.__base() + 'B';
            },
            method2 : function() {
                return this.__base() + 'B2';
            }
        });

    test.equal(new B().method1(), 'AB');
    test.equal(new B().method2(), 'undefinedB2');
    test.done();
};

exports.testStaticBase = function(test) {
    var A = inherit({}, {
            staticMethod : function() {
                return 'A';
            }
        }),
        B = inherit(A, {}, {
            staticMethod : function() {
                return this.__base() + 'B';
            }
        });

    test.equal(B.staticMethod(), 'AB');
    test.done();
};

exports.testObjectMixin = function(test) {
    var A = inherit(),
        M = {
            methodM : function() {
                return 'M';
            }
        },
        B = inherit([A, M]);

    test.equal(new B().methodM(), 'M');
    test.done();
};

exports.testFunctionMixin = function(test) {
    var A = inherit(),
        M = inherit({
            methodM : function() {
                return 'M';
            }
        }),
        B = inherit([A, M]);

    test.equal(new B().methodM(), 'M');
    test.strictEqual(new B().__self, B);
    test.done();
};

exports.testFunctionMixinStatic = function(test) {
    var A = inherit(),
        M = inherit({}, {
            staticMethodM : function() {
                return 'M';
            }
        }),
        B = inherit([A, M]);

    test.equal(B.staticMethodM(), 'M');
    test.done();
};

exports.testBaseMocking = function(test) {
     var A = inherit({
            m : function() {
                return 'A';
            }
        }),
        B = inherit(A, {
            m : function() {
                return this.__base() + 'B';
            }
        });

     B.prototype.m.__base = function() { return 'C'; };

     var b = new B();

     test.equal(b.m(), 'CB');
     test.done();
};
<|endoftext|>


<commit_before>var win = Ti.UI.currentWindow;

var ServerHandler = require('/includes/ServerHandler');
Ti.include('/includes/lib/json.i18n.js');

var isMcStyle = Ti.App.Properties.getBool('mcStyledUI', true);

var tableView = require('/includes/PullToRefresh')({
	style: Ti.UI.iPhone.TableViewStyle.PLAIN,
	scrollIndicatorStyle: Ti.UI.iPhone.ScrollIndicatorStyle.WHITE,
	editable: true
});

if(isMcStyle) {
	tableView.setSeparatorColor('#4b4b4b');
	tableView.setBackgroundImage('/img/full-bg.png');
}

win.add(tableView);

function updateList() {
	//opening the database containing the servers that we will display
	var db = Ti.Database.open('servers');
	var servers = db.execute('SELECT * FROM servers');
	//erase the existing tableview entries
	tableView.setData([]);
	//this index corresponds to the tableviewrow id
	var i = 0;

	if(servers.rowCount < 1) {
		tableView.appendRow(ServerHandler.getEmptyPlaceholderRow());
	} else {
		//loop through the servers
		while(servers.isValidRow()) {
			//getting all the data corresponding to the row, it will be useful later
			var data = {
				name: servers.fieldByName('name'),
				host: servers.fieldByName('host'),
				port: servers.fieldByName('port'),
				sqlid: servers.fieldByName('id'),
				id: i
			};

			try {
				//create temporary row, that will say "polling server..."
				ServerHandler.getRow(data, i, function(e) {
					tableView.appendRow(e.row);
				}, ServerHandler.state.POLLING);

				//get real info
				ServerHandler.getServerInfo(data, i, function(e) {
					e.row.data = e.data;
					//update the existing temporary row and update it in consequence
					tableView.updateRow(e.index, e.row);
				});
			} catch(e) {
				alert("Uh oh, I think something went terribly wrong. :(\nI'm working on this issue, but for now you can restart the app.");
			}

			//next server, next row
			servers.next();
			i++;
		}
	}

	//we're done with the database
	servers.close();
}

Ti.App.addEventListener('reload', updateList);

tableView.addEventListener('delete', function(e) {
	var db = Ti.Database.open('servers');
	db.execute('DELETE FROM servers WHERE id=?', e.rowData.data.sqlid);
	db.close();
});

var b_add = Ti.UI.createButton({
	image: '/img/add.png',
	backgroundImage: '/img/menubar-button.png'
});

b_add.addEventListener('click', function(e) {
	var win_add = Ti.UI.createWindow({
		url: 'add.js',
		title: I('addServer.title'),
		barImage: '/img/menubar.png',
		backgroundImage: '/img/full-bg.png'
	});

	win_add.addEventListener('close', function(e) {
		updateList();
	});

	win_add.open({
		modal: true
	});
});

var b_edit = Ti.UI.createButton({
	image: '/img/edit.png',
	backgroundImage: '/img/menubar-button.png'
});

var b_done = Ti.UI.createButton({
	image: '/img/check.png',
	backgroundImage: '/img/menubar-button.png'
});

var b_info = Ti.UI.createButton({
	image: '/img/info.png',
	backgroundImage: '/img/menubar-button.png'
});

b_edit.addEventListener('click', function(e) {
	tableView.setEditing(true);
	win.setLeftNavButton(b_done, {
		animated: true
	});
	win.setRightNavButton(b_add, {
		animated: true
	});
});

b_done.addEventListener('click', function(e) {
	tableView.setEditing(false);
	win.setLeftNavButton(b_edit, {
		animated: true
	});
	win.setRightNavButton(b_info, {
		animated: true
	});
});

b_info.addEventListener('click', function(e) {
	var win_info = Ti.UI.createWindow({
		url: 'credits.js',
		title: I('credits.title'),
		barImage: '/img/menubar.png',
		backgroundImage: '/img/full-bg.png'
	});

	win_info.open({
		modal: true
	});
});

win.setRightNavButton(b_info);
win.setLeftNavButton(b_edit);

var view_ad = Ti.UI.iOS.createAdView({
	adSize: Ti.UI.iOS.AD_SIZE_PORTRAIT,
	bottom: 0
});

win.add(view_ad);
updateList();
<commit_msg>Stop editing before reloading<commit_after>var win = Ti.UI.currentWindow;

var ServerHandler = require('/includes/ServerHandler');
Ti.include('/includes/lib/json.i18n.js');

var isMcStyle = Ti.App.Properties.getBool('mcStyledUI', true);

var tableView = require('/includes/PullToRefresh')({
	style: Ti.UI.iPhone.TableViewStyle.PLAIN,
	scrollIndicatorStyle: Ti.UI.iPhone.ScrollIndicatorStyle.WHITE,
	editable: true
});

if(isMcStyle) {
	tableView.setSeparatorColor('#4b4b4b');
	tableView.setBackgroundImage('/img/full-bg.png');
}

win.add(tableView);

function updateList() {
	//opening the database containing the servers that we will display
	var db = Ti.Database.open('servers');
	var servers = db.execute('SELECT * FROM servers');
	//erase the existing tableview entries
	tableView.setData([]);
	tableView.setEditing(false);
	//this index corresponds to the tableviewrow id
	var i = 0;

	if(servers.rowCount < 1) {
		tableView.appendRow(ServerHandler.getEmptyPlaceholderRow());
	} else {
		//loop through the servers
		while(servers.isValidRow()) {
			//getting all the data corresponding to the row, it will be useful later
			var data = {
				name: servers.fieldByName('name'),
				host: servers.fieldByName('host'),
				port: servers.fieldByName('port'),
				sqlid: servers.fieldByName('id'),
				id: i
			};

			try {
				//create temporary row, that will say "polling server..."
				ServerHandler.getRow(data, i, function(e) {
					tableView.appendRow(e.row);
				}, ServerHandler.state.POLLING);

				//get real info
				ServerHandler.getServerInfo(data, i, function(e) {
					e.row.data = e.data;
					//update the existing temporary row and update it in consequence
					tableView.updateRow(e.index, e.row);
				});
			} catch(e) {
				alert("Uh oh, I think something went terribly wrong. :(\nI'm working on this issue, but for now you can restart the app.");
			}

			//next server, next row
			servers.next();
			i++;
		}
	}

	//we're done with the database
	servers.close();
}

Ti.App.addEventListener('reload', updateList);

tableView.addEventListener('delete', function(e) {
	var db = Ti.Database.open('servers');
	db.execute('DELETE FROM servers WHERE id=?', e.rowData.data.sqlid);
	db.close();
});

var b_add = Ti.UI.createButton({
	image: '/img/add.png',
	backgroundImage: '/img/menubar-button.png'
});

b_add.addEventListener('click', function(e) {
	var win_add = Ti.UI.createWindow({
		url: 'add.js',
		title: I('addServer.title'),
		barImage: '/img/menubar.png',
		backgroundImage: '/img/full-bg.png'
	});

	win_add.addEventListener('close', function(e) {
		updateList();
	});

	win_add.open({
		modal: true
	});
});

var b_edit = Ti.UI.createButton({
	image: '/img/edit.png',
	backgroundImage: '/img/menubar-button.png'
});

var b_done = Ti.UI.createButton({
	image: '/img/check.png',
	backgroundImage: '/img/menubar-button.png'
});

var b_info = Ti.UI.createButton({
	image: '/img/info.png',
	backgroundImage: '/img/menubar-button.png'
});

b_edit.addEventListener('click', function(e) {
	tableView.setEditing(true);
	win.setLeftNavButton(b_done, {
		animated: true
	});
	win.setRightNavButton(b_add, {
		animated: true
	});
});

b_done.addEventListener('click', function(e) {
	tableView.setEditing(false);
	win.setLeftNavButton(b_edit, {
		animated: true
	});
	win.setRightNavButton(b_info, {
		animated: true
	});
});

b_info.addEventListener('click', function(e) {
	var win_info = Ti.UI.createWindow({
		url: 'credits.js',
		title: I('credits.title'),
		barImage: '/img/menubar.png',
		backgroundImage: '/img/full-bg.png'
	});

	win_info.open({
		modal: true
	});
});

win.setRightNavButton(b_info);
win.setLeftNavButton(b_edit);

var view_ad = Ti.UI.iOS.createAdView({
	adSize: Ti.UI.iOS.AD_SIZE_PORTRAIT,
	bottom: 0
});

win.add(view_ad);
updateList();
<|endoftext|>


<commit_before>/*
 * Spreed WebRTC.
 * Copyright (C) 2013-2015 struktur AG
 *
 * This file is part of Spreed WebRTC.
 *
 * 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/>.
 *
 */

define([ // Helper module to put non dependency base libraries together.
	'modernizr',
	'moment',
	'Howler',
	'desktop-notify',
	'bigscreen',
	'visibly',
	'avltree',
	'jed',
	'audiocontext',
	'rAF',
	'humanize',
	'sha',
	'sjcl',
	'text',
	'webfont'], function() {});
<commit_msg>Use webfonts.js in main to avoid load order error in built javascript.<commit_after>/*
 * Spreed WebRTC.
 * Copyright (C) 2013-2015 struktur AG
 *
 * This file is part of Spreed WebRTC.
 *
 * 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/>.
 *
 */

define([ // Helper module to put non dependency base libraries together.
	'modernizr',
	'moment',
	'Howler',
	'desktop-notify',
	'bigscreen',
	'visibly',
	'avltree',
	'jed',
	'audiocontext',
	'rAF',
	'humanize',
	'sha',
	'sjcl',
	'text'], function() {});
<|endoftext|>


<commit_before>'use strict';

var grunt = require('grunt');

/**
 * Constructs a test case.
 *
 * @param  {string}           file   The `package.json` file to be tested.
 * @param  {boolean}          valid  Flag indicating whether the test is
 *                                   expected to pass.
 * @param  {Array}            [args] Additional arguments to pass to `grunt`.
 * @return {function(Object)}        Testing function for `nodeunit`.
 */
function test(file, valid, args) {
    return function(test) {
        test.expect(2);

        grunt.util.spawn({
            grunt: true,
            args: [
                '--gruntfile', 'test/Gruntfile.js',
                '--pkgFile', file
            ].concat(args || []).concat('npm-validate')
        }, function(error, result, code) {
            if (valid) {
                test.ifError(error);
                test.equal(code, 0);
            } else {
                test.notEqual(error, null);
                test.notEqual(code, 0);
            }
            test.done();
        });
    };
}

module.exports = {
    empty: test('fixtures/empty.json', false),
    force: test('fixtures/empty.json', true, ['--force', true]),
    minimal: test('fixtures/minimal.json', true),
    package: test('../package.json', true),
    strict: test('fixtures/minimal.json', false, ['--strict', true])
};
<commit_msg>Use Google Closure style of marking function parameters as optional.<commit_after>'use strict';

var grunt = require('grunt');

/**
 * Constructs a test case.
 *
 * @param  {string}           file   The `package.json` file to be tested.
 * @param  {boolean}          valid  Flag indicating whether the test is
 *                                   expected to pass.
 * @param  {Array=}           args   Additional arguments to pass to `grunt`.
 * @return {function(Object)}        Testing function for `nodeunit`.
 */
function test(file, valid, args) {
    return function(test) {
        test.expect(2);

        grunt.util.spawn({
            grunt: true,
            args: [
                '--gruntfile', 'test/Gruntfile.js',
                '--pkgFile', file
            ].concat(args || []).concat('npm-validate')
        }, function(error, result, code) {
            if (valid) {
                test.ifError(error);
                test.equal(code, 0);
            } else {
                test.notEqual(error, null);
                test.notEqual(code, 0);
            }
            test.done();
        });
    };
}

module.exports = {
    empty: test('fixtures/empty.json', false),
    force: test('fixtures/empty.json', true, ['--force', true]),
    minimal: test('fixtures/minimal.json', true),
    package: test('../package.json', true),
    strict: test('fixtures/minimal.json', false, ['--strict', true])
};
<|endoftext|>


<commit_before>/**
 * pushState加载url对应的页面主体内容
 *
 * @param url
 */
function loadUrl(url) {
	$.ajax({
		"url" : blogInfo.pushUrl,
		"method" : "POST",
		"cache" : false,
		"dataType" : "json",
		"data" : {
			"url" : url
		},
		"success" : function(data) {
			document.title = data.title;
			$("#blog_center").animate({
				"opacity" : 0
			}, "fast", "swing", function() {
				$(this).html(data.blog_center);
				$("#blog_center").animate({
					"opacity" : 100
				}, "fast", "swing");
			});
		},
		"error" : function(jqXHR, textStatus, errorThrown) {
			$("#blog_center").html(
					"
ajax加载失败 "
							+ errorThrown + "
")
		}
	});
}
/**
 * 为链接绑定pushState方法
 */
$.fn.bindPushState = function() {
	$(this).click(function(evt) {
		if ("pushState" in history) {
			evt.preventDefault();
			history.pushState({
				"state_url" : this.href
			}, "", this.href);
			loadUrl(this.href);
		}
	});
	return $(this);
};
/**
 * 显示消息提示
 *
 * @param msgType
 * @param msg
 */
function alertMsg(msgType, msg) {
	var msgNode = $("
" + msg + "
");
	$("#main_div>div").prepend(msgNode);
	msgNode.fadeIn("fast", "linear", function() {
		$(this).delay(3500).fadeToggle(1500, "linear", function() {
			$(this).remove();
		});
	});
}
/**
 * 模态框消息
 *
 * @param msgType
 * @param title
 * @param msg
 */
function alertModal(msgType, title, msg) {
	var msgNode = $("
" + msg + "
");
	$("#msg_div .modal-title").html(title);
	$("#msg_div .modal-body").html(msgNode);
	$("#msg_div").modal("show");
}
/**
 * 获取验证码图片的URL
 *
 * @return string
 */
function getRcodeUrl() {
	return blogInfo.rcodeUrlTpl.replace(/\[rand\]/, Math.random());
}
/**
 * 用户登录和管理博客按钮的切换
 *
 * @param isLogin
 *            是否登录的状态int
 */
function updateUserArea(isLogin) {
	if (isLogin == 1)
		$("#user_area")
				.html(
						" 管理博客  ");
	else
		$("#user_area")
				.html(
						" 博主登录");
}
/**
 * 导航条激活位置切换
 *
 * @param selector
 */
function updateNav(selector) {
	$("#main_navbar a.active").removeAttr("class");
	$(selector).addClass("active");
}
/**
 * 登录博客页面，提交表单时触发
 */
function postLoginForm() {
	$
			.ajax({
				"url" : blogInfo.doLoginUrl,
				"method" : "POST",
				"cache" : false,
				"dataType" : "json",
				"data" : {
					"username" : $("#username").val(),
					"pass" : $("#pass").val(),
					"rcode" : $("#rcode").val()
				},
				"success" : function(data) {
					if (!data.success) {
						$("#login_err_tip").html(
								"出错了 " + data.msg).show();
						$("#rcode_img").attr("src", getRcodeUrl());
					} else {
						// 设置cookie
						var Days = 30, exp = new Date();
						exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
						document.cookie = "osid=" + data.osid + "; expires="
								+ exp.toGMTString() + "; path="
								+ blogInfo.blog_context;
						blogInfo.is_login = 1;
						updateUserArea(1);
						$('#login_div').modal('hide');
					}
				},
				"error" : function(jqXHR, textStatus, errorThrown) {
					$("#login_err_tip").html(
							"ajax加载失败 " + errorThrown).show();
				}
			});
}
/**
 * 准备就绪后博客执行的函数
 *
 * @param int
 *            nIndex 导航条当前的位置(从0开始)
 * @param function
 *            successFn 加载主体内容的函数
 *
 */
function blogInit(nIndex) {
	// 数据库连接提示
	if (blogInfo.conn_ok == 0)
		alertMsg("danger", "数据库连接失败");
	// 导航条
	$("#main_navbar a:eq(" + nIndex + ")").addClass("active");
	// 判断是否支持 pushState
	if ("pushState" in history) {
		// 浏览器前进、后退
		window.addEventListener('popstate', function(e) {
			if (history.state) {
				loadUrl(e.state.state_url);
			}
		}, false);
	}
	$("#main_navbar a").bindPushState().click(function() {
		updateNav(this);
	});
	// 管理连接生成
	var adminUrlarr = [ {
		"name" : "博客设置",
		"action" : "sets",
		"type" : 1
	}, {
		"name" : "分类管理",
		"action" : "types",
		"type" : 1
	}, {
		"name" : "标签管理 ",
		"action" : "tags",
		"type" : 1
	}, {
		"name" : "文件管理",
		"action" : "files",
		"type" : 1
	}, {
		"name" : "发表文章",
		"action" : "postTopic",
		"type" : 1
	}, {
		"type" : 0
	}, {
		"name" : "博客环境信息",
		"action" : "env",
		"type" : 1
	}, {
		"name" : "注销登录",
		"action" : "javascript:logoutConfirm()",
		"type" : 2
	}, ], adminListHtml = "", i;
	for (i = 0; i < adminUrlarr.length; i++) {
		if (adminUrlarr[i].type == 0)
			adminListHtml += "

";
		else if (adminUrlarr[i].type == 1) {
			adminListHtml += "
";
			adminListHtml += (""
					+ adminUrlarr[i].name + "");
			adminListHtml += "
";
		} else {
			adminListHtml += "
";
			adminListHtml += ("" + adminUrlarr[i].name + "");
			adminListHtml += "
";
		}
	}
	$("#admin_list").html(adminListHtml);
	$("#admin_list a:lt(6)").bindPushState();
	/* 更新登录状态 */
	updateUserArea(blogInfo.is_login);
	/* 登录界面代码生成 */
	var loginDivBody = "<form class=\"form-horizontal\">", loginDivFooter = "<button type=\"button\" class=\"btn btn-default\"\
								data-dismiss=\"modal\">取消</button>\
							<button id=\"login_btn\" type=\"button\" class=\"btn btn-primary\">登录博客</button>";
	loginDivBody += "
\

\

登录错误提示
\

\

\

\
		用户名\

\
			<input type=\"text\" class=\"form-control\" id=\"username\"\
				placeholder=\"用户名\">\

\

\

\
		密码\

\
			<input type=\"password\" class=\"form-control\" id=\"pass\"\
				placeholder=\"密码\">\

\

\

\
		验证码\

\
			<input type=\"text\" class=\"form-control\" id=\"rcode\"\
				placeholder=\"验证码\">\

\

\

\
				换一张？\

\

\

\

\

\
			\

\

";
	loginDivBody += "</form>";
	$("#login_div").html(
			createModalDiv(blogInfo.blogname + "-登录", loginDivBody,
					loginDivFooter));
	/* 消息提示模态框 */
	$("#msg_div").html(
			createModalDiv("Modal title",
					"

",
					""));
	/* 登录界面验证码刷新 */
	var reloadRcode = function() {
		$("#rcode_img").attr("src", getRcodeUrl());
	}
	$("#rcode_img").click(reloadRcode);
	$("#rcode_new").click(reloadRcode);

	$("#login_div input").focus(function() {
		$("#login_err_tip").hide();
	}).keydown(function(event) {
		if (event.which == 13) {
			event.preventDefault();
			postLoginForm();
		}
	});
	$("#login_btn").click(postLoginForm);

	$("#user_area").click(function() {
		if (blogInfo.is_login == 1)
			$(this).parent().toggleClass("open");
		else
			$("#login_div").modal("show");// 弹窗要求登录
	}).parent().mouseenter(function() {
		if (blogInfo.is_login == 1)
			$(this).addClass("open");
	}).mouseleave(function() {
		if (blogInfo.is_login == 1)
			$(this).removeClass("open");
	});
}
function logoutConfirm() {
	var r;
	if (arguments.length > 0)
		r = arguments[0];
	else
		r = confirm("你确定要退出吗?");
	if (r == true) {
		// 删除cookie
		var Days = 5, exp = new Date();
		exp.setTime(exp.getTime() - Days * 24 * 60 * 60 * 1000);
		document.cookie = "osid=123; expires=" + exp.toGMTString() + "; path="
				+ blogInfo.blog_context;
		location.href = blogInfo.logoutUrl;
	}
}
function getCookie(c_name) {
	if (document.cookie.length > 0) {
		c_start = document.cookie.indexOf(c_name + "=")
		if (c_start != -1) {
			c_start = c_start + c_name.length + 1
			c_end = document.cookie.indexOf(";", c_start)
			if (c_end == -1)
				c_end = document.cookie.length
			return unescape(document.cookie.substring(c_start, c_end))
		}
	}
	return ""
}
function loadJsFile(jsFile, fn) {
	var oHead = document.getElementsByTagName("head")[0];
	var jsObject = document.createElement("SCRIPT");
	jsObject.type = "text/javascript";
	jsObject.src = jsFile;
	jsObject.defer = "defer";
	jsObject.onload = fn;
	oHead.appendChild(jsObject);
}
/**
 * 模态框代码生成
 *
 * @param modal_title
 *            标题
 * @param modal_body
 *            内容部分
 * @param modal_footer
 *            底部
 * @returns String
 */
function createModalDiv(modal_title, modal_body, modal_footer) {
	var divHtml = "
\

\

\
							<button type=\"button\" class=\"close\" data-dismiss=\"modal\"\
								aria-label=\"Close\">\
								×\
							</button>\

"
			+ modal_title + "
\

";
	divHtml += ("
" + modal_body + "
");
	if (modal_footer != "")
		divHtml += ("
" + modal_footer + "
");
	divHtml += "

";
	return divHtml;
}
/**
 * 刷新右侧的区域
 */
function refreshRight() {
	$.ajax({
		"url" : blogInfo.refreshRUrl,
		"method" : "POST",
		"cache" : false,
		"dataType" : "json",
		"success" : function(data) {
			$("#blog_right").animate({
				"opacity" : 0
			}, "fast", "swing", function() {
				$(this).html(data.html);
				$("#blog_right").animate({
					"opacity" : 100
				}, "fast", "swing");
			});
		},
		"error" : function(jqXHR, textStatus, errorThrown) {
		}
	});
}<commit_msg>修复伪静态时，不能注销的问题<commit_after>/**
 * pushState加载url对应的页面主体内容
 *
 * @param url
 */
function loadUrl(url) {
	$.ajax({
		"url" : blogInfo.pushUrl,
		"method" : "POST",
		"cache" : false,
		"dataType" : "json",
		"data" : {
			"url" : url
		},
		"success" : function(data) {
			document.title = data.title;
			$("#blog_center").animate({
				"opacity" : 0
			}, "fast", "swing", function() {
				$(this).html(data.blog_center);
				$("#blog_center").animate({
					"opacity" : 100
				}, "fast", "swing");
			});
		},
		"error" : function(jqXHR, textStatus, errorThrown) {
			$("#blog_center").html(
					"
ajax加载失败 "
							+ errorThrown + "
")
		}
	});
}
/**
 * 为链接绑定pushState方法
 */
$.fn.bindPushState = function() {
	$(this).click(function(evt) {
		if ("pushState" in history) {
			evt.preventDefault();
			history.pushState({
				"state_url" : this.href
			}, "", this.href);
			loadUrl(this.href);
		}
	});
	return $(this);
};
/**
 * 显示消息提示
 *
 * @param msgType
 * @param msg
 */
function alertMsg(msgType, msg) {
	var msgNode = $("
" + msg + "
");
	$("#main_div>div").prepend(msgNode);
	msgNode.fadeIn("fast", "linear", function() {
		$(this).delay(3500).fadeToggle(1500, "linear", function() {
			$(this).remove();
		});
	});
}
/**
 * 模态框消息
 *
 * @param msgType
 * @param title
 * @param msg
 */
function alertModal(msgType, title, msg) {
	var msgNode = $("
" + msg + "
");
	$("#msg_div .modal-title").html(title);
	$("#msg_div .modal-body").html(msgNode);
	$("#msg_div").modal("show");
}
/**
 * 获取验证码图片的URL
 *
 * @return string
 */
function getRcodeUrl() {
	return blogInfo.rcodeUrlTpl.replace(/\[rand\]/, Math.random());
}
/**
 * 用户登录和管理博客按钮的切换
 *
 * @param isLogin
 *            是否登录的状态int
 */
function updateUserArea(isLogin) {
	if (isLogin == 1)
		$("#user_area")
				.html(
						" 管理博客  ");
	else
		$("#user_area")
				.html(
						" 博主登录");
}
/**
 * 导航条激活位置切换
 *
 * @param selector
 */
function updateNav(selector) {
	$("#main_navbar a.active").removeAttr("class");
	$(selector).addClass("active");
}
/**
 * 登录博客页面，提交表单时触发
 */
function postLoginForm() {
	$
			.ajax({
				"url" : blogInfo.doLoginUrl,
				"method" : "POST",
				"cache" : false,
				"dataType" : "json",
				"data" : {
					"username" : $("#username").val(),
					"pass" : $("#pass").val(),
					"rcode" : $("#rcode").val()
				},
				"success" : function(data) {
					if (!data.success) {
						$("#login_err_tip").html(
								"出错了 " + data.msg).show();
						$("#rcode_img").attr("src", getRcodeUrl());
					} else {
						// 设置cookie
						var Days = 30, exp = new Date();
						exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
						document.cookie = "osid=" + data.osid + "; expires="
								+ exp.toGMTString() + "; path=/";
						blogInfo.is_login = 1;
						updateUserArea(1);
						$('#login_div').modal('hide');
					}
				},
				"error" : function(jqXHR, textStatus, errorThrown) {
					$("#login_err_tip").html(
							"ajax加载失败 " + errorThrown).show();
				}
			});
}
/**
 * 准备就绪后博客执行的函数
 *
 * @param int
 *            nIndex 导航条当前的位置(从0开始)
 * @param function
 *            successFn 加载主体内容的函数
 *
 */
function blogInit(nIndex) {
	// 数据库连接提示
	if (blogInfo.conn_ok == 0)
		alertMsg("danger", "数据库连接失败");
	// 导航条
	$("#main_navbar a:eq(" + nIndex + ")").addClass("active");
	// 判断是否支持 pushState
	if ("pushState" in history) {
		// 浏览器前进、后退
		window.addEventListener('popstate', function(e) {
			if (history.state) {
				loadUrl(e.state.state_url);
			}
		}, false);
	}
	$("#main_navbar a").bindPushState().click(function() {
		updateNav(this);
	});
	// 管理连接生成
	var adminUrlarr = [ {
		"name" : "博客设置",
		"action" : "sets",
		"type" : 1
	}, {
		"name" : "分类管理",
		"action" : "types",
		"type" : 1
	}, {
		"name" : "标签管理 ",
		"action" : "tags",
		"type" : 1
	}, {
		"name" : "文件管理",
		"action" : "files",
		"type" : 1
	}, {
		"name" : "发表文章",
		"action" : "postTopic",
		"type" : 1
	}, {
		"type" : 0
	}, {
		"name" : "博客环境信息",
		"action" : "env",
		"type" : 1
	}, {
		"name" : "注销登录",
		"action" : "javascript:logoutConfirm()",
		"type" : 2
	}, ], adminListHtml = "", i;
	for (i = 0; i < adminUrlarr.length; i++) {
		if (adminUrlarr[i].type == 0)
			adminListHtml += "

";
		else if (adminUrlarr[i].type == 1) {
			adminListHtml += "
";
			adminListHtml += (""
					+ adminUrlarr[i].name + "");
			adminListHtml += "
";
		} else {
			adminListHtml += "
";
			adminListHtml += ("" + adminUrlarr[i].name + "");
			adminListHtml += "
";
		}
	}
	$("#admin_list").html(adminListHtml);
	$("#admin_list a:lt(6)").bindPushState();
	/* 更新登录状态 */
	updateUserArea(blogInfo.is_login);
	/* 登录界面代码生成 */
	var loginDivBody = "<form class=\"form-horizontal\">", loginDivFooter = "<button type=\"button\" class=\"btn btn-default\"\
								data-dismiss=\"modal\">取消</button>\
							<button id=\"login_btn\" type=\"button\" class=\"btn btn-primary\">登录博客</button>";
	loginDivBody += "
\

\

登录错误提示
\

\

\

\
		用户名\

\
			<input type=\"text\" class=\"form-control\" id=\"username\"\
				placeholder=\"用户名\">\

\

\

\
		密码\

\
			<input type=\"password\" class=\"form-control\" id=\"pass\"\
				placeholder=\"密码\">\

\

\

\
		验证码\

\
			<input type=\"text\" class=\"form-control\" id=\"rcode\"\
				placeholder=\"验证码\">\

\

\

\
				换一张？\

\

\

\

\

\
			\

\

";
	loginDivBody += "</form>";
	$("#login_div").html(
			createModalDiv(blogInfo.blogname + "-登录", loginDivBody,
					loginDivFooter));
	/* 消息提示模态框 */
	$("#msg_div").html(
			createModalDiv("Modal title",
					"

",
					""));
	/* 登录界面验证码刷新 */
	var reloadRcode = function() {
		$("#rcode_img").attr("src", getRcodeUrl());
	}
	$("#rcode_img").click(reloadRcode);
	$("#rcode_new").click(reloadRcode);

	$("#login_div input").focus(function() {
		$("#login_err_tip").hide();
	}).keydown(function(event) {
		if (event.which == 13) {
			event.preventDefault();
			postLoginForm();
		}
	});
	$("#login_btn").click(postLoginForm);

	$("#user_area").click(function() {
		if (blogInfo.is_login == 1)
			$(this).parent().toggleClass("open");
		else
			$("#login_div").modal("show");// 弹窗要求登录
	}).parent().mouseenter(function() {
		if (blogInfo.is_login == 1)
			$(this).addClass("open");
	}).mouseleave(function() {
		if (blogInfo.is_login == 1)
			$(this).removeClass("open");
	});
}
function logoutConfirm() {
	var r;
	if (arguments.length > 0)
		r = arguments[0];
	else
		r = confirm("你确定要退出吗?");
	if (r == true) {
		// 删除cookie
		var Days = 5, exp = new Date();
		exp.setTime(exp.getTime() - Days * 24 * 60 * 60 * 1000);
		document.cookie = "osid=123; expires=" + exp.toGMTString() + "; path=/";
		location.href = blogInfo.logoutUrl;
	}
}
function getCookie(c_name) {
	if (document.cookie.length > 0) {
		c_start = document.cookie.indexOf(c_name + "=")
		if (c_start != -1) {
			c_start = c_start + c_name.length + 1
			c_end = document.cookie.indexOf(";", c_start)
			if (c_end == -1)
				c_end = document.cookie.length
			return unescape(document.cookie.substring(c_start, c_end))
		}
	}
	return ""
}
function loadJsFile(jsFile, fn) {
	var oHead = document.getElementsByTagName("head")[0];
	var jsObject = document.createElement("SCRIPT");
	jsObject.type = "text/javascript";
	jsObject.src = jsFile;
	jsObject.defer = "defer";
	jsObject.onload = fn;
	oHead.appendChild(jsObject);
}
/**
 * 模态框代码生成
 *
 * @param modal_title
 *            标题
 * @param modal_body
 *            内容部分
 * @param modal_footer
 *            底部
 * @returns String
 */
function createModalDiv(modal_title, modal_body, modal_footer) {
	var divHtml = "
\

\

\
							<button type=\"button\" class=\"close\" data-dismiss=\"modal\"\
								aria-label=\"Close\">\
								×\
							</button>\

"
			+ modal_title + "
\

";
	divHtml += ("
" + modal_body + "
");
	if (modal_footer != "")
		divHtml += ("
" + modal_footer + "
");
	divHtml += "

";
	return divHtml;
}
/**
 * 刷新右侧的区域
 */
function refreshRight() {
	$.ajax({
		"url" : blogInfo.refreshRUrl,
		"method" : "POST",
		"cache" : false,
		"dataType" : "json",
		"success" : function(data) {
			$("#blog_right").animate({
				"opacity" : 0
			}, "fast", "swing", function() {
				$(this).html(data.html);
				$("#blog_right").animate({
					"opacity" : 100
				}, "fast", "swing");
			});
		},
		"error" : function(jqXHR, textStatus, errorThrown) {
		}
	});
}<|endoftext|>


<commit_before>var FPS = 60;

var KEYCODE_UP = 38;
var KEYCODE_DOWN = 40;
var KEYCODE_LEFT = 37;
var KEYCODE_RIGHT = 39;
var KEYCODE_SPACE = 32;

var tableScorecards = {name:'', speed:0, life_count:0};
var height_property = 20;

var leftPress;
var rightPress;
var upPress;
var downPress;

var canvas;                //Main canvas
var stage;                 //Main display stage

var hero;                  //the actual hero
var alive;                 //whether the player is alive

var messageField;          //Message display field

//register key functions

function GameController(canvas) {
    this.hero = null;
    this.units = {};
    this.rotate = false;
    this.speed = false;
    this.canvas = canvas;
    this.socket = null;

    var controller = this;
    document.onkeydown = function (e) {
        controller.handleKeyDown(e);
    };
    document.onkeyup = function (e) {
        controller.handleKeyUp(e);
    };

    this.createConnection = function () {
        this.socket = createSocket(this);
    };

    this.sendToServer = function (heroAction, value) {
        var data = {};
        if (this.hero) {
            var hero_id = this.hero.id
        }
        else {
            var hero_id = ''
        }
        value = {'id': hero_id, 'name': value};
        data[heroAction] = value;
        var data = JSON.stringify(data);
        this.socket.send(data);
    };

    this.updateScorecardHeroes = function(hero){
        if(hero.type.slice(0, 'hero'.length) == 'hero'){
            var table = document.getElementById('scorecardHeroes').getElementsByTagName('tbody')[0];
            var row = document.getElementById(hero.id);
            if (row){
                var cell1 = row.getElementsByTagName('td')[0];
                var cell2 = row.getElementsByTagName('td')[1];
                var cell3 = row.getElementsByTagName('td')[2];
                var cell4 = row.getElementsByTagName('td')[3];
                var cell5 = row.getElementsByTagName('td')[4];
            }
            else{
                var row = table.insertRow(table.rows.length);
                var elem = document.createElement("img");
                elem.src = "static/images/" + hero.type + ".png";
                var cell1 = row.insertCell(0);
                var cell2 = row.insertCell(1);
                var cell3 = row.insertCell(2);
                var cell4 = row.insertCell(3);
                var cell5 = row.insertCell(4);
                cell1.appendChild(elem);
                row.id = hero.id;
            }
            cell2.innerHTML = hero.name;
            cell3.innerHTML = hero.hits;
            cell4.innerHTML = 3 - hero.life_count;
            cell5.innerHTML = parseInt(cell3.innerText) - parseInt(cell4.innerText);
            sortTable(table);
        }
    };

    this.onData = function (event) {
        var answer = JSON.parse(event.data);
        console.log(answer);

        for (var key in answer){
            switch (key) {
                case 'init':
                    this.start(answer.init);
                    break;
                case 'error':
                    this.error(answer.error);
                    break;
                case 'new':
                    this.newUnit(answer.new);
                    break;
                case 'update':
                    this.updateUnit(answer.update);
                    break;
                case 'delete':
                    this.killUnit(answer.delete);
                    break;
                case 'update_life':
                    this.updateLife(answer.update_life);
                    break;
            }
        }

    };

    this.error = function(error) {
        console.log(error)
    };

    this.start = function (init) {
        var formStartGame =document.getElementById('formStartGame');
        formStartGame.remove();
        var unitsObj = init['units'];
        var hero_id = init['hero_id'];
        var game_field = init['game'];
        this.frequency = init['frequency'];
        this.canvas.width = game_field.width;
        this.canvas.height = game_field.height;
        this.stage = new createjs.Stage(this.canvas);

        //create Units
        this.units = {};

        //ensure stage is blank and add the hero
        this.stage.clear();
        this.stage.addChild(this.hero);

        for (var i in unitsObj) {
            var unit = new createjs.Bitmap("static/images/" + unitsObj[i].type + ".png");
            for (var property in unitsObj[i]) {
                if (property != 'angle') {
                    unit[property] = unitsObj[i][property];
                }
                if (property == 'angle') {
                    unit.rotation = unitsObj[i].angle;
                }
            }
            unit.regX = unit.width / 2;
            unit.regY = unit.height / 2;
            this.units[unit.id] = unit;
            this.stage.addChild(unit);
            this.updateScorecardHeroes(unitsObj[i]);
        }
        this.hero = this.units[hero_id];

        //Show hero property
        for (var property in tableScorecards){
            if (property in this.hero){
                tableScorecards[property] = new createjs.Text("", "bold 18px Arial", "#FFFFFF");
                tableScorecards[property].x = this.canvas.width - 20;
                tableScorecards[property].y = height_property;
                tableScorecards[property].textAlign = "right";
                var value = property + ": " + (this.hero[property]).toString();
                tableScorecards[property].text = value;
                this.stage.addChild(tableScorecards[property]);
                height_property += 20;
            }
            else{
                console.log('Hero does not have property ' + property)
            }
        }

        //reset key presses
        this.leftPress = this.rightPress = this.upPress = this.downPress = this.spascePress = false;

        this.stage.update();

        //start game timer
        if (!createjs.Ticker.hasEventListener("tick")) {
            createjs.Ticker.setFPS(FPS);
            var controller = this;
            createjs.Ticker.addEventListener("tick", function () {
                controller.tick()
            });
        }
        console.log(createjs.Ticker.getInterval())
    };

    this.updateTableScorecards = function(){
        for(var property in tableScorecards){
            if (property in this.hero){
                var value = property + ": " + (this.hero[property]).toString();
                tableScorecards[property].text = value;
            }
            else{
                console.log('Hero does not have property ' + property)
            }
        }
    };

    this.newUnit = function (unitData) {
        if (!this.units[unitData.id]) {
            var unit = new createjs.Bitmap("static/images/" + unitData.type + ".png");
            for (var property in unitData) {
                if (property != 'angle') {
                    unit[property] = unitData[property];
                }
                if (property == 'angle') {
                    unit.rotation = unitData.angle;
                }
            }
            this.units[unitData.id] = unit;
            this.stage.addChild(unit);
            this.stage.update();
            this.updateScorecardHeroes(unitData);
        }
    };

    this.updateUnit = function (unitData) {
        var id = unitData['id'];

        for (var key in unitData) {
            if (this.units[id].hasOwnProperty(key)) {
                this.units[id][key] = unitData[key]

            }
            else if (key = 'angle') {
                this.units[id]['rotation'] = unitData[key]
            }
        }
        this.units[id].regX = this.units[id].width / 2;
        this.units[id].regY = this.units[id].height / 2;
        this.units[id].speedTick = this.units[id].speed / this.frequency / FPS;
        if (this.hero && id == this.hero['id']){
            this.updateTableScorecards()
        };
        this.updateScorecardHeroes(unitData);
    };

    this.killUnit = function (unitData) {
        var id = unitData['id'];
        this.stage.removeChild(this.units[id]);
        this.stage.update();
        this.updateScorecardHeroes(unitData);
        delete this.units[id];
    };

    this.updateLife = function (unitData) {
        var id = unitData['id'];
        this.units[id].life_count = unitData.life_count;
        this.updateTableScorecards();
    };

    this.tick = function (event) {

        var units = this.units;
        for (var i in units) {
            if (units[i].speed != 0 && units[i].speedTick) {
                if (units[i].x != units[i].x1 || units[i].y != units[i].y1) {
                    units[i].x = this.canvas.width - units[i].x;
                    units[i].y = this.canvas.height - units[i].y;
                    units[i].x += Math.sin(units[i].rotation * (Math.PI / -180)) * units[i].speedTick;
                    units[i].y += Math.cos(units[i].rotation * (Math.PI / -180)) * units[i].speedTick;
                    units[i].x = this.canvas.width - units[i].x;
                    units[i].y = this.canvas.height - units[i].y;
                }
            }
        }

        this.stage.update();

    };

    this.handleKeyDown = function (e) {
        //cross browser issues exist
        if (!e) {
            var e = window.event;
        }
        switch (e.keyCode) {
            case KEYCODE_LEFT:
                if (!this.leftPress) {
                    this.leftPress = true;
                    this.sendToServer('rotate_left', null)
                }
                return false;
            case KEYCODE_RIGHT:
                if (!this.leftPress) {
                    this.leftPress = true;
                    this.sendToServer('rotate_right', null)
                }
                return false;
            case KEYCODE_UP:
                //TODO: What is the meaning of `speed` as boolean. Non sense to me
                if (!this.speed) {
                    this.speed = true;
                    this.sendToServer('change_speed_up', null);
                }
                return false;
            case KEYCODE_DOWN:
                if (!this.speed) {
                    this.speed = true;
                    this.sendToServer('change_speed_down', null);
                }
                return false;
            case KEYCODE_SPACE:
                if (!this.spascePress){
                    this.spascePress = true;
                    this.sendToServer('start_fire', null);
                }
        }
    };

    this.handleKeyUp = function (e) {
        //cross browser issues exist
        if (!e) {
            var e = window.event;
        }
        switch (e.keyCode) {
            case KEYCODE_LEFT:
                if (this.leftPress) {
                    this.leftPress = false;
                    this.sendToServer('stop_rotate', null)
                }
                break;
            case KEYCODE_RIGHT:
                if (this.leftPress) {
                    this.leftPress = false;
                    this.sendToServer('stop_rotate', null)
                }
                break;
            case KEYCODE_UP:
                if (this.speed) {
                    this.speed = false;
                    this.sendToServer('stop_change_speed', null)
                }
                break;
            case KEYCODE_DOWN:
                if (this.speed) {
                    this.speed = false;
                    this.sendToServer('stop_change_speed', null)
                }
                break;
            case KEYCODE_SPACE:
                if (this.spascePress){
                    this.spascePress = false;
                    this.sendToServer('stop_fire', null)
                }
                break;
        }
    };

    this.sendAction = function (action) {
        var http = new XMLHttpRequest();
        var url = "api/hero/" + this.hero.id + "/action/" + action;
        http.open("POST", url, true);
        http.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
        http.send();
    }

}<commit_msg>hero name has same color as icon<commit_after>var FPS = 60;

var KEYCODE_UP = 38;
var KEYCODE_DOWN = 40;
var KEYCODE_LEFT = 37;
var KEYCODE_RIGHT = 39;
var KEYCODE_SPACE = 32;

var tableScorecards = {name:'', speed:0, life_count:0};
var height_property = 20;

var leftPress;
var rightPress;
var upPress;
var downPress;

var canvas;                //Main canvas
var stage;                 //Main display stage

var hero;                  //the actual hero
var alive;                 //whether the player is alive

var messageField;          //Message display field

//register key functions

function GameController(canvas) {
    this.hero = null;
    this.units = {};
    this.rotate = false;
    this.speed = false;
    this.canvas = canvas;
    this.socket = null;

    var controller = this;
    document.onkeydown = function (e) {
        controller.handleKeyDown(e);
    };
    document.onkeyup = function (e) {
        controller.handleKeyUp(e);
    };

    this.createConnection = function () {
        this.socket = createSocket(this);
    };

    this.sendToServer = function (heroAction, value) {
        var data = {};
        if (this.hero) {
            var hero_id = this.hero.id
        }
        else {
            var hero_id = ''
        }
        value = {'id': hero_id, 'name': value};
        data[heroAction] = value;
        var data = JSON.stringify(data);
        this.socket.send(data);
    };

    this.updateScorecardHeroes = function(hero){
        if(hero.type.slice(0, 'hero'.length) == 'hero'){
            var table = document.getElementById('scorecardHeroes').getElementsByTagName('tbody')[0];
            var row = document.getElementById(hero.id);
            if (row){
                var cell1 = row.getElementsByTagName('td')[0];
                var cell2 = row.getElementsByTagName('td')[1];
                var cell3 = row.getElementsByTagName('td')[2];
                var cell4 = row.getElementsByTagName('td')[3];
                var cell5 = row.getElementsByTagName('td')[4];
            }
            else{
                var row = table.insertRow(table.rows.length);
                var elem = document.createElement("img");
                elem.src = "static/images/" + hero.type + ".png";
                var cell1 = row.insertCell(0);
                var cell2 = row.insertCell(1);
                var cell3 = row.insertCell(2);
                var cell4 = row.insertCell(3);
                var cell5 = row.insertCell(4);
                cell1.appendChild(elem);
                row.id = hero.id;
            }
            var color = hero.type.split("_").pop();
            row.style.color = color;
            cell2.innerHTML = hero.name;
            cell3.innerHTML = hero.hits;
            cell4.innerHTML = 3 - hero.life_count;
            cell5.innerHTML = parseInt(cell3.innerText) - parseInt(cell4.innerText);
            sortTable(table);
        }
    };

    this.onData = function (event) {
        var answer = JSON.parse(event.data);
        console.log(answer);

        for (var key in answer){
            switch (key) {
                case 'init':
                    this.start(answer.init);
                    break;
                case 'error':
                    this.error(answer.error);
                    break;
                case 'new':
                    this.newUnit(answer.new);
                    break;
                case 'update':
                    this.updateUnit(answer.update);
                    break;
                case 'delete':
                    this.killUnit(answer.delete);
                    break;
                case 'update_life':
                    this.updateLife(answer.update_life);
                    break;
            }
        }

    };

    this.error = function(error) {
        console.log(error)
    };

    this.start = function (init) {
        var formStartGame =document.getElementById('formStartGame');
        formStartGame.remove();
        var unitsObj = init['units'];
        var hero_id = init['hero_id'];
        var game_field = init['game'];
        this.frequency = init['frequency'];
        this.canvas.width = game_field.width;
        this.canvas.height = game_field.height;
        this.stage = new createjs.Stage(this.canvas);

        //create Units
        this.units = {};

        //ensure stage is blank and add the hero
        this.stage.clear();
        this.stage.addChild(this.hero);

        for (var i in unitsObj) {
            var unit = new createjs.Bitmap("static/images/" + unitsObj[i].type + ".png");
            for (var property in unitsObj[i]) {
                if (property != 'angle') {
                    unit[property] = unitsObj[i][property];
                }
                if (property == 'angle') {
                    unit.rotation = unitsObj[i].angle;
                }
            }
            unit.regX = unit.width / 2;
            unit.regY = unit.height / 2;
            this.units[unit.id] = unit;
            this.stage.addChild(unit);
            this.updateScorecardHeroes(unitsObj[i]);
        }
        this.hero = this.units[hero_id];

        //Show hero property
        for (var property in tableScorecards){
            if (property in this.hero){
                tableScorecards[property] = new createjs.Text("", "bold 18px Arial", "#FFFFFF");
                tableScorecards[property].x = this.canvas.width - 20;
                tableScorecards[property].y = height_property;
                tableScorecards[property].textAlign = "right";
                var value = property + ": " + (this.hero[property]).toString();
                tableScorecards[property].text = value;
                this.stage.addChild(tableScorecards[property]);
                height_property += 20;
            }
            else{
                console.log('Hero does not have property ' + property)
            }
        }

        //reset key presses
        this.leftPress = this.rightPress = this.upPress = this.downPress = this.spascePress = false;

        this.stage.update();

        //start game timer
        if (!createjs.Ticker.hasEventListener("tick")) {
            createjs.Ticker.setFPS(FPS);
            var controller = this;
            createjs.Ticker.addEventListener("tick", function () {
                controller.tick()
            });
        }
        console.log(createjs.Ticker.getInterval())
    };

    this.updateTableScorecards = function(){
        for(var property in tableScorecards){
            if (property in this.hero){
                var value = property + ": " + (this.hero[property]).toString();
                tableScorecards[property].text = value;
            }
            else{
                console.log('Hero does not have property ' + property)
            }
        }
    };

    this.newUnit = function (unitData) {
        if (!this.units[unitData.id]) {
            var unit = new createjs.Bitmap("static/images/" + unitData.type + ".png");
            for (var property in unitData) {
                if (property != 'angle') {
                    unit[property] = unitData[property];
                }
                if (property == 'angle') {
                    unit.rotation = unitData.angle;
                }
            }
            this.units[unitData.id] = unit;
            this.stage.addChild(unit);
            this.stage.update();
            this.updateScorecardHeroes(unitData);
        }
    };

    this.updateUnit = function (unitData) {
        var id = unitData['id'];

        for (var key in unitData) {
            if (this.units[id].hasOwnProperty(key)) {
                this.units[id][key] = unitData[key]

            }
            else if (key = 'angle') {
                this.units[id]['rotation'] = unitData[key]
            }
        }
        this.units[id].regX = this.units[id].width / 2;
        this.units[id].regY = this.units[id].height / 2;
        this.units[id].speedTick = this.units[id].speed / this.frequency / FPS;
        if (this.hero && id == this.hero['id']){
            this.updateTableScorecards()
        };
        this.updateScorecardHeroes(unitData);
    };

    this.killUnit = function (unitData) {
        var id = unitData['id'];
        this.stage.removeChild(this.units[id]);
        this.stage.update();
        this.updateScorecardHeroes(unitData);
        delete this.units[id];
    };

    this.updateLife = function (unitData) {
        var id = unitData['id'];
        this.units[id].life_count = unitData.life_count;
        this.updateTableScorecards();
    };

    this.tick = function (event) {

        var units = this.units;
        for (var i in units) {
            if (units[i].speed != 0 && units[i].speedTick) {
                if (units[i].x != units[i].x1 || units[i].y != units[i].y1) {
                    units[i].x = this.canvas.width - units[i].x;
                    units[i].y = this.canvas.height - units[i].y;
                    units[i].x += Math.sin(units[i].rotation * (Math.PI / -180)) * units[i].speedTick;
                    units[i].y += Math.cos(units[i].rotation * (Math.PI / -180)) * units[i].speedTick;
                    units[i].x = this.canvas.width - units[i].x;
                    units[i].y = this.canvas.height - units[i].y;
                }
            }
        }

        this.stage.update();

    };

    this.handleKeyDown = function (e) {
        //cross browser issues exist
        if (!e) {
            var e = window.event;
        }
        switch (e.keyCode) {
            case KEYCODE_LEFT:
                if (!this.leftPress) {
                    this.leftPress = true;
                    this.sendToServer('rotate_left', null)
                }
                return false;
            case KEYCODE_RIGHT:
                if (!this.leftPress) {
                    this.leftPress = true;
                    this.sendToServer('rotate_right', null)
                }
                return false;
            case KEYCODE_UP:
                //TODO: What is the meaning of `speed` as boolean. Non sense to me
                if (!this.speed) {
                    this.speed = true;
                    this.sendToServer('change_speed_up', null);
                }
                return false;
            case KEYCODE_DOWN:
                if (!this.speed) {
                    this.speed = true;
                    this.sendToServer('change_speed_down', null);
                }
                return false;
            case KEYCODE_SPACE:
                if (!this.spascePress){
                    this.spascePress = true;
                    this.sendToServer('start_fire', null);
                }
        }
    };

    this.handleKeyUp = function (e) {
        //cross browser issues exist
        if (!e) {
            var e = window.event;
        }
        switch (e.keyCode) {
            case KEYCODE_LEFT:
                if (this.leftPress) {
                    this.leftPress = false;
                    this.sendToServer('stop_rotate', null)
                }
                break;
            case KEYCODE_RIGHT:
                if (this.leftPress) {
                    this.leftPress = false;
                    this.sendToServer('stop_rotate', null)
                }
                break;
            case KEYCODE_UP:
                if (this.speed) {
                    this.speed = false;
                    this.sendToServer('stop_change_speed', null)
                }
                break;
            case KEYCODE_DOWN:
                if (this.speed) {
                    this.speed = false;
                    this.sendToServer('stop_change_speed', null)
                }
                break;
            case KEYCODE_SPACE:
                if (this.spascePress){
                    this.spascePress = false;
                    this.sendToServer('stop_fire', null)
                }
                break;
        }
    };

    this.sendAction = function (action) {
        var http = new XMLHttpRequest();
        var url = "api/hero/" + this.hero.id + "/action/" + action;
        http.open("POST", url, true);
        http.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
        http.send();
    }

}<|endoftext|>


<commit_before>/*
Case Conductor is a Test Case Management system.
Copyright (C) 2011-2012 Mozilla

This file is part of Case Conductor.

Case Conductor is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Case Conductor 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with Case Conductor.  If not, see <http://www.gnu.org/licenses/>.
*/
/*jslint    browser:    true,
            indent:     4 */
/*global    ich, jQuery */

var CC = (function (CC, $) {

    'use strict';

    $(function () {
        // plugins
        $('.details:not(html)').html5accordion();
        $('#messages').messages({
            handleAjax: true,
            closeLink: '.message'
        });
        $('input[placeholder], textarea[placeholder]').placeholder();
        $('#suite-form .caseselect').multiselect();
        $('#filter').customAutocomplete({
            textbox: '#text-filter',
            inputList: '.visual .filter-group:not(.keyword)',
            newInputList: '.visual .filter-group.keyword',
            multipleCategories: true,
            allowNew: true,
            autoSubmit: true,
            newInputTextbox: 'input[type="text"]',
            fakePlaceholder: true,
            initialFocus: true,
            inputsNeverRemoved: true,
            prefix: 'filter'
        });
        $('.tagging').customAutocomplete({
            textbox: '#id_add_tags',
            ajax: true,
            url: $('#id_add_tags').data('autocomplete-url'),
            inputList: '.taglist',
            triggerSubmit: null,
            allowNew: true,
            restrictAllowNew: true,
            inputType: 'tag',
            noInputsNote: true,
            prefix: 'tag'
        });
        $('#editprofile .add-item').customAutocomplete({
            textbox: '#env-elements-input',
            inputList: '.env-element-list',
            ajax: true,
            url: $('#env-elements-input').data('autocomplete-url'),
            hideFormActions: true,
            expiredList: '.env-element-list',
            inputType: 'element',
            caseSensitive: true,
            prefix: 'element'
        });
        $('#suite-form .caseselect .multiunselected .selectsearch').customAutocomplete({
            textbox: '#search-add',
            inputList: '.groups .filter-group:not(.keyword)',
            newInputList: '.groups .filter-group.keyword',
            multipleCategories: true,
            allowNew: true,
            triggerSubmit: null,
            inputsNeverRemoved: true,
            prefix: 'filter'
        });
        $('.runsdrill').html5finder({
            loading: true,
            headerSelector: '.listordering',
            sectionSelector: '.col',
            sectionContentSelector: '.colcontent',
            sectionClasses: [
                'products',
                'cycles',
                'runs'
            ],
            sectionItemSelectors: [
                'input[name="product"]',
                'input[name="testcycle"]',
                'input[name="testrun"]'
            ],
            callback: function () {
                $('.runsdrill .drillenv').slideUp('fast');
            },
            lastChildCallback: function (choice) {
                var environments = $('.runsdrill .drillenv').css('min-height', '169px').slideDown('fast'),
                    ajaxUrl = $(choice).data('sub-url');
                environments.loadingOverlay();
                $.get(ajaxUrl, function (data) {
                    environments.loadingOverlay('remove');
                    environments.html(data.html);
                });
            }
        });
        $('.managedrill').html5finder({
            loading: true,
            horizontalScroll: true,
            scrollContainer: '.finder',
            headerSelector: '.listordering',
            sectionSelector: '.col',
            sectionContentSelector: '.colcontent',
            sectionClasses: [
                'products',
                'cycles',
                'runs',
                'suites'
            ],
            sectionItemSelectors: [
                'input[name="product"]',
                'input[name="testcycle"]',
                'input[name="testrun"]',
                'input[name="testsuite"]'
            ]
        });
        $('.resultsdrill').html5finder({
            loading: true,
            horizontalScroll: true,
            scrollContainer: '.finder',
            headerSelector: '.listordering',
            sectionSelector: '.col',
            sectionContentSelector: '.colcontent',
            sectionClasses: [
                'products',
                'cycles',
                'runs',
                'cases'
            ],
            sectionItemSelectors: [
                'input[name="product"]',
                'input[name="testcycle"]',
                'input[name="testrun"]',
                'input[name="testrunincludedtestcase"]'
            ]
        });

        // local.js
        CC.inputHadFocus();

        // manage-results.js
        CC.toggleAdvancedFiltering('#filter');
        CC.loadListItemDetails();
        CC.manageActionsAjax();
        CC.directFilterLinks();
        CC.filterFormAjax('.listpage');

        // manage-products.js
        CC.formOptionsFilter({
            container: '#addsuite',
            trigger_sel: '#id_product',
            target_sel: '.multiunselected .select',
            option_sel: '.selectitem',
            multiselect_widget_bool: true
        });
        CC.formOptionsFilter({
            container: '#addrun',
            trigger_sel: '#id_test_cycle',
            target_sel: '#id_suites'
        });
        CC.formOptionsFilter({
            container: '#single-case-add',
            trigger_sel: '#id_product',
            target_sel: '#id_productversion'
        });
        CC.formOptionsFilter({
            container: '#single-case-add',
            trigger_sel: '#id_product',
            target_sel: '#id_initial_suite',
            optional: true
        });
        CC.testcaseAttachments('.attach');
        CC.testcaseVersioning('#addcase');
        CC.envNarrowing('#envnarrowlist');

        // manage-env.js
        CC.createEnvProfile();
        CC.editEnvProfile();

        // manage-tags.js
        CC.manageTags('#managetags');

        // runtests.js
        CC.hideEmptyRuntestsEnv();
        CC.autoFocus('.details.stepfail > .summary', '#run');
        CC.autoFocus('.details.testinvalid > .summary', '#run');
        CC.runTests('#run');
        CC.breadcrumb('.runsdrill');
        CC.failedTestBug('#run');
    });

    $(window).load(function () {
        // manage-results.js
        CC.openListItemDetails();
    });

    return CC;

}(CC || {}, jQuery));
<commit_msg>Activate product version and suite options filtering on bulk-case-add page.<commit_after>/*
Case Conductor is a Test Case Management system.
Copyright (C) 2011-2012 Mozilla

This file is part of Case Conductor.

Case Conductor is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Case Conductor 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with Case Conductor.  If not, see <http://www.gnu.org/licenses/>.
*/
/*jslint    browser:    true,
            indent:     4 */
/*global    ich, jQuery */

var CC = (function (CC, $) {

    'use strict';

    $(function () {
        // plugins
        $('.details:not(html)').html5accordion();
        $('#messages').messages({
            handleAjax: true,
            closeLink: '.message'
        });
        $('input[placeholder], textarea[placeholder]').placeholder();
        $('#suite-form .caseselect').multiselect();
        $('#filter').customAutocomplete({
            textbox: '#text-filter',
            inputList: '.visual .filter-group:not(.keyword)',
            newInputList: '.visual .filter-group.keyword',
            multipleCategories: true,
            allowNew: true,
            autoSubmit: true,
            newInputTextbox: 'input[type="text"]',
            fakePlaceholder: true,
            initialFocus: true,
            inputsNeverRemoved: true,
            prefix: 'filter'
        });
        $('.tagging').customAutocomplete({
            textbox: '#id_add_tags',
            ajax: true,
            url: $('#id_add_tags').data('autocomplete-url'),
            inputList: '.taglist',
            triggerSubmit: null,
            allowNew: true,
            restrictAllowNew: true,
            inputType: 'tag',
            noInputsNote: true,
            prefix: 'tag'
        });
        $('#editprofile .add-item').customAutocomplete({
            textbox: '#env-elements-input',
            inputList: '.env-element-list',
            ajax: true,
            url: $('#env-elements-input').data('autocomplete-url'),
            hideFormActions: true,
            expiredList: '.env-element-list',
            inputType: 'element',
            caseSensitive: true,
            prefix: 'element'
        });
        $('#suite-form .caseselect .multiunselected .selectsearch').customAutocomplete({
            textbox: '#search-add',
            inputList: '.groups .filter-group:not(.keyword)',
            newInputList: '.groups .filter-group.keyword',
            multipleCategories: true,
            allowNew: true,
            triggerSubmit: null,
            inputsNeverRemoved: true,
            prefix: 'filter'
        });
        $('.runsdrill').html5finder({
            loading: true,
            headerSelector: '.listordering',
            sectionSelector: '.col',
            sectionContentSelector: '.colcontent',
            sectionClasses: [
                'products',
                'cycles',
                'runs'
            ],
            sectionItemSelectors: [
                'input[name="product"]',
                'input[name="testcycle"]',
                'input[name="testrun"]'
            ],
            callback: function () {
                $('.runsdrill .drillenv').slideUp('fast');
            },
            lastChildCallback: function (choice) {
                var environments = $('.runsdrill .drillenv').css('min-height', '169px').slideDown('fast'),
                    ajaxUrl = $(choice).data('sub-url');
                environments.loadingOverlay();
                $.get(ajaxUrl, function (data) {
                    environments.loadingOverlay('remove');
                    environments.html(data.html);
                });
            }
        });
        $('.managedrill').html5finder({
            loading: true,
            horizontalScroll: true,
            scrollContainer: '.finder',
            headerSelector: '.listordering',
            sectionSelector: '.col',
            sectionContentSelector: '.colcontent',
            sectionClasses: [
                'products',
                'cycles',
                'runs',
                'suites'
            ],
            sectionItemSelectors: [
                'input[name="product"]',
                'input[name="testcycle"]',
                'input[name="testrun"]',
                'input[name="testsuite"]'
            ]
        });
        $('.resultsdrill').html5finder({
            loading: true,
            horizontalScroll: true,
            scrollContainer: '.finder',
            headerSelector: '.listordering',
            sectionSelector: '.col',
            sectionContentSelector: '.colcontent',
            sectionClasses: [
                'products',
                'cycles',
                'runs',
                'cases'
            ],
            sectionItemSelectors: [
                'input[name="product"]',
                'input[name="testcycle"]',
                'input[name="testrun"]',
                'input[name="testrunincludedtestcase"]'
            ]
        });

        // local.js
        CC.inputHadFocus();

        // manage-results.js
        CC.toggleAdvancedFiltering('#filter');
        CC.loadListItemDetails();
        CC.manageActionsAjax();
        CC.directFilterLinks();
        CC.filterFormAjax('.listpage');

        // manage-products.js
        CC.formOptionsFilter({
            container: '#addsuite',
            trigger_sel: '#id_product',
            target_sel: '.multiunselected .select',
            option_sel: '.selectitem',
            multiselect_widget_bool: true
        });
        CC.formOptionsFilter({
            container: '#addrun',
            trigger_sel: '#id_test_cycle',
            target_sel: '#id_suites'
        });
        CC.formOptionsFilter({
            container: '#single-case-add',
            trigger_sel: '#id_product',
            target_sel: '#id_productversion'
        });
        CC.formOptionsFilter({
            container: '#single-case-add',
            trigger_sel: '#id_product',
            target_sel: '#id_initial_suite',
            optional: true
        });
        CC.formOptionsFilter({
            container: '#bulk-case-add',
            trigger_sel: '#id_product',
            target_sel: '#id_productversion'
        });
        CC.formOptionsFilter({
            container: '#bulk-case-add',
            trigger_sel: '#id_product',
            target_sel: '#id_initial_suite',
            optional: true
        });
        CC.testcaseAttachments('.attach');
        CC.testcaseVersioning('#addcase');
        CC.envNarrowing('#envnarrowlist');

        // manage-env.js
        CC.createEnvProfile();
        CC.editEnvProfile();

        // manage-tags.js
        CC.manageTags('#managetags');

        // runtests.js
        CC.hideEmptyRuntestsEnv();
        CC.autoFocus('.details.stepfail > .summary', '#run');
        CC.autoFocus('.details.testinvalid > .summary', '#run');
        CC.runTests('#run');
        CC.breadcrumb('.runsdrill');
        CC.failedTestBug('#run');
    });

    $(window).load(function () {
        // manage-results.js
        CC.openListItemDetails();
    });

    return CC;

}(CC || {}, jQuery));
<|endoftext|>