Both of the following code blocks work on Chrome and Firefox but not on Internet Explorer 11
I've searched forums and all but I haven't found any solution yet:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var starttime = (new Date()).getTime();
$(window).unload(function(){
$.post('timetest.php', {spent: (new Date()).getTime() - starttime});
});
});
</script>
<script>
function start()
{
starttime = (new Date()).getTime();
alert(starttime);
}
function leave()
{
stoptime = (new Date()).getTime();
var params = "spent="+(stoptime-starttime);
xmlobj = new XMLHttpRequest();
xmlobj.open('POST', 'timetest.php', true);
xmlobj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlobj.setRequestHeader("Content-length", params.length);
xmlobj.setRequestHeader("Connection", "close");
xmlobj.send(params);
}
</script>
<body onload=start() onunload=leave()>
Related
I found this link on the internet which demonstrates how WebRTC works https://shanetully.com/2014/09/a-dead-simple-webrtc-example/
Its source code is here https://github.com/shanet/WebRTC-Example
Now, I am trying to follow the example and here what I did:
1- I created a folder name voicechat
2- I created 2 folders inside voicechat. That is voicechat\client & voicechat\server
3- I put the index.html & webrtc.js into voicechat\client
4- I put server.js into voicechat\server
5- I put the folder voicechat into my Tomcat webapps folder. So The path will be like this C:\apache-tomcat-7.0.53\webapps\ROOT\voicechat
6- I started my Tomcat.
7- I opened http://xxx.xxx.xxx.xxx/voicechat/client/index.html in my PC & the webpage showed webcam (webcam 1) of my PC. No problem.
8- I opened http://xxx.xxx.xxx.xxx/voicechat/client/index.html in another PC & the webpage also showed webcam (webcam 2) of other PC. But I could not see webcam 1 of my PC. And when I talked in my PC, the person sitting in other PC could not hear what I am talking and via versa.
So, why it didn't work What did I do wrong?
Here is the code of 3 files:
index.html
<html>
<head>
<script src="webrtc.js"></script>
</head>
<body>
<video id="localVideo" autoplay muted style="width:40%;"></video>
<video id="remoteVideo" autoplay style="width:40%;"></video>
<br />
<input type="button" id="start" onclick="start(true)" value="Start Video"></input>
<script type="text/javascript">
pageReady();
</script>
</body>
</html>
webrtc.js
var localVideo;
var remoteVideo;
var peerConnection;
var peerConnectionConfig = {'iceServers': [{'url': 'stun:stun.services.mozilla.com'}, {'url': 'stun:stun.l.google.com:19302'}]};
navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.webkitRTCIceCandidate;
window.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;
function pageReady() {
localVideo = document.getElementById('localVideo');
remoteVideo = document.getElementById('remoteVideo');
serverConnection = new WebSocket('ws://127.0.0.1:3434');
serverConnection.onmessage = gotMessageFromServer;
var constraints = {
video: true,
audio: true,
};
if(navigator.getUserMedia) {
navigator.getUserMedia(constraints, getUserMediaSuccess, errorHandler);
} else {
alert('Your browser does not support getUserMedia API');
}
}
function getUserMediaSuccess(stream) {
localStream = stream;
localVideo.src = window.URL.createObjectURL(stream);
}
function start(isCaller) {
peerConnection = new RTCPeerConnection(peerConnectionConfig);
peerConnection.onicecandidate = gotIceCandidate;
peerConnection.onaddstream = gotRemoteStream;
peerConnection.addStream(localStream);
if(isCaller) {
peerConnection.createOffer(gotDescription, errorHandler);
}
}
function gotMessageFromServer(message) {
if(!peerConnection) start(false);
var signal = JSON.parse(message.data);
if(signal.sdp) {
peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp), function() {
peerConnection.createAnswer(gotDescription, errorHandler);
}, errorHandler);
} else if(signal.ice) {
peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice));
}
}
function gotIceCandidate(event) {
if(event.candidate != null) {
serverConnection.send(JSON.stringify({'ice': event.candidate}));
}
}
function gotDescription(description) {
console.log('got description');
peerConnection.setLocalDescription(description, function () {
serverConnection.send(JSON.stringify({'sdp': description}));
}, function() {console.log('set description error')});
}
function gotRemoteStream(event) {
console.log('got remote stream');
remoteVideo.src = window.URL.createObjectURL(event.stream);
}
function errorHandler(error) {
console.log(error);
}
server.js
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({port: 3434});
wss.broadcast = function(data) {
for(var i in this.clients) {
this.clients[i].send(data);
}
};
wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log('received: %s', message);
wss.broadcast(message);
});
});
server.js is intended to be run as a node server for websocket signaling. Run it with node server.js. You shouldn't need Tomcat at all.
From the project readme:
The signaling server uses Node.js and ws and can be started as such:
$ npm install ws
$ node server/server.js
With the client running, open client/index.html in a recent version of either Firefox or Chrome.
You can open index.html with just a file URL.
I changed HTTPS_PORT = 8443 to HTTP_PORT = 8443. Do same with all the https; change it to http. Next, have only const serverConfig = { }; as the serverConfig and delete serverConfig in const httpServer = http.createServer(handleRequest); After these changes, u can now run your server with npm start.
This is the ultimate simple code can do the job. No need to install Node.js. Why need to install Node.js?
AND put that code into index.html file and start your webhost, then you done!
<!DOCTYPE html>
<html>
<head>
<script src="//simplewebrtc.com/latest.js"></script>
</head>
<body>
<div id="localVideo" muted></div>
<div id="remoteVideo"></div>
<script>
var webrtc = new SimpleWebRTC({
localVideoEl: 'localVideo',
remoteVideosEl: 'remoteVideo',
autoRequestMedia: true
});
webrtc.on('readyToCall', function () {
webrtc.joinRoom('My room name');
});
</script>
</body>
</html>
Hi everyone i am trying to register new account on my local openfire server using strophe.js and strophe.register.js plugin by following the steps for registration provide on many websites.But i get error in my strophe.register.js file at line var auth_old = conn.authenticate.bind(conn); that conn.authenticate is undefined
below is the my code
code of my js file
$(document).ready(function () {
var conn = new Strophe.Connection(
"http://jabber.local/http-bind");
console.log(conn);
var callback = function (status) {
if ( status === Strophe.Status.REGISTERING ) {
console.log('REGISTERING')
conn.authenticate();
}
else if ( status === Strophe.Status.REGIFAIL ) {
console.log('REGIFAIL')
}
else if ( status === Strophe.Status.REGISTER ) {
console.log('REGISTER')
conn.register.fields.username = "joe"
conn.register.fields.password = "doe"
conn.register.submit();
}
else if ( status === Strophe.Status.SUBMITTING ) {
console.log('SUBMITTING')
}
else if ( status === Strophe.Status.SBMTFAIL ) {
console.log('SBMTFAIL')
console.log('Something went wrong...');
}
else if ( status === Strophe.Status.REGISTERED ) {
console.log('REGISTERED')
console.log('Your account has been created successfully and is ready to use!');
}
}
conn.register.connect("example.com", callback);
});
and the html file code is
<html>
<head>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js'></script>
<script src='../scripts/strophe.js'></script>
<script type="text/javascript" src="../scripts/strophe.register.js"></script>
<script src='../scripts/flXHR.js'></script>
<script src='../scripts/strophe.flxhr.js'></script>
<link rel='stylesheet' href='hello.css'>
<script src='hello.js'></script>
</head>
<body>
<h1>Hello</h1>
<div id='log'>
</div>
<!-- login dialog -->
<div id='login_dialog' class='hidden'>
<label>JID:</label><input type='text' id='jid'>
<label>Password:</label><input type='password' id='password'>
</div>
</body>
</html>
can enyone tell my why this happend and how to solve this.One more thing i also comment the lines that most site said to do.
/* if (register.length === 0) {
conn._changeConnectStatus(Strophe.Status.REGIFAIL, null);
return true;
}*/
this.enabled = true;
Just noticed that you are using the older version of the plugin. Please update the strophe.register.js from https://github.com/metajack/strophejs-plugins/blob/master/register/strophe.register.js
I have checked the latest version it does not have below line
var auth_old = conn.authenticate.bind(conn);
<!DOCTYPE html>
<html>
<head>
<title>WebRTC Reference App</title>
<meta http-equiv="X-UA-Compatible" content="chrome=1"/>
<link rel="canonical" href="https://apprtc.appspot.com/?r=96443121"/>
<link rel="stylesheet" href="css/main.css" />
<script type="text/javascript" src="_ah/channel/jsapi.js"></script>
<!--<script type="text/javascript" src="/_ah/channel/jsapi"></script>-->
<script src="js/main.js"></script>
<!-- Load the polyfill to switch-hit between Chrome and Firefox -->
<script src="js/adapter.js"></script>
</head>
<body >
<script type="text/javascript">
var errorMessages = [];
var channelToken = 'AHRlWroGHj6YqWMdr7JeFULjqux9vQzrpCOnFM7zD91GLHc4PVW1WDZJI08ptgM_XMj5M22InerI5Lw5QN1rS3rHu2Dlnx3g95ILmzupe2OFB4OLCbZGbAQ';
var me = '49847744';
var roomKey = '96443121';
var roomLink = 'https://apprtc.appspot.com/?r=96443121';
var initiator = 0;
var pcConfig = {"iceServers": [{"url": "stun:stun.l.google.com:19302"}]};
var pcConstraints = {"optional": [{"DtlsSrtpKeyAgreement": true}]};
var offerConstraints = {"optional": [], "mandatory": {}};
var mediaConstraints = {"audio": true, "video": true};
var turnUrl = 'https://computeengineondemand.appspot.com/turn?username=49847744&key=4080218913';
var stereo = false;
var audio_send_codec = '';
var audio_receive_codec = 'opus/48000';
setTimeout(initialize, 1);
</script>`enter code here`
<div id="maindiv">
<div id="container" ondblclick="enterFullScreen()">
<div id="card">
<div id="local">
<video id="localVideo" autoplay muted="true"/>
</div>
<div id="remote">
<video id="remoteVideo" autoplay>
</video>
<div id="mini">
<video id="miniVideo" autoplay muted="true"/>
</div>
</div>
</div>
</div>
<div class="buttons">
<button id="startButton">Start</button>
<button id="callButton">Call</button>
<button id="hangupButton">Hang Up</button>
</div>
</div>
<script>
var localStream, localPeerConnection, remotePeerConnection;
var localVideo = document.getElementById("localVideo");
var remoteVideo = document.getElementById("remoteVideo");
var startButton = document.getElementById("startButton");
var callButton = document.getElementById("callButton");
var hangupButton = document.getElementById("hangupButton");
startButton.disabled = false;
callButton.disabled = true;
hangupButton.disabled = true;
startButton.onclick = start;
callButton.onclick = call;
hangupButton.onclick = hangup;
function trace(text) {
console.log((performance.now() / 1000).toFixed(3) + ": " + text);
}
function gotStream(stream){
trace("Received local stream");
localVideo.src = URL.createObjectURL(stream);
localStream = stream;
callButton.disabled = false;
}
function start() {
trace("Requesting local stream");
startButton.disabled = true;
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
navigator.getUserMedia({audio:true, video:true}, gotStream,
function(error) {
trace("navigator.getUserMedia error: ", error);
});
}
function call() {
callButton.disabled = true;
hangupButton.disabled = false;
trace("Starting call");
if (localStream.getVideoTracks().length > 0) {
trace('Using video device: ' + localStream.getVideoTracks()[0].label);
}
if (localStream.getAudioTracks().length > 0) {
trace('Using audio device: ' + localStream.getAudioTracks()[0].label);
}
var servers = null;
localPeerConnection = new webkitRTCPeerConnection(servers);
trace("Created local peer connection object localPeerConnection");
localPeerConnection.onicecandidate = gotLocalIceCandidate;
remotePeerConnection = new webkitRTCPeerConnection(servers);
trace("Created remote peer connection object remotePeerConnection");
remotePeerConnection.onicecandidate = gotRemoteIceCandidate;
remotePeerConnection.onaddstream = gotRemoteStream;
localPeerConnection.addStream(localStream);
trace("Added localStream to localPeerConnection");
localPeerConnection.createOffer(gotLocalDescription);
}
function gotLocalDescription(description){
localPeerConnection.setLocalDescription(description);
trace("Offer from localPeerConnection: \n" + description.sdp);
remotePeerConnection.setRemoteDescription(description);
remotePeerConnection.createAnswer(gotRemoteDescription);
}
function gotRemoteDescription(description){
remotePeerConnection.setLocalDescription(description);
trace("Answer from remotePeerConnection: \n" + description.sdp);
localPeerConnection.setRemoteDescription(description);
}
function hangup() {
trace("Ending call");
localPeerConnection.close();
remotePeerConnection.close();
localPeerConnection = null;
remotePeerConnection = null;
hangupButton.disabled = true;
callButton.disabled = false;
}
function gotRemoteStream(event){
remoteVideo.src = URL.createObjectURL(event.stream);
trace("Received remote stream");
}
function gotLocalIceCandidate(event){
if (event.candidate) {
remotePeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
trace("Local ICE candidate: \n" + event.candidate.candidate);
}
}
function gotRemoteIceCandidate(event){
if (event.candidate) {
localPeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
trace("Remote ICE candidate: \n " + event.candidate.candidate);
}
}
</script>
</body>
<footer id="status">`enter code here`
</footer>
<div id="infoDiv"></div>
</html>
here in the code above how to connect two different pc's and do a video call. I had taken it from webrtc.org.
I am getting two videos on the same PC. I want to connect two different PC's and do a video call. the example for this can be seen on vline.com where the link is autogenerated and on just needs to connect to the given link and they can do a video call.
please help
You will need a signaling server to relay all messages between the two peers. You could for example do this in Javascript using node.js:
var WebSocketServer = require('websocket').server;
var http = require('http');
var clients = [];
var server = http.createServer(function(request, response) {
// process HTTP request. Since we're writing just WebSockets server
// we don't have to implement anything.
});
server.listen(80, function() {
console.log((new Date()) + " Server is listening on port 80");
});
// create the server
wsServer = new WebSocketServer({
httpServer: server
});
function sendCallback(err) {
if (err) console.error("send() error: " + err);
}
// This callback function is called every time someone
// tries to connect to the WebSocket server
wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection from origin ' + request.origin + '.');
var connection = request.accept(null, request.origin);
console.log(' Connection ' + connection.remoteAddress);
clients.push(connection);
// This is the most important callback for us, we'll handle
// all messages from users here.
connection.on('message', function(message) {
if (message.type === 'utf8') {
// process WebSocket message
console.log((new Date()) + ' Received Message ' + message.utf8Data);
// broadcast message to all connected clients
clients.forEach(function (outputConnection) {
if (outputConnection != connection) {
outputConnection.send(message.utf8Data, sendCallback);
}
});
}
});
connection.on('close', function(connection) {
// close user connection
console.log((new Date()) + " Peer disconnected.");
});
});
The peers need to send all signaling (offers, answers and candidates) via this signaling server (socket.send()). peer example below:
function connect() {
if (!started && localStream && channelReady) {
createPeerConnection();
started = true;
peerConn.createOffer(setLocalAndSendMessage, errorCallback, mediaConstraints);
} else {
alert("Local stream may not be running yet, or problem with signaling");
}
}
// send SDP via websocket connection
function setLocalAndSendMessage(sessionDescription) {
peerConn.setLocalDescription(sessionDescription);
socket.send(JSON.stringify(sessionDescription));
}
// Signaling messages end up here
function onMessage(evt) {
var descr = JSON.parse(evt.data);
if (descr.type === 'offer') {
if (!started) {
createPeerConnection();
started = true;
}
peerConn.setRemoteDescription(new RTCSessionDescription(descr));
peerConn.createAnswer(setLocalAndSendMessage, errorCallback, mediaConstraints);
} else if (descr.type === 'answer'){
peerConn.setRemoteDescription(new RTCSessionDescription(descr));
} else if (descr.type === 'candidate'){
var candidate = new RTCIceCandidate({sdpMLineIndex: descr.sdpMLineIndex, sdpMid: descr.sdpMid, candidate: descr.candidate});
peerConn.addIceCandidate(candidate);
}
}
//Creates a new RTCPeerConnection
function createPeerConnection() {
peerConn = new webkitRTCPeerConnection({"iceServers": []});
// send any ice candidates to the other peer
peerConn.onicecandidate = function(evt) {
if (event.candidate) {
socket.send(JSON.stringify({
type: "candidate",
sdpMLineIndex: evt.candidate.sdpMLineIndex,
sdpMid: evt.candidate.sdpMid,
candidate: evt.candidate.candidate}));
} else {
console.log("End of candidates.");
}
};
peerConn.addStream(localStream);
peerConn.addEventListener("addstream", onRemoteStreamAdded, false);
}
function onRemoteStreamAdded(event) {
//peerConn.removeEventListener("addstream", onRemoteStreamAdded, false);
remotevidArr.src = window.URL.createObjectURL(event.stream);
}
I'm displaying a Bing Map (v7) in my Webmatrix2 website with a series of pushpins & infoboxes drawn from a SQL Express database using a JSON enquiry.
While the maps appears in all 3 browsers I'm testing (IE, FF & Chrome) the pushpins are sometimes not showing in FF & Chrome, particularly if I refresh with Cntrl+F5
This is my first JSON and Bing Maps app so expect there's a few mistakes.
Any suggestions on how to improve the code and get display consistency?
#{
Layout = "~/_MapLayout.cshtml";
}
<script type="text/javascript" src="~/Scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<link rel="StyleSheet" href="infoboxStyles.css" type="text/css">
<script type="text/javascript">
var map = null;
var pinLayer, pinInfobox;
var mouseover;
var pushpinFrameHTML = '<div class="infobox"><a class="infobox_close" href="javascript:closeInfobox()"><img src="/Images/close2.jpg" /></a><div class="infobox_content">{content}</div></div><div class="infobox_pointer"><img src="images/pointer_shadow.png"></div>';
var pinLayer = new Microsoft.Maps.EntityCollection();
var infoboxLayer = new Microsoft.Maps.EntityCollection();
function getMap() {
map = new Microsoft.Maps.Map(document.getElementById('map'), {
credentials: "my-key",
zoom: 4,
center: new Microsoft.Maps.Location(-25, 135),
mapTypeId: Microsoft.Maps.MapTypeId.road
});
pinInfobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false });
AddData();
}
$(function AddData() {
$.getJSON('/ListSchools', function (data) {
var schools = data;
$.each(schools, function (index, school) {
for (var i = 0; i < schools.length; i++) {
var pinLocation = new Microsoft.Maps.Location(school.SchoolLat, school.SchoolLon);
var NewPin = new Microsoft.Maps.Pushpin(pinLocation);
NewPin.title = school.SchoolName;
NewPin.description = "-- Learn More --";
pinLayer.push(NewPin); //add pushpin to pinLayer
Microsoft.Maps.Events.addHandler(NewPin, 'mouseover', displayInfobox);
}
});
infoboxLayer.push(pinInfobox);
map.entities.push(pinLayer);
map.entities.push(infoboxLayer);
});
})
function displayInfobox(e) {
if (e.targetType == "pushpin") {
var pin = e.target;
var html = "<span class='infobox_title'>" + pin.title + "</span><br/>" + pin.description;
pinInfobox.setOptions({
visible: true,
offset: new Microsoft.Maps.Point(-33, 20),
htmlContent: pushpinFrameHTML.replace('{content}', html)
});
//set location of infobox
pinInfobox.setLocation(pin.getLocation());
}
}
function closeInfobox() {
pinInfobox.setOptions({ visible: false });
}
function getCurrentLocation() {
var geoLocationProvider = new Microsoft.Maps.GeoLocationProvider(map);
geoLocationProvider.getCurrentPosition();
}
</script>
<body onload="getMap();">
<div id="map" style="position:relative; width:800px; height:600px;"></div>
<div>
<input type="button" value="Find Nearest Schools" onclick="getCurrentLocation();" />
</div>
</body>
The JSON file is simply
#{
var db = Database.Open("StarterSite");
var sql = #"SELECT * FROM Schools WHERE SchoolLon != ' ' AND SchoolLon != 'null' ";
var data = db.Query(sql);
Json.Write(data, Response.Output);
}
Add your pinLayer, infobox, and infoboxLayer before calling the AddData function and see if that makes a difference. Also verify that school.SchoolLat and school.SchoolLon are numbers and not a string version of a number. If they are a string, then use parseFloat to turn them into a number. Other than that everything looks fine.
In his blog post, Christian Cantrell shows how to use STORAGE_VOLUME_MOUNT in ActionScript.
He has written a Flex app called FileTile.
I would like to see a JavaScript alert box that says “You have inserted “ + e.storageVolume.name, and “You have removed a storage volume”.
<html>
<head>
<title>New Adobe AIR Project</title>
<script type="text/javascript" src="lib/air/AIRAliases.js"></script>
<script type="text/javascript" src="lib/air/AIRIntrospector.js"></script>
<script type="text/javascript" src="lib/jQuery/jquery-1.4.3.min.js"></script>
<script type="text/javascript">
var msg = '<h1>Please insert your SwatchDog (SD) card.</h1>';
function trace() {
var message = 'Hello Max';
air.Introspector.Console.log(message);
}
function readFile(v) {
var myFile = air.File.desktopDirectory.resolvePath("MyFile.txt");
var fileStream = new air.FileStream();
fileStream.open(myFile, air.FileMode.READ);
$('#app').append('<p>' + fileStream.readUTFBytes(fileStream.bytesAvailable) + '</p>');
fileStream.close();
}
function onVolumeMount(e) {
$('#app').html('<h1>Thank you</h1><p>I can see you have multiple devices:</p>');
var volumes = air.StorageVolumeInfo.storageVolumeInfo.getStorageVolumes();
for (var i = 0; i < volumes.length; i++) {
$('#app').append(volumes[i].rootDirectory.nativePath);
}
if (e.storageVolume.isRemovable) {
if (e.storageVolume.name == 'SWATCHDOG') {
$('#app').append('<p>And SwatchDog is drive: ' + e.storageVolume.rootDirectory.nativePath + '</p>');
readFile(e.storageVolume)
} else {
$('#app').append('<p>But the one you just plugged in is not SwatchDog.</p>');
}
}
}
function onVolumeUnmount(e) {
$('#app').html('<h1>Goodbye!</h1>' + msg);
}
jQuery(function($){
var PluggedIn = false;
var volumes = air.StorageVolumeInfo.storageVolumeInfo.getStorageVolumes();
for (var i = 0; i < volumes.length; i++) {
if (volumes[i].isRemovable) {
PluggedIn = true;
if (volumes[i].name == 'SWATCHDOG') {
$('#app').append('I see you already have SwatchDog plugged in!');
readFile(volumes[i])
} else {
$('#app').append('What you have plugged in is not SwatchDog.');
}
}
}
if (!PluggedIn){
$('#app').append(msg);
}
air.StorageVolumeInfo.storageVolumeInfo.addEventListener(air.StorageVolumeChangeEvent.STORAGE_VOLUME_MOUNT, onVolumeMount);
air.StorageVolumeInfo.storageVolumeInfo.addEventListener(air.StorageVolumeChangeEvent.STORAGE_VOLUME_UNMOUNT, onVolumeUnmount);
})
</script>
</head>
<body>
<div id="app">
</div>
<button onclick="trace();">Say Hello Max!</button>
</body>
</html>