[00:00] isaacs: without having to be careful about references.
[00:00] ashb: which is really hard to do
[00:00] isaacs: ACTION has programmed in msie 6 enough to know how easy it is to miss a reference
[00:00] ashb: i've tried it. and even when i was trying it i still missed a couple of cases of unintentionaly shared state
[00:00] ashb: prototypes are a bitch for that
[00:00] isaacs: tell me about it!
[00:01] isaacs: js isn't really intended to be shared-nothing
[00:01] isaacs: s/really/even remotely/
[00:01] ashb: :)
[00:02] Tim_Smart: What is wrong with process.createChildProcess('node', ['my_worker.js']); ?
[00:02] mikeal1: so
[00:02] Tim_Smart: then add a "output" callback
[00:02] mikeal1: i was just talking to jan
[00:02] mikeal1: and erlang has a model for dealing with the code reloading and making consumers aware
[00:02] mikeal1: so like
[00:02] mikeal1: var mymodule = require('./mymodule');
[00:03] mikeal1: mymodule.addListener("reload", function(oldmodule, newmodule) {})
[00:03] mikeal1: that way you can write in ways to handling removing references you might have to code that is getting swapped out
[00:03] ashb: mikeal1: that means you need to store resources in a file-level global
[00:03] ashb: and if you do that then those resources will never get GCd
[00:04] mikeal1: that's what is already happening at some level
[00:04] mikeal1: because if those references don't get removed that are never going to get GC'd anyway
[00:05] ashb: not really
[00:05] isaacs: Tim_Smart: that's essentially what i'm suggesting
[00:05] ashb: your module is a class
[00:05] ashb: one of its functions creates a repeating timer
[00:05] isaacs: the supervisor is the thing that watches for changes and re-spawns the child procs.
[00:05] ashb: the module itself never has to keep track of that
[00:05] isaacs: mikeal1: that works in erlang because the modules don't leak state with the outside world.
[00:06] Tim_Smart: isaacs: Pass JSON messages, and use JSON.stringify and JSON.parse. I might write an abstraction at some point
[00:06] mikeal1: they *can* if you write really bad code :)
[00:06] isaacs: mikeal1: right, but you have to go out of your way to make that happen in erlang. in js, that's the normal paradigm
[00:06] isaacs: Tim_Smart: do it!
[00:06] isaacs: Tim_Smart: scroll back, i would love it if someone did this.
[00:07] isaacs: ashb: you said boost takes how long?
[00:07] ashb: about 20mins on my mbp
[00:07] Tim_Smart: isaacs: So it reloads when the files change?
[00:07] ashb: it took an hour last night, but i was compiling in 2vms at the same time
[00:08] isaacs: ashb: new macbookpro 15" 2.8GHz 4GB 1067 MHz DDR3 FTW!!
[00:08] isaacs: took about 2 minutes.
[00:08] dnolen has joined the channel
[00:08] ashb: o_O
[00:08] ashb: that seems *really* quick
[00:08] ashb: SSD?
[00:08] isaacs: oh, actually, more like 5
[00:09] isaacs: Tim_Smart: yeah, you'd tell the supervisor the entry point and the files to watch.
[00:09] ashb: oh i've only got 666mhz ram too
[00:09] isaacs: Tim_Smart: ideally, i could say "watch this folder, and run this module"
[00:09] Tim_Smart: OK. So it essentially turns into a app server
[00:09] isaacs: Tim_Smart: then, the supervisor should pipe it's stdout to stdout, and its stderr to stderr
[00:09] isaacs: Tim_Smart: kinda, yeah
[00:10] mikeal1: yeah, that's broken ATM tho :)
[00:10] isaacs: mikeal1: what's broken?
[00:10] isaacs: Tim_Smart: ideally, the supervisor'd be really small, and extremely crash proof, and also restart the app if it crashes.
[00:10] mikeal1: if you write to the subprocess stdio the data event won't occur in the subprocess
[00:10] mikeal1: that's the unittest i wrote up that ryah merged today
[00:10] isaacs: i see
[00:10] isaacs: yeah, saw that.
[00:11] isaacs: well, now that there's a test, we should have a fix soonish :)
[00:11] mikeal1: also, we do this in couchdb, write JSON to a child process
[00:11] mikeal1: and you shouldn't underestimate the IO overhead even with stdio
[00:11] isaacs: oh, this should really only be used in cases where stability is more important than performance.
[00:12] isaacs: stability and freshness of code
[00:12] mikeal1: davisp just took the erlang_js stuff so that he can pass JSON to an embedded erlang process and that alone doubled the performance of the view server
[00:12] isaacs: mikeal1: but, in this case, also, you wouldn't be passing much between server and child.
[00:12] isaacs: mikeal1: i mean, the child is probably "outputting" to http responses or whatever, right?
[00:13] mikeal1: you don't pass all that much in the view server either
[00:13] isaacs: mikeal1: i mean, you could pass *nothing* in most cases.
[00:13] mikeal1: nope, not an entire http response, just the key/value paris for the view
[00:13] isaacs: the child could be the actual http server.
[00:13] mikeal1: it's for the map/reduce stuff
[00:13] isaacs: right, so you're passing anything back and forth. i'm suggesting doing this in cases where you'd probably not pass anything back and forth.
[00:14] isaacs: just map the child's stderr to the parents so that if you do sys.debug() it's not lost.
[00:14] mikeal1: so, at that SSJS meetup, ryah mentioned really quickly that he planned on implementing a childProcess + IPC API
[00:15] isaacs: yeah, that sounded neat
[00:15] mikeal1: and that would be much faster than passing over stdio
[00:15] Tim_Smart: mikeal1: He has also post on the web workers thread on the google group
[00:15] isaacs: IPC can certainly be really useful for a lot of cases that are much more involved than just a simple supervisor.
[00:15] isaacs: doing web workers with IPC over stdio is possible today, and neat, but not really all that practical.
[00:16] Tim_Smart: Yeah I think it is just to wait in to ryan lands it in core
[00:16] Tim_Smart: s/in/until/
[00:16] isaacs: Tim_Smart: yea
[00:16] ashb: are any of the posix message things better than just json over stdio?
[00:17] ryah_away: would be nice to have multiple channels
[00:17] ryah: also passing fds
[00:17] ryah: but i'm sure stdio is super fast
[00:17] ryah: i just realized that there is two too many pipes when doing two node processes
[00:18] ryah: trying to fix that right now
[00:18] mikeal1: the WebWorker API is nice, but I think it fits a model better where you create WebWorkers without much regard for the number of cores, and the WebWorker implementation itself scales those over how every many processors you have
[00:18] mikeal1: that's what it was designed for
[00:18] ashb: mikeal1: GCD :)
[00:18] Booster_ has joined the channel
[00:18] Tim_Smart: Well I'll have up a quick hack at implementing a WebWorker prototype for node
[00:18] mikeal1: i'm tethered to my iPhone, so i get big blurbs of messages all at once and not really as they are happening, so forgive me if I trail behind a big :)
[00:20] ryah: http://github.com/popular/watched <-- node is almost on here
[00:20] Tim_Smart: yay
[00:20] ryah: node has 1033
[00:21] Tim_Smart: http://howtonode.org/deploying-node-upstart-monit :p
[00:24] isaacs: ashb: looks like arabica changed
[00:24] isaacs: getting build errors.
[00:24] isaacs: ashb: http://gist.github.com/296424
[00:25] ashb: welll fuck.
[00:25] ashb: isaacs: 105 or 10.6?
[00:25] ashb: .6
[00:25] ashb: hmmm
[00:25] isaacs: guess i'll try again when github decided to serve tarballs again
[00:26] ashb: worked for me last night :(
[00:26] isaacs: yeah, i don't know what's up with it atm
[00:26] isaacs: from the messages, looks like it's definitely arabica related.
[00:26] ashb: yeah
[00:26] ashb: tho thats odd. cos its using the bundled version correctly
[00:27] ashb: fuckedy-fuck-fuck
[00:27] paulca has joined the channel
[00:31] ashb: ACTION blows away things from the cellar and tries again
[00:33] stephenlb: Tim_Smart++ for article at howtonode.org
[00:38] jed has joined the channel
[00:38] orlandov: so is there a node planet yet?
[00:40] Tim_Smart: NODE"S PLANET IS EARTH
[00:40] Tim_Smart: IT RULES TEH WORLD
[00:41] mikeal1: i think everyone is waiting for someone to write one *in* node :)
[00:41] ashb: i think i own planetjs.org
[00:41] mikeal1: but i certainly don't want to take on the work of writing a new universal feed parser
[00:42] orlandov: but aggregation is so easy! ;)
[00:46] dnolen_ has joined the channel
[00:51] RayMorgan_ has joined the channel
[01:02] RayMorgan has joined the channel
[01:07] Tim_Smart: isaacs: I have created a exact implementation of the Web Worker spec
[01:08] Tim_Smart: just need to test it now
[01:14] CIA-78: node: 03Ryan Dahl 07master * rfe85062 10/ (3 files in 3 dirs):
[01:14] CIA-78: node: Bugfix: blocked pumping in stdio coupling
[01:14] CIA-78: node: This should fix the test in c05b5d8 by Mikeal Rogers. - http://bit.ly/cRWRo1
[01:14] ryah: mikeal1: ---^
[01:14] mikeal1: sweet!
[01:14] ryah: really difficult to fix
[01:14] mikeal1: what was the problem?
[01:15] ryah: there are special threads for stdio which pump data from one process into the other
[01:15] ryah: and those pumps were getting blocked
[01:16] ryah: see http://github.com/ry/node/blob/fe85062046ac36c2207aa0bbd2f496663eaca996/deps/coupling/coupling.c
[01:17] ryah: hopefully i haven't introduced a dozen other bugs with this change
[01:27] steadicat has joined the channel
[01:28] mikeal has joined the channel
[01:29] deanlandolt_: isaacs_mobile: you, sir, are freakin' nuts...beautifully done on the multipart parser
[01:30] isaacs_mobile: Thaanks :)
[01:38] sudoer has joined the channel
[01:39] brapse has joined the channel
[01:58] elliottcable: creepy. fucking. shit. http://elliottcable.tumblr.com/post/24171135/woman-in-the-oven
[01:58] mikeal has joined the channel
[02:01] scudco has joined the channel
[02:04] frodenius: elliottcable: maaaaan that is creepy shit
[02:04] elliottcable: frodenius: no kidding, right?
[02:05] frodenius: i am going to scare the hell out of my little brother
[02:05] inimino: hehe
[02:17] paulca has joined the channel
[02:21] CIA-78: node: 03Matt Brubeck 07master * r1737cdc 10/ doc/api.txt :
[02:21] CIA-78: node: Fix the documentation of dns error handling.
[02:21] CIA-78: node: These are actually passed as Error objects, not separate "code" and "message"
[02:21] CIA-78: node: parameters. - http://bit.ly/9YAyA4
[02:24] blackdog` has joined the channel
[02:25] mikeal has joined the channel
[02:28] eikke has joined the channel
[02:29] gf3: ryah: awesome, thanks
[02:29] gf3: re: fe85062
[02:49] rryan has joined the channel
[02:50] Yuffster has joined the channel
[02:51] JimBastard has joined the channel
[02:51] JimBastard: hey Tim_Smart
[02:51] micheil_away: moin ryah & gf3
[02:51] Tim_Smart: Hello JimBastard
[02:51] JimBastard: look what i found on one of my servers, http://174.143.204.44/Biggie/
[02:51] micheil: and jim / tim
[02:51] JimBastard: made that a few months ago
[02:51] JimBastard: sup micheil
[02:51] micheil: not a lot, just got back from work/.
[02:52] JimBastard: i got business drunk today
[02:52] JimBastard: balmer peaked quite nicely
[02:52] Tim_Smart: Looks like a gangsta
[02:52] JimBastard: its notorious big
[02:52] JimBastard: (not saying anything about actually using the image, just made it a while back for fun)
[02:53] Tim_Smart: ACTION is now fat. He had two bacon and egg pirs
[02:53] Tim_Smart: *pies
[02:57] aguynamedben has joined the channel
[02:57] micheil: Tim_Smart: I'll pull that article shortly, just gotta grab some food & stuff
[02:57] Tim_Smart: Creationix already has :p
[02:58] micheil: oh
[02:59] micheil_mbp has joined the channel
[03:00] quirkey has joined the channel
[03:01] micheil_mbp: ACTION is seriously going to need to create a new design for the site
[03:04] creationix has joined the channel
[03:07] creationix: micheil_mbp: what ideas do you have for a redesign?
[03:08] micheil: I'm not sure yet
[03:09] Tim_Smart: Awesome-ness
[03:09] creationix: you should be able to change most look and feel with just the howtonode.org repo. let me know if you need access to the engine too
[03:11] creationix: hmm, well actually changes to the engine won't take effect unless you log into my server and restart it. only the content is hooked up to github
[03:12] creationix: ACTION: wonders if it's possible to have a node server restart itself using a github hook
[03:13] binary42 has joined the channel
[03:13] binary42 has joined the channel
[03:13] inimino: creationix: hey, nice post btw
[03:13] creationix: which one, the monit one was by Tim_Smart
[03:14] inimino: the one you wrote yesterday
[03:14] inimino: (part II of whatever it was)
[03:14] creationix: thanks, that one was fun
[03:14] creationix: I almost wish we had continuable type things instead of promises in node
[03:14] inimino: hehe
[03:15] creationix: I couldn't get the syntax to work for event emitters though, they really need an object you can attach callbacks to
[03:15] inimino: creationix: would you mind pointing those links to the blog post instead of the README?
[03:15] inimino: http://inimino.org/~inimino/blog/fileio_first_release
[03:15] creationix: sure thing
[03:15] inimino: that'll actually be updated when I release a new version
[03:15] inimino: the stuff under /asof/{timestamp} is perma-frozen
[03:16] creationix: done
[03:16] inimino: thanks
[03:17] creationix: I love the github post commit hook. I just push code and it's live on the site
[03:17] inimino: that is cool
[03:17] creationix: I was wondering if node had something like ruby's Kernel.exec
[03:17] creationix: http://ruby-doc.org/core/classes/Kernel.html#M005968
[03:17] creationix: then a node process could restart itself.
[03:18] creationix: well, do a git pull and then restart itself
[03:19] inimino: Kernel:: is a weird name for that
[03:19] inimino: but... hm, no, I think the closest thing is system()
[03:19] creationix: well, in ruby you just call exec. Kernel is always in local scope
[03:20] Tim_Smart: sys.exec vs Kernel.exec?
[03:20] inimino: well, I guess it's sys.exec
[03:20] inimino: but the original node process will still exist
[03:21] creationix: exactely
[03:21] creationix: I guess with monit runnint you can just kill yourself and let it restart you
[03:21] creationix: but there may be some lag there
[03:21] Tim_Smart: yeah depending on the monit check interval
[03:21] inimino: can we trap signals yet?
[03:22] Tim_Smart: inimino: I think so
[03:22] inimino: lots of low-level Unix stuff is still missing
[03:22] creationix: I know that process emits them
[03:22] creationix: not sure if that is a trap or not
[03:22] inimino: I don't see it in the docs
[03:23] creationix: search for "SIGINT", "SIGUSR1"
[03:23] inimino: there's a lot more docs than the last time I looked at the API page :-)
[03:23] Tim_Smart: process.addListener("SIGINT" ... )
[03:24] inimino: ah
[03:24] creationix: maybe we could get the hot reloading working and then just put all the logic in an external reloadable library
[03:24] creationix: then a git pull from within node should be enough to reload the logic
[03:24] inimino: well, you can always create a runner process and have it spawn your actual app
[03:25] creationix: that would be weird. Have a process with a github post commit hook listener that creates a sub-process with another hook listener
[03:25] brapse has joined the channel
[03:26] creationix: May just a single running app that does the listening for both code bases and runs the builder in a subprocess
[03:26] creationix: if the content changes, then pull it and re-run the generator. If the generator code changes, pull it and re-run the generator
[03:28] creationix: I think that would be a good generic library for making any node app self-updateable
[03:28] Tim_Smart: inimino: I'm working on a Web Worker implementation atm
[03:29] Tim_Smart: trying to keep it as close to spec as possible... But I'm keeping it on the Javascript side atm
[03:29] creationix: how are those different than sub-processes? more communication?
[03:29] Tim_Smart: Web Workers are just OS level processes
[03:30] Tim_Smart: they have a standard stdio pipe, so you have to use the JSON library. Can't share anything other than raw data
[03:30] Tim_Smart: unless you toSource() it and then eval() it
[03:31] creationix: so it's sys.exec with a different api?
[03:31] inimino: Tim_Smart: cool
[03:31] Tim_Smart: It's a really simple implementation, nothing fancy
[03:32] inimino: creationix: it's more like message passing to a sandboxed, extra VM
[03:32] creationix: so you can inject code into and then work with it through messages
[03:32] inimino: yes
[03:33] creationix: ok, now that is cool
[03:33] creationix: but I'll bet the implementation uses sys.exec :P
[03:33] Tim_Smart: process.createChildProcess
[03:34] creationix: oh yeah, that's the one with streaming IO
[03:34] Tim_Smart: didn't want to require un-necessary stuff
[03:34] Tim_Smart: well it is all async
[03:34] creationix: yeah, my sqlite3 driver is just a wrapper around the command-line sqlite3 command using process.createChildProcess
[03:35] Tim_Smart: You should probably write a C++ wrapper for the official library :p
[03:36] creationix: naw too much C++ for me
[03:36] creationix: besides, it runs amazingly fast. All the hard work is done by sqlite3 which is written in c
[03:36] Tim_Smart: The API isn't that bad... It took me a day to get my head around it, and I had never written C++ in my life
[03:37] creationix: though I can't tell a number from a string in the query results
[03:37] Tim_Smart: I still am a little confused with referencing in C++ though
[03:37] Tim_Smart: I never know when to use a * or & with a variable
[03:37] micheil: ACTION really wants just on ORM.
[03:37] micheil: *one
[03:38] creationix: micheil: come up with a nice api and I'll slap it onto node-persistence
[03:38] micheil: heh heh
[03:38] micheil: just something like activerecord
[03:38] creationix: the hard part for me there was coming up with a good async api
[03:38] micheil: db.find(...).addCallback(fn).addErrback(fn)
[03:38] micheil: db.find().wait()
[03:38] micheil: all works with promises
[03:38] creationix: well, my low level drivers already have that kind of stuff
[03:39] creationix: it's the higher-level stuff like validations and associations that I'm still working out
[03:39] micheil: ACTION is doing stuff with mongodb and noSQL/schemaless db's atm
[03:40] creationix: btw, what are the most stable noSQL libraries for node currently
[03:40] creationix: I need to import a couple into node-persistence
[03:40] micheil: db.validates(...); db.insert(something that doesn't valid) => emits Errback(new Error("validation not met."))
[03:40] micheil: creationix: I'll be working with both mongodb and mongodb-native, doing a few benchmarks
[03:41] micheil: I'll probably go with the C++ on though
[03:41] isaacs_mobile has joined the channel
[03:41] creationix: micheil: have you seen the driver interface in node-persistence? I tried to make it generic enough to fit noSQL drivers
[03:41] creationix: http://github.com/creationix/node-persistence
[03:41] micheil: no, I haven't really looked at persistence
[03:44] micheil: creationix: why not: var conn = new persistence.Connection();
[03:44] micheil: rather then: var conn = persistence.new_connection()
[03:44] micheil: ?
[03:45] micheil: or did I miss something?
[03:45] creationix: I don't remember. I think there was a good reason. Maybe it's just my aversion to using the new operator
[03:46] micheil: example usage:
[03:46] micheil: http://github.com/creationix/node-persistence/blob/master/test/common.js#L43
[03:46] micheil: cold be: return new backends[path].connection.apply(this, args);
[03:47] micheil: or maybe even without apply(this, args)
[03:47] micheil: just (args)
[03:47] isaacs_mobile_ has joined the channel
[03:48] creationix: maybe. I gotta go for now, file a ticket if you want
[03:48] micheil: auto merge is a bitch.
[03:50] micheil: wooo! all the tests pass on node-mongodb
[03:52] Tim_Smart: :) How are you interfacing with it?
[03:54] RayMorgan has joined the channel
[03:56] micheil: uhh..
[03:56] micheil: node-mongodb is a node module
[03:58] Tim_Smart: oh I though you were the author :D
[03:58] Tim_Smart: thought*
[03:58] micheil: no
[03:59] Tim_Smart: I'm most likely will be using MongoDB for a few projects then
[03:59] Tim_Smart: *going to be
[04:00] micheil: note to self: don't try modifying 36000 rows in a mongodb tables from the shell.
[04:01] micheil: it's just fricking slow that way
[04:01] micheil: but it worked a frickin treat!
[04:02] Tim_Smart: Gah my web worker implementation is seg faulting
[04:03] Tim_Smart: ACTION shakes his fist
[04:03] micheil: :(
[04:03] micheil: :P
[04:03] micheil: Tim_Smart: couldn't you just use tcp to pass stuff about?
[04:04] Tim_Smart: well ideally stdio is reasonable easy
[04:05] micheil: okay
[04:05] micheil: Tim_Smart: alternatively you could write a C++ manager api
[04:05] micheil: or something
[04:06] Tim_Smart: Forking processes in C++ messes with the main event loop
[04:06] Tim_Smart: I'm getting "WARNING: promise.wait() is being called too often."
[04:06] Tim_Smart: Although I never call promise.wait(). /me digs though nodes source
[04:10] creationix has joined the channel
[04:10] micheil: oh shit. duck everyone!
[04:10] stephenlb: heh
[04:10] micheil: ;P
[04:10] micheil: creationix: j/k
[04:11] creationix: don't worry, I read the logs before logging in anyway :P
[04:11] rictic has joined the channel
[04:15] creationix: micheil: I remember why I didn't use new, it's because you can't mix apply and new on the same function.
[04:15] micheil: oh
[04:19] kriszyp has joined the channel
[04:19] creationix: I'm thinking my next howtonode article will be how to make a live chat server. It will be kinda like the how to make a blog in 15 minutes from other languages, but live chat it so much more node.
[04:19] gwoo: nice
[04:19] micheil: creationix: I was going to do that one :(
[04:20] stephenlb: creationix: cool
[04:20] gwoo: micheil: you can do the screencast :)
[04:20] micheil: ACTION loves working with tcp/realtime network sockets
[04:20] creationix: micheil: ok, make a good tutorial and I'll make the screencast version of it
[04:20] micheil: okay
[04:21] micheil: It might be in a few days though, I've got some work I've gotta do first
[04:21] creationix: use websockets and pretend that all browsers support it, it will feel liberating
[04:21] stephenlb: heh
[04:22] creationix: I made a real proof of concept one a while back http://github.com/creationix/websocket/tree/master/sample/
[04:23] creationix: * real simple
[04:23] micheil: creationix: raw protocol right up.
[04:24] micheil: so it'll cover the implementation of a tcp server for a chat application
[04:24] micheil: - the implementation of a layer to grab the messages from the tcp server using a comet or websocket connector
[04:24] micheil: - and a basic frontend
[04:25] micheil: ACTION waits for his 36000 record mongodb to update..
[04:25] creationix: sounds like fun, kind of like orbited?
[04:25] micheil: yeah
[04:25] creationix: good idea
[04:25] micheil: oh, and just for the lols, it'll be backed by dojo toolkit on the client
[04:26] creationix: yuck
[04:26] micheil: hmm?
[04:26] micheil: what would you use?
[04:26] creationix: just not a fan of Dojo personally, it's fine to use
[04:27] micheil: why not?
[04:28] mikeal has joined the channel
[04:28] creationix: Dojo just seems bloated to me, and I've seen many people struggle with it
[04:28] creationix: I haven't used it much personally
[04:28] micheil: it's not
[04:28] micheil: Dojo has just had the bloat thing thrown on it, because people don't understand it
[04:28] creationix: and I like to write my own libraries for fun
[04:28] micheil: not for comet and stuff like that. you'd be insane to do it
[04:29] inimino: hehe
[04:29] micheil: most useless regex ever:
[04:29] micheil: replace(/(^\s+|\s+$)/g, " ");
[04:29] creationix: sortof trim
[04:29] micheil: not even
[04:30] micheil: I was trying to remove the whitespace at start and end of strings
[04:30] inimino: and replace it with a single space?
[04:32] micheil: no
[04:32] micheil: replace it with no space
[04:33] nodejs_v8 has joined the channel
[04:33] aho: if (typeof String.prototype.trim !== 'function') {
[04:33] aho: String.prototype.trim = function () {
[04:33] aho: return this.replace(/^\s+|\s+$/g, '');
[04:33] aho: };
[04:33] aho: }
[04:33] aho: looks like that... usually
[04:36] Tim_Smart: nodejs_v8: " jlsdjfkl sdjf lsdkj f "replace(/^\s+|\s+$/g, '');
[04:36] nodejs_v8: Tim_Smart: Exception: SyntaxError: Unexpected identifier
[04:36] Tim_Smart: nodejs_v8: " jlsdjfkl sdjf lsdkj f ".replace(/^\s+|\s+$/g, '');
[04:36] nodejs_v8: Tim_Smart: "jlsdjfkl sdjf lsdkj f"
[04:37] micheil: aho: no, I'm working in the mongodb shell
[04:37] aho: and that's relevant, because...?
[04:37] creationix: doesn't mongo
[04:38] creationix: doesn't mongo's JS have String.prototype.trim built in?
[04:38] creationix: but I guess you don't want to always add a string back in huh?
[04:38] creationix: * add a space back in
[04:38] isaacs has joined the channel
[04:39] Tim_Smart: Hmm well I got my Web Worker thing to get a single direction of communication
[04:39] creationix: nodejs_v8: " easy ".trim()
[04:39] nodejs_v8: creationix: "easy"
[04:39] Tim_Smart: hahaha
[04:39] creationix: Tim_Smart: cool
[04:39] micheil: creationix: I didn't need to use it, I'm already running a few replaces, it was easier to write the regex
[04:40] micheil: nodejs_v8: " test test test ".trim() == "test test test"
[04:40] nodejs_v8: micheil: false
[04:40] micheil: which is what I needed
[04:40] Tim_Smart: nodejs_v8: " test test test ".trim().replace(/\s+\, '');
[04:40] nodejs_v8: Tim_Smart: Exception: SyntaxError: Invalid regular expression: missing /
[04:40] Tim_Smart: nodej" test test test ".trim().replace(/\s+/, '');
[04:40] Tim_Smart: nodejs_v8: " test test test ".trim().replace(/\s+, '');
[04:40] nodejs_v8: Tim_Smart: Exception: SyntaxError: Invalid regular expression: missing /
[04:41] Tim_Smart: nodejs_v8: " test test test ".trim().replace(/\s+/, '');
[04:41] nodejs_v8: Tim_Smart: "testtest test"
[04:41] Tim_Smart: >.<
[04:41] micheil: fail.
[04:41] Tim_Smart: nodejs_v8: " test test test ".trim().replace(/\s+/, ' ');
[04:41] nodejs_v8: Tim_Smart: "test test test"
[04:42] micheil: nodejs_v8: " test test test ".replace(/(^\s+|\s+$/g, "").replace(/\s+/, " ");
[04:42] nodejs_v8: micheil: Exception: SyntaxError: Invalid regular expression: /(^\s+|\s+$/: Unterminated group
[04:42] Tim_Smart: nodejs_v8: " test test test ".trim().replace(/\s+/g, ' ');
[04:42] nodejs_v8: Tim_Smart: "test test test"
[04:42] micheil: nodejs_v8: " test test test ".replace(/(^\s+|\s+$)/g, "").replace(/\s+/, " ");
[04:42] nodejs_v8: micheil: "test test test"
[04:42] Tim_Smart: friggen finally
[04:42] micheil: nodejs_v8: " test test test ".replace(/(^\s+|\s+$)/g, "").replace(/\s+/g, " ");
[04:42] nodejs_v8: micheil: "test test test"
[04:43] micheil: theoretically I could make it one regex, but eh.
[04:43] micheil: it does the job.
[04:43] Tim_Smart: replace is awesome for iterating over matches
[04:43] creationix: true
[04:43] inimino: ooh, regexes
[04:43] Tim_Smart: as you can pass a function
[04:45] creationix: what do you guys think about articles on howtonode that are teaching generic javascript without any node specific apis sometimes?
[04:45] micheil: creationix: sounds good. as people will be coming from frontend libraries
[04:46] creationix: I'm especially thinking about the ES5 stuff in node that you can't use in browsers because most browsers don't have it
[04:46] inimino: js> " a b c ".replace(/^ +| +$|( )+/g,'$1')
[04:46] gbot2: inimino: "a b c"
[04:46] inimino: creationix: sure, that'd be great
[04:47] micheil: nodejs_v8: " test test test ".replace(/^\s+|\s+$|(\s)+/g, "$1")
[04:47] nodejs_v8: micheil: "test test test"
[04:47] micheil: nice
[04:47] creationix: nodejs_v8: Object.create({parent: true}, {child: {value: true,enumarable:false}})
[04:47] nodejs_v8: creationix: {"parent": true}
[04:47] creationix: Object.create({parent: true}, {child: {value: "I'm the kid",enumarable:false}}).child
[04:48] micheil: js> Object.create({parent: true}, {child: {value: true,enumarable:false}})
[04:48] gbot2: micheil: Error: TypeError: Object.create is not a function
[04:48] creationix: nodejs_v8: Object.create({parent: true}, {child: {value: "I'm the kid",enumarable:false}}).child
[04:48] nodejs_v8: creationix: "I'm the kid"
[04:48] micheil: lols.
[04:48] inimino: 'enumerable'
[04:48] creationix: the only docs about it I've seen anywhere on the web are the crappy ones in the ES5 spec
[04:48] inimino: yes
[04:49] creationix: basically the second argument to Object.create lets you create an object with hidden properties
[04:49] inimino: the spec isn't docs
[04:49] creationix: like length in arrays
[04:49] inimino: it's a pretty decent spec
[04:49] creationix: good for a spec, terrible as api docs
[04:49] inimino: yes
[04:49] inimino: someone needs to write some docs, I guess
[04:49] creationix: it just tells you how to implement Object.create, not what it actually does
[04:49] inimino: anyway, bbiab
[04:50] creationix: what version of node does this bot run? latest?
[04:51] creationix: nodejs_v8: process.version
[04:51] nodejs_v8: creationix: Exception: ReferenceError: process is not defined
[04:53] gwoo has joined the channel
[04:54] Tim_Smart: Not the latest latest
[04:54] Tim_Smart: Yesturdays version? lol
[04:55] isaacs: nodejs_v8: " test test test ".replace(/(^\s+|\s+$)|(\s)(\2)\s*/g, '$2')
[04:55] nodejs_v8: isaacs: "test test test"
[04:56] isaacs: ACTION views "theoretically it could be done in one regex, but meh" as a personal challenge.
[04:56] Tim_Smart: But still, the version of v8 it runs is the same
[04:56] isaacs: probably a simpler way
[04:57] isaacs: nodejs_v8: " test test test ".replace(/(^\s+|\s+$)|(\s)\s*/g, '$2')
[04:57] nodejs_v8: isaacs: "test test test"
[04:57] creationix: I wish it had my latest inspect patch. I think it got lost in Ryan's inbox
[04:58] Tim_Smart: ryah: ping ----^
[04:58] isaacs: nodejs_v8: " test test test ".replace(/^\s+|\s+$|(\s)\s+/g, '$1')
[04:58] nodejs_v8: isaacs: "test test test"
[04:58] micheil: nodejs_v8: " test test test ".replace(/^\s+|\s+$|(\s)+/g, "$1")
[04:58] nodejs_v8: micheil: "test test test"
[04:58] micheil: works
[04:59] isaacs: oh, yeah, that works, too
[04:59] micheil: much simpler too imo.
[04:59] isaacs: but i think it might be like a ns faster if you don't match single-spaces and replace them with a single space.
[04:59] micheil: infact.
[04:59] micheil: nodejs_v8: " test test test ".replace(/^\s+|\s+$|(\s)+/g, " ")
[04:59] nodejs_v8: micheil: " test test test "
[04:59] micheil: for what I needed.
[04:59] micheil: almost
[04:59] Tim_Smart: I like trim().replace(/\s+/g, ' '); better
[04:59] isaacs: Tim_Smart: that's cheating!
[04:59] micheil: each to their own
[05:00] Tim_Smart: isaacs: nevaaar!
[05:00] isaacs: actually, yeah, in practice, i'd prefer .trim().replace(/\s{2,}/g, " ")
[05:00] isaacs: or something
[05:00] isaacs: but there was a challenge issued.
[05:01] inimino: hehe
[05:01] Tim_Smart: Hmm process.ChildProcess.prototype.write does not seem to work as expected
[05:03] creationix: nodejs_v8: [Object.keys([1,2,3]),Object.getOwnPropertyNames([1,2,3])]
[05:03] nodejs_v8: creationix: [["0", "1", "2"], [0, 1, 2, "length"]]
[05:03] creationix: cool, latest v8, they just added that one
[05:04] creationix: though I wonder why the array indexes are integers and not strings
[05:04] Tim_Smart: nodejs_v8: Object.getOwnPropertyNames(this)
[05:04] nodejs_v8: Tim_Smart: ["TypeError", "decodeURI", "String", "Function", "Number", "undefined", "parseFloat", "encodeURI", "encodeURIComponent", "ReferenceError", "RegExp", "escape", "Array", "isNaN", "URIError", "unescape", "RangeError", "Date", "Infinity", "decodeURIComponent", "EvalError", "Math", "Boolean", "Error", "SyntaxError", "Object", "NaN", "eval", "parseInt", "execScript", "JSON", "isFinite"]
[05:04] isaacs: creationix: that's what makes arrays so special.
[05:05] creationix: I thought all keys were coerced to strings before doing property lookups
[05:05] Tim_Smart: jQuery return a super-array
[05:05] Tim_Smart: *returns
[05:05] creationix: and Object.keys is giving strings
[05:06] inimino: that's probably a bug
[05:07] creationix: well, I found it because it bit me while implementing the inspect patch that allows for showing hidden properties
[05:07] JimBastard: howtonode is looking good
[05:07] creationix: thanks, though it's costing me a lot of sleep. Not sure I'll write one tonight
[05:07] inimino: s/probably //
[05:08] JimBastard: i'd do one, but im not sure what it would be on
[05:08] creationix: inimino: did you just read the spec?
[05:08] inimino: creationix: yes
[05:08] Tim_Smart: nodejs_v8: function(){this.toString = function(){eval('process.kill()')}}
[05:08] nodejs_v8: Tim_Smart: Exception: SyntaxError: Unexpected token (
[05:08] Tim_Smart: nodejs_v8: (function(){this.toString = function(){eval('process.kill()')}})
[05:08] nodejs_v8: Tim_Smart: function (){this.toString = function(){eval('process.kill()')}}
[05:08] creationix: Tim_Smart: need to call the function
[05:09] inimino: hehe
[05:09] Tim_Smart: nodejs_v8: new (function(){this.toString = function(){eval('process.kill()')}}))
[05:09] nodejs_v8: Tim_Smart: Exception: SyntaxError: Unexpected token )
[05:09] Tim_Smart: nodejs_v8: new (function(){this.toString = function(){eval('process.kill()')}})
[05:09] nodejs_v8: Tim_Smart: {"toString": function (){eval('process.kill()')}}
[05:10] creationix: member:nodejs_v8: (function(){this.toString = function(){eval('process.kill()')}})()
[05:10] creationix: doh, silly copy paste
[05:11] creationix: shouldn't work anyway, it said there is no process defined
[05:11] Tim_Smart: nodejs_v8: Function.prototype.toString = function(){eval('process.kill()')}; (function(){})
[05:11] nodejs_v8: Tim_Smart: Exception: ReferenceError: process is not defined
[05:11] creationix: that's a clever way to execute it though
[05:12] Tim_Smart: nodejs_v8: Function.prototype.toString = function(){eval('GLOBAL')}; (function(){})
[05:12] nodejs_v8: Tim_Smart: Exception: ReferenceError: GLOBAL is not defined
[05:12] Tim_Smart: hmm, something is calling it :p
[05:14] Tim_Smart: nodejs_v8: Function.prototype.toString = function(){eval('sys')}; (function(){})
[05:14] nodejs_v8: Tim_Smart: Exception: ReferenceError: sys is not defined
[05:14] Tim_Smart: I give up
[05:15] inimino: nodejs_v8: ({get x(){process.exit()})
[05:15] nodejs_v8: inimino: Exception: SyntaxError: Unexpected token )
[05:15] Tim_Smart: nodejs_v8: Function.prototype.toString = function(){eval('Object.getOwnPropertyNames(this)')}; (function(){})
[05:15] inimino: nodejs_v8: ({get x(){process.exit()}})
[05:15] nodejs_v8: Tim_Smart: undefined
[05:15] nodejs_v8: inimino: Exception: ReferenceError: process is not defined
[05:16] creationix: inimino: V8 is treating arrays special for sure,
[05:16] creationix: nodejs_v8: Object.getOwnPropertyNames([1,2,3]).map(function (name) { return Object.getOwnPropertyDescriptor([1,2,3], name.toString())
[05:16] nodejs_v8: creationix: Exception: SyntaxError: Unexpected end of input
[05:16] Tim_Smart: inimino: The pretty printer calls .toString() on functions
[05:17] Tim_Smart: that is why I was seeing if I could reverse it that way
[05:18] Tim_Smart: nodejs_v8: Function.prototype.toString = function(){return eval('Object.getOwnPropertyNames(this)')}; (function(){})
[05:18] nodejs_v8: Tim_Smart:
[05:18] inimino: Tim_Smart: the pretty printer runs with the rest of the code in whatever sandbox you have though right?
[05:18] Tim_Smart: Yeah which is a node process
[05:18] Tim_Smart: the pretty printer code needs replacing
[05:19] inimino: creationix: yeah, array indices are optimized as integers, but everything else is strings, it looks like someone forgot to normalize the output... I'd file a bug if there isn't one
[05:19] inimino: Tim_Smart: what's it look like now?
[05:20] Tim_Smart: http://dl.dropbox.com/u/396394/ircbot.tar.gz
[05:20] Tim_Smart: lib/v8/v8evaler,js
[05:21] rictic has joined the channel
[05:21] creationix: inimino: also array values aren't real properties
[05:21] creationix: nodejs_v8: [Object.getOwnPropertyDescriptor([1,2,3], 0), Object.getOwnPropertyDescriptor([1,2,3],"length")]
[05:21] richtaur has joined the channel
[05:21] nodejs_v8: creationix: [undefined, {"value": 3, "writable": true, "enumerable": false, "configurable": **RECURSION**}]
[05:21] creationix: doesn't matter if you pass in 0 or "0" it always comes back undefined
[05:21] richtaur has joined the channel
[05:23] inimino: Tim_Smart: hehe I was going to say, I have some code for that
[05:23] inimino: Tim_Smart: but that is a modification of my code :-)
[05:23] inimino: Tim_Smart: the original is here: http://dl.dropbox.com/u/396394/ircbot.tar.gz
[05:23] inimino: the **RECURSION** thing is new
[05:24] Tim_Smart: nodejs_v8: Function.prototype.toString
[05:24] nodejs_v8: Tim_Smart: function toString() { [native code] }
[05:24] inimino: js> #1=[#1#]
[05:24] gbot2: inimino: [[[[[[[[...]]]]]]]]
[05:25] inimino: nodejs_v8: a=[]; a[0]=a; a
[05:25] nodejs_v8: inimino: [**RECURSION**]
[05:25] Tim_Smart: inimino: Might change to this: http://jsbeautifier.org/
[05:26] Tim_Smart: actually, maybe not
[05:26] inimino: you don't really want a beautifier
[05:26] inimino: it needs to be compact
[05:26] inimino: and it needs to truncate things
[05:27] Tim_Smart: It is running slow atm... might be my internet
[05:27] inimino: bbl
[05:28] creationix: heh, google's c8 issue tracker says I'm forbidden from creating a new issue
[05:28] creationix: *v8
[05:28] Tim_Smart: o.
[05:28] Tim_Smart: o.O
[05:28] creationix: well, there was already an automatic ticket saying it doesn't pass the ES5 test suite for Object.getOwnPropertyNames
[05:29] creationix: I was hoping that having a ticket from a real person would speed up the process
[05:30] creationix: funny thing is it let me enter one ticket
[05:30] creationix: now I'm putting in the second ticket in another browser. I guess there is a one ticket per browser rule somewhere
[05:30] siong1987 has joined the channel
[05:31] nodejs_v8 has joined the channel
[05:31] Tim_Smart: weird
[05:33] creationix: got it, two tickets filed. Cool thing about node is we're the first to get new v8 features
[05:34] creationix: browser users have to wait ages
[05:37] creationix: ooh, reading the v8 sources, Object.create supports setting get and set properties on new objects.
[05:37] creationix: ACTION plans evil api with hidden dynamic properties
[05:42] scudco has joined the channel
[05:42] creationix: crap, found a bug in my inspect code, Objects that don't have a prototype at all don't have __lookupGetter__ and friends
[05:43] mikeal has joined the channel
[05:52] mnutt has joined the channel
[05:56] mnutt: does anybody know if there are any known issues with calling wait() on a posix.stat() call?
[05:56] mnutt: for instance: http://gist.github.com/296575
[05:57] mnutt: the problem that I'm running into is that the file may or may not exist
[05:57] mnutt: and if it doesn't exist, node.js throws an error
[05:59] RayMorgan has joined the channel
[06:10] richtaur has left the channel
[06:16] micheil: mnutt: in which case you should be using promises rather then wait()
[06:17] micheil: or, you could try{}catch it
[06:18] mnutt: mitchell: I have a list of n files that I want to check for existence, are promises the right way to go for that?
[06:18] micheil: yes
[06:19] micheil: then you can go something like...
[06:21] micheil: https://gist.github.com/4d3900a86a3cac15a843
[06:23] mnutt: that looks good but I'm trying to return the presence of each file as one single json hash
[06:23] mnutt: but I guess I could iterate over the promises and add each one as a callback to the previous one?
[06:24] micheil: well, yeah, you could always change that for a json hash
[06:24] micheil: slightly different code structure but still the same idea
[06:24] mnutt: cool, I'll give it a try
[06:24] mnutt: thanks for your help
[06:25] micheil: https://gist.github.com/4d3900a86a3cac15a843
[06:44] mikeal has joined the channel
[06:45] dnolen has joined the channel
[06:52] RayMorgan has joined the channel
[06:54] RayMorgan has joined the channel
[06:57] kennethkalmer has joined the channel
[07:12] rictic has joined the channel
[07:14] RayMorgan has joined the channel
[07:20] siong1987 has joined the channel
[07:42] Tim_Smart: nodejs_v8: Function.prototype.toString = function(){return eval('Object.getOwnPropertyNames(this)')}; (function(){})
[07:42] nodejs_v8: Tim_Smart:
[07:42] Tim_Smart: nodejs_v8: Function.prototype.toString = function(){return eval('this')}; (function(){})
[07:42] nodejs_v8: Tim_Smart:
[07:49] qFox has joined the channel
[07:58] elliottcable: gurgh
[07:58] elliottcable: this haaaaates me
[08:23] tlrobinson_ has joined the channel
[08:32] scudco has joined the channel
[08:36] Tim_Smart: Hmm can't get ChildProcess.write() to work corrently
[08:36] Tim_Smart: *correctly
[08:56] teemow has joined the channel
[09:31] jed has joined the channel
[09:32] chakrit has joined the channel
[09:54] Connorhd has joined the channel
[09:54] felixge has joined the channel
[09:54] felixge has joined the channel
[10:07] felixge has joined the channel
[10:11] ithinkihaveacat has joined the channel
[10:17] geelen has joined the channel
[10:20] BBB has joined the channel
[10:37] teemow has joined the channel
[10:38] lifo has joined the channel
[10:49] felixge has joined the channel
[10:49] felixge has joined the channel
[10:56] ayo has joined the channel
[11:00] micheil: hey, inimino, you about?
[11:01] felixge has joined the channel
[11:01] micheil: felixge: or you?
[11:02] micheil: because I'm lost as to the cause of this one: http://groups.google.com/group/nodejs/browse_thread/thread/22d23f001378f0db?hl=en
[11:08] micheil_mbp has joined the channel
[11:10] felixge has joined the channel
[11:10] felixge has joined the channel
[11:12] felixge: micheil: I'll check it out
[11:13] micheil: it looks like javascript engine isn't working correctly
[11:20] felixge: micheil: I don't get any test fails on HEAD
[11:20] micheil: niether
[11:20] micheil: are you on debian etch?
[11:21] felixge: osx
[11:21] felixge: I have on suspicion
[11:21] felixge: I think 'make test' uses the installed binary
[11:21] felixge: rather than the current build
[11:23] felixge: test.py looks good so
[11:23] felixge: hm
[11:30] micheil: I can't think of a reason why array.push wouldn't be avaialbe
[11:32] micheil: maybe hasOwnProperty is broken?
[11:33] felixge: micheil: they could have bad build cache from v8
[11:33] micheil: hmm..
[11:34] micheil: I got them to do a fresh checkout of node, that would mean there's no cache
[11:34] felixge: micheil: maybe 'make distclean' would help
[11:34] felixge: hm
[11:34] felixge: weird
[11:35] micheil: there doesn't seem to be any v8 issues open with debian
[11:35] micheil: or vica verse
[11:41] micheil: maybe get them to download the v8 source, tell them to make it, and give them a test file
[11:41] micheil: if v8 crashes on that, we know it's an issue with v8
[11:50] unomi has joined the channel
[12:02] felixge: micheil: I kinda think it's unlikely that it is a v8 issue
[12:02] micheil: hmm..
[12:02] micheil: I can't think of what could cause it in node though
[12:03] felixge: but then again, edge is old
[12:03] felixge: * etch
[12:03] micheil: hmm..
[12:03] micheil: true
[12:04] micheil: a second voice on the thread might be useful
[12:07] Connorhd_ has joined the channel
[12:12] markwubben has joined the channel
[12:28] Connorhd has joined the channel
[12:30] bryanl has joined the channel
[12:53] mies has joined the channel
[13:04] kriszyp has joined the channel
[13:15] charlenopires has joined the channel
[13:16] rtomayko has joined the channel
[13:18] micheil has joined the channel
[14:02] unomi has joined the channel
[14:21] paulca has joined the channel
[14:46] piranha has joined the channel
[14:57] jed has joined the channel
[15:07] paulca has joined the channel
[15:14] paulca has left the channel
[15:24] piranha has joined the channel
[15:35] aguynamedben has joined the channel
[15:37] dnolen has joined the channel
[15:50] alex-desktop has joined the channel
[15:52] piranha has joined the channel
[16:05] bobbywilson0 has joined the channel
[16:08] bobbywilson0: req.uri.path is returning "TypeError: Cannot read property 'path' of undefined", I am not sure why the uri object would be undefined in this case?
[16:11] ithinkihaveacat: maybe req.url? can you dump the req object?
[16:16] piranha_ has joined the channel
[16:23] bobbywilson0: ithinkihaveacat: is there an inspect type function to use to dump it? puts just gives me [object Object]
[16:24] deanlandolt has joined the channel
[16:25] inimino: bobbywilson0: it's url
[16:25] bobbywilson0: inimino: thanks
[16:42] ithinkihaveacat: bobbywilson0: yes: sys.debug(sys.inspect(req))
[16:47] nrstott has joined the channel
[16:49] bobbywilson0: ithinkihaveacat: oh cool, thanks
[17:02] technoweenie has joined the channel
[17:33] deanlandolt has joined the channel
[17:40] Yuffster has joined the channel
[17:50] isaacs has joined the channel
[17:54] dnolen has joined the channel
[18:06] mnutt has joined the channel
[18:15] omygawshkenas has joined the channel
[18:17] sudoer has joined the channel
[18:20] paulca has joined the channel
[18:36] rictic has joined the channel
[18:42] brandon_beacher has joined the channel
[19:01] piranha_ has joined the channel
[19:11] r11t has joined the channel
[19:14] scudco has joined the channel
[19:21] piranha has joined the channel
[19:23] mikeal has joined the channel
[19:25] rednul_ has joined the channel
[19:31] piranha_ has joined the channel
[19:40] bryanl has joined the channel
[19:46] isaacs has joined the channel
[19:48] gwoo has joined the channel
[19:51] piranha has joined the channel
[19:58] RayMorgan has joined the channel
[19:59] paulca has joined the channel
[20:11] rryan has joined the channel
[20:13] paulca has joined the channel
[20:18] BBB has joined the channel
[20:18] chakrit has joined the channel
[20:20] paulca has joined the channel
[20:31] paulca has joined the channel
[20:47] brandon_beacher_ has joined the channel
[20:50] binary42 has joined the channel
[20:57] brandon_beacher_ has joined the channel
[20:57] mikeal has joined the channel
[21:16] bobbywilson0 has joined the channel
[21:19] Tim_Smart has joined the channel
[21:19] nodejs_v8 has joined the channel
[21:26] Connorhd has joined the channel
[21:27] eikke has joined the channel
[21:27] sveisvei has joined the channel
[21:30] geelen has joined the channel
[21:41] piranha has joined the channel
[21:43] nrstott has joined the channel
[21:43] Tim_Smart: nodejs_v8: var test = []; for(let i = 0; i < 5; i++)test.push(i);test
[21:43] nodejs_v8: Tim_Smart: Exception: SyntaxError: Unexpected identifier
[22:07] tmpvar has joined the channel
[22:10] scudco has joined the channel
[22:27] rtomayko has joined the channel
[22:30] kriszyp has joined the channel
[22:47] mikeal has joined the channel
[22:59] tlrobinson_ has joined the channel
[23:12] deformated has joined the channel
[23:15] paulca has joined the channel
[23:19] eikke has joined the channel
[23:26] joshbuddy has joined the channel
[23:35] jspiros has joined the channel
[23:37] cloudhead has joined the channel
[23:45] rictic has joined the channel
[23:46] Yuffster has joined the channel
[23:46] jspiros has joined the channel
[23:52] eikke has joined the channel