TypeScript and node.js

2,869 views
Skip to first unread message

Tomasz Janczuk

unread,
Oct 1, 2012, 4:20:34 PM10/1/12
to nodejs
What is your opinion of the value TypeScript can bring to node.js
development?

What is TypeScript: http://www.typescriptlang.org/Playground/
1h video by Anders Hajlsberg: http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript

Thanks,
Tomasz

Dick Hardt

unread,
Oct 1, 2012, 4:30:44 PM10/1/12
to nod...@googlegroups.com
I think it is a step in the right direction.

+ Requires no changes to existing source.
+ Typing can be done where you want do do it.
+ Brings Visual Studio developers to node.js
+ Spec, code etc. is all open and MS seems open to input from others.

- slight change in compiled source from original -- would prefer original source to be passed through or inserted as comment on same line if really needed

-- Dick
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en

Lemol Morais Lutonda

unread,
Oct 1, 2012, 3:36:18 PM10/1/12
to nod...@googlegroups.com
"...+ Brings Visual Studio developers to node.js...", or viceversa?
Btw, there is also plugins for Sublime Text, Vim, Emacs.

I think it is awesome!

Atenciosamente,

Leza Morais Lutonda, Lemol-C
http://lemolsoft.webs.com
http://github.com/lemol
http://twitter.com/lemolsoft

El 01-Oct-12 5:30 PM, Dick Hardt escribi�:
Participe en la XVI Convencion Cientifica de Ingenieria y Arquitectura del 26 al 30 de noviembre de 2012. La Habana, Cuba: http://ccia.cujae.edu.cu

Consulte la enciclopedia colaborativa cubana. http://www.ecured.cu

José F. Romaniello

unread,
Oct 1, 2012, 4:40:52 PM10/1/12
to nod...@googlegroups.com

2012/10/1 Dick Hardt <dick....@gmail.com>

+ Brings Visual Studio developers to node.js


I was wondering about this... in the video he does a lot of emphasis in the code completion (intellisense). What is the value of this outside Visual Studio? Why you will make your javascript typed? just to compile it into something similar and get compiler errors?

Rick Waldron

unread,
Oct 1, 2012, 4:46:47 PM10/1/12
to nod...@googlegroups.com
It doesn't make your JavaScript typed. It makes you write programs that are type-enforced. Once the code is compiled, it becomes regular JavaScript. The benefit comes when v8 can super-optimize your code because you have "implied types".

Rick

Lemol Morais Lutonda

unread,
Oct 1, 2012, 3:48:06 PM10/1/12
to nod...@googlegroups.com
El 01-Oct-12 5:40 PM, José F. Romaniello escribió:

I was wondering about this... in the video he does a lot of emphasis in the code completion (intellisense). What is the value of this outside Visual Studio? Why you will make your javascript typed? just to compile it into something similar and get compiler errors?

At http://www.typescriptlang.org/#Download: There is also TypeScript support for other editors available.

Participe en la XVI Convención Científica de Ingeniería y Arquitectura del 26 al 30 de noviembre de 2012. La Habana, Cuba: http://ccia.cujae.edu.cu

Dick Hardt

unread,
Oct 1, 2012, 4:49:42 PM10/1/12
to nod...@googlegroups.com
Many code editors do code completion -- it is a great productivity tool for developers ramping on using modules they are not intimately familiar with. MS made the code available which makes it easier for other editors / IDEs to do the same.

For less sophisticated developers (most people, and most of the VS market), the compiler errors will remove much debugging frustration and allow them to focus on creating rather than debugging.

Code completion was a HUGE feature for Perl and Python developers when I built Komodo at ActiveState.

-- Dick

José F. Romaniello

unread,
Oct 1, 2012, 4:58:38 PM10/1/12
to nod...@googlegroups.com
2012/10/1 Lemol Morais Lutonda <lez...@fecrd.cujae.edu.cu>

At http://www.typescriptlang.org/#Download: There is also TypeScript support for other editors available.

this is just syntax highlighting, no code completion

José F. Romaniello

unread,
Oct 1, 2012, 5:15:13 PM10/1/12
to nod...@googlegroups.com
2012/10/1 Rick Waldron <waldro...@gmail.com>

The benefit comes when v8 can super-optimize your code because you have "implied types".

thanks! this is something I didn't know. I see some value there even for people like me not interested in compile time errors or working in visual studio (again, I have worked there for 7 years)

Gustavo Machado

unread,
Oct 1, 2012, 5:15:08 PM10/1/12
to nod...@googlegroups.com
For less sophisticated developers (most people, and most of the VS market), the compiler errors will remove much debugging frustration and allow them to focus on creating rather than debugging.


It also allows them to focus on "creating" instead of understanding what they are doing. Take the sample on the playground for instance:

constructor (message: string) {
this.greeting = message;
}

will translate to:

    function Greeter(message) {
        this.greeting = message;
    }

If you can only handle string, should you not be doing a check and writing a proper message? What will happen to javascript users that consume your code generated with TypeScript? It's not a huge gain IMO, and a few CONS:

- only get intellisense in VS (a gigantic IDE which will handle from databases, to manual tests).
- TypeScript seems to be making the code longer to type and less readable instead of shorter/better (like others do).
- yet another language/dependency on your project.
- most of the type-related things could be handled gracefully with comments.

Gus

Rick Waldron

unread,
Oct 1, 2012, 5:36:48 PM10/1/12
to nod...@googlegroups.com
You can't get runtime optimizations with comments.


Take a look at this example:

function f( a ) {
  return "Hello Number " + a;
}

// Say you called it like this, of course it will work,
// but the runtime won't necessarily optimize
// because you've given it no information about what
// it CAN optimize. Besides, you really wanted a string.
f(1);


// So enforce it...
function f( a: string ) {
  return "Hello Number " + a;
}

// throws on compilation
f(1);

// Which would encourage you to go back to your code
// and make it a string:
f("1");

// Now it passes the compilation and this is what it outputs:
function f(a) {
  return "Hello Number " + a;
}
f("1");

The point is that it made you think about what you were passing to the function.


The above example is fairly contrived and I'm sure that most runtimes will figure that specific case out and optimize just the same, but allow it to serve as a simplified example case.


Rick


 

Gus

Mark Hahn

unread,
Oct 1, 2012, 5:53:20 PM10/1/12
to nod...@googlegroups.com
The above example is fairly contrived

And useless.  The JS would work fine passing it a number.

Gustavo Machado

unread,
Oct 1, 2012, 5:58:21 PM10/1/12
to nod...@googlegroups.com
Rick, that's super interesting however I've said "most", and there's no reference to these type of optimizations in TypeScript. It even says "in any browser, in any host", so who will perform those optimizations? Looks like TypeScript is not. Actually, this:

Greeter.prototype.greet = function(a: string) {
return "Hello, " + a;
}

Translates to this:

Greeter.prototype.greet = function (a) {
    return "Hello, " + a;
};

So no +1 for TypeScript in this case :)

Gus

Rick Waldron

unread,
Oct 1, 2012, 5:59:40 PM10/1/12
to nod...@googlegroups.com
On Mon, Oct 1, 2012 at 5:53 PM, Mark Hahn <ma...@hahnca.com> wrote:
The above example is fairly contrived

And useless.  The JS would work fine passing it a number.

Did you actually read the entire example? I said that for you, but thanks for the additional coverage.

Yes, it will work, that's not the point. The point is that the runtime can optimize the execution if it can find ways to make assumptions about the code it's executing. One the most common is based on types.


Rick

Mark Hahn

unread,
Oct 1, 2012, 6:03:43 PM10/1/12
to nod...@googlegroups.com
Yes, it will work, that's not the point. 

Then give me an example that does make the point.  I'm a little thick-headed.

Rick Waldron

unread,
Oct 1, 2012, 6:04:28 PM10/1/12
to nod...@googlegroups.com
On Mon, Oct 1, 2012 at 5:58 PM, Gustavo Machado <mach...@gmail.com> wrote:
Rick, that's super interesting however I've said "most", and there's no reference to these type of optimizations in TypeScript. It even says "in any browser, in any host", so who will perform those optimizations? Looks like TypeScript is not. Actually, this:

Greeter.prototype.greet = function(a: string) {
return "Hello, " + a;
}

Translates to this:

Greeter.prototype.greet = function (a) {
    return "Hello, " + a;
};

So no +1 for TypeScript in this case :)

TypeScript definitely does not perform the optimization. The optimizations are performed by the runtime. 

Your example is essentially the same thing as the one I gave, so I dont know what point you're trying to make. If you had this in your code:

(new Greeting()).greet(1);

The TS compiler would throw an exception and tell you to fix the argument being passed, which means you'd change it to:

(new Greeting()).greet("1");


Now a runtime can look at your API and the function body of greet, then look at the calls and determine that _yes_ it will always be called with a string. This will allow the runtime to then perform explicit string optimizations (whatever those might be).


Rick

Rick Waldron

unread,
Oct 1, 2012, 6:05:08 PM10/1/12
to nod...@googlegroups.com
On Mon, Oct 1, 2012 at 6:03 PM, Mark Hahn <ma...@hahnca.com> wrote:
Yes, it will work, that's not the point. 

Then give me an example that does make the point.  I'm a little thick-headed.

See my last email to Gustavo.

Mark Hahn

unread,
Oct 1, 2012, 6:18:54 PM10/1/12
to nod...@googlegroups.com
 This will allow the runtime to then perform explicit string optimizations (whatever those might be).

But there aren't any optimizations that can be made.  All I'm asking for is one real use case that does something useful.

Rick Waldron

unread,
Oct 1, 2012, 6:28:30 PM10/1/12
to nod...@googlegroups.com
On Mon, Oct 1, 2012 at 6:18 PM, Mark Hahn <ma...@hahnca.com> wrote:
 This will allow the runtime to then perform explicit string optimizations (whatever those might be).

But there aren't any optimizations that can be made.  All I'm asking for is one real use case that does something useful.


Yes, there are and I've given you a legitimate use case: in this particular example, if the runtime can assume that no type coercion needs to occur, it can skip that step all together, which means it performs better.

Dave Clements

unread,
Oct 1, 2012, 6:44:29 PM10/1/12
to nodejs
I'm surprised at the confusion re: ricks point, it seems to center
around the word "optimized"...

I believe the point is that typescript enforces optimizable code
writing practices upon the developer.

Passing in a string to a function that expects a string and only works
with it as a string avoids implicit type coercian.

If there is no type coercian, not only have we saved the interpreter
an additional step (or steps), but it allows for runtime optimizations
(eg in the underlying C or even underlying assembly code) to be made
that would not be possible if implicit type coercian was neccessary.

I wont be using Typescript at this time - but its existence and this
discussion has made me think more about the way I use types.

A really awesome tool would be one that requires no extra verbage, but
works in the same "intellisense" way - saying things like "Are you
sure you mean this?" .... like a JSHint in the editor... wait I think
this already exists. Anyways, JSHint type guessing capabilities would
rock.

A final point, I don't think TypeScript should be classed as a
language, strictly speaking - its more of a... *waves hands* ..
precompilation syntax overlay.

That's possibly why there has been some confusion... calling it a
language makes you think it works like at has the same general purpose
as Javascript or Python or whatever, when it doesn't.

It's simply the complimentary linguistic interface to the whole
intellisense idea. Its a tool, not even a tool, *part* of a tool... so
I wouldn't call it a language,


Mark Hahn

unread,
Oct 1, 2012, 6:44:43 PM10/1/12
to nod...@googlegroups.com
if the runtime can assume that no type coercion needs to occur, it can skip that step all together,

Ok, I get it now.  This example is still really weak. You save at most a few nanoseconds.  To me the extra typing wouldn't be worth it.

I have to admit I'm really biased.  Not having to type vars is one of the best things to happen to me in the past decade.  I run into a problem that type-checking could find about once a month at the most.

However, I know there are many that will appreciate the typing and I wish you the best of luck.

Isaac Schlueter

unread,
Oct 1, 2012, 6:46:01 PM10/1/12
to nod...@googlegroups.com
I've been through the paces quite a few times trying to optimize the
hell out of very hot code. In the last few years, this has been
mostly in V8, of course, but the basic principles are not too far off
in different JS environments.

It's important to not put too much weight in rules of thumb, and we
programmers are particularly bad at that, given our tendencies towards
abstraction. But that disclaimer out of the way, I've found very few
exceptions to these two rules:

1. If you have more than one of something, use a class; not a "plain
old object". I recently changed the "url" module in node-master, and
made it twice as fast by replacing the plain {}-style objects with Url
class instances.
2. Always put the same kinds of things in the same places. An array
of numbers should only ever have numbers; an array of objects should
always only have objects. If a FooBar object has a "foo" member, then
set this.foo to *something* in the constructor.

It's really nice writing code in a loosely typed language. Most of
the time, these optimizations are not all that relevant, and when they
are, the odd exception is probably fine, if it's truly exceptional.
But when you really care about maximizing speed, that flexibility can
make it surprisingly tricky to track down all the deviations.

I'm probably not going to stop using Vim to write code any time soon.
I'm probably never going to use Windows as my development environment.
Code completion sort of annoys me, and I've usually turned it off
when I had editors that did it. But I'm actually very excited about
TypeScript.

It'd be a great idea to write up a TypeScript header file for the API
surface in Node. Then, we could automatically test for API
deviations, validate and flesh out our documentation, etc. Static
typing *does* confer some very relevant value. Typically it does so
at the cost of flexibility, but this brings a lot of the benefits to
JavaScript in an optional way, which is very powerful.

Also, it's not reinventing the language. It is JavaScript, mostly.
Or JavaScript entirely, if you just write JS and have a separate
declaration file, but with the benefits of linting that does more than
whine about comma placement and indentation, and *actually finds
subtle errors* in your programs.

There have been a lot of attempts to come up with ways to add type
hints and API-auto-documentation to JavaScript. (JSDoc, YUIDoc,
AS3/ES4, etc.) Most of those are not very compelling. The fact that
Microsoft is doing this, and building products on top of it (which
they will inevitably hope to make money on), is very encouraging. It
says to me that this is going to be a real thing with real developers
working on it, with budgets and timelines, and the whole bit. It's
somebody's job.


I had some suggestions that I passed along to the folks at Microsoft:

1. It'd be *amazing* if there was a way to automatically try to guess
at the best types, given a set of JavaScript code. Writing a
declaration file is insanely tedious. I don't want to do it, and
that's a blocker to adoption. I know that this is a hard problem, and
totally not what you'd expect in a first release, but hey, V8 is
guessing types pretty good, so it must be possible. That would make
me happy.

2. It'd be nice (as I think someone mentioned in this thread) to let
it put run-time type-checking into exposed functions at the API
surface. If this needed to be a dev flag or something, then that's
fine. I'd go ahead and let it in exported functions, though. We have
a lot of that code in Node, and it's tedious to write and maintain.

Rick Waldron

unread,
Oct 1, 2012, 6:47:38 PM10/1/12
to nod...@googlegroups.com
Thanks for this, I'm running out of steam and I appreciate you pitching in to help explain and clarify.

Also...

"A really awesome tool would be one that requires no extra verbage, but
works in the same "intellisense" way - saying things like "Are you
sure you mean this?" .... like a JSHint in the editor... wait I think
this already exists. Anyways, JSHint  type guessing capabilities would
rock."


Best idea ever. I want that.

Rick

Rick Waldron

unread,
Oct 1, 2012, 6:50:37 PM10/1/12
to nod...@googlegroups.com
Isaac,

This belongs on your blog, no joke. I'm going to nag you until you do it.

Rick

Alexey Petrushin

unread,
Oct 1, 2012, 7:00:08 PM10/1/12
to nod...@googlegroups.com, i...@izs.me
> It'd be a great idea to write up a TypeScript header file for the API surface in Node.

Can't it be done with plain js? Something like this

    // Implementation file.
    fs.readFile = function(name, callback){...}

    // Header file with types.
    fs.untypedReadFile = fs.readFile
    fs.readFile = function(name, callback){
      if(!_(name).isString()) throw new Error("name should be a string!")
      fs.untypedReadFile(name, callback)
    }

Alexey Petrushin

unread,
Oct 1, 2012, 7:02:22 PM10/1/12
to nod...@googlegroups.com, i...@izs.me
Or shorter, like:

    // Header file with types.
    fs.untypedReadFile = fs.readFile
    fs.readFile = function(name, callback){
      expect(name).to.have.type 'string'
      fs.untypedReadFile(name, callback)
    }

Rick Waldron

unread,
Oct 1, 2012, 7:05:10 PM10/1/12
to nod...@googlegroups.com, i...@izs.me
    }

--

An imperative "assertion" is not the same as simply ensuring that your actual code only ever passes a value of a single specific type.

Rick

Dick Hardt

unread,
Oct 1, 2012, 7:10:58 PM10/1/12
to nod...@googlegroups.com, Isaac Schlueter
+1 to putting this on your blog Isaac.

Shripad K

unread,
Oct 1, 2012, 10:46:29 PM10/1/12
to nod...@googlegroups.com
I'm sorry I don't have Windows running to test it on. Can you write multiple constructors/methods of varying types? How does TypeScript translate this code to equivalent JS code?

constructor (message: string) {
this.greeting = message;
}

constructor (message: number) {
this.greeting = message;
}

If it can translate properly, this definitely looks like a big plus for easing development in JS.

Raffaele Sena

unread,
Oct 1, 2012, 11:18:02 PM10/1/12
to nod...@googlegroups.com
I just tried in the "playground"
(http://www.typescriptlang.org/Playground/) and unfortunately it
doesn't work.

I also was hoping it could do this, but it's not a simple task if the
underlying language doesn't support it
(I wrote a Java to ActionScript converter and this is still one of the
few things I couldn't properly translate)

-- Raffaele

Shripad K

unread,
Oct 1, 2012, 11:19:39 PM10/1/12
to nod...@googlegroups.com
Okay I just tried it in the TypeScript playground. Doesn't seem like it supports translating multiple constructors/methods. Also, support for pre-initialization of variables before constructor is invoked would also be a good feature. However, TypeScript is definitely a step in the right direction. It would be cool if it could support multiple constructors/methods. Helps in converting this code:

var Test = (function () {
    function Test(message) {
        if(typeof message === "string) {
           this.greeting = message;
        } else if(typeof message === "number") {
           this.num = message;
        }
    };
    Test.prototype.setGreeting = function (message) {
          this.greeting = message;
    };
    Test.prototype.setNum = function(num) {
          this.num = num;
    };
    Test.prototype.getNum = function() {
          return this.num;
    };
    Test.prototype.getGreeting = function() {
          return this.greeting;
    };
    return Greeter;
})();

to a much cleaner code.. something like this:

class Greeter {
        num: number = 0;
greeting: string = "";
constructor (message: string) {
this.greeting = message;
}
        construtor (message: number) {
                this.num = message;
        }
void set(message: string) {
this.greeting = message;
}
        void set(message: number) {
                this.num = message;
        }
        string getGreeting() {
                return this.greeting;
        }
        string getNum() {
                return this.num;
        }
}

Yi Tan

unread,
Oct 2, 2012, 1:55:09 AM10/2/12
to nod...@googlegroups.com
IMHO, TypeScript makes Javascript feel like ActionScript/Java/C#... loss JavaScript's agility, and the things smell awful enterprise

My vote goes to coffeescript


Regards,

ty


2012/10/2 Shripad K <assortme...@gmail.com>

greelgorke

unread,
Oct 2, 2012, 8:06:25 AM10/2/12
to nod...@googlegroups.com
A word about saving debugging time through statical typing: I come from java, and i can tell, that the strongly typed environment never reduced the debugging effort for me. 'use strict'-pragma, inclusive existence checking and unit-test save me from debugging not statical types. in comparison with java i save much development time with js.

plus: maintainability is a two headed beast, and it comes first through a clean code und documentation, it don't really matters which language it is.

Typescript sounds more like a me2 to me, nothing more. i wonder if it will be there in 1-3 years or even leave the .net ecosystem.


Am Montag, 1. Oktober 2012 22:50:01 UTC+2 schrieb Dick Hardt:

On Oct 1, 2012, at 1:40 PM, José F. Romaniello <jfroma...@gmail.com> wrote:


2012/10/1 Dick Hardt <dick....@gmail.com>
+ Brings Visual Studio developers to node.js


I was wondering about this... in the video he does a lot of emphasis in the code completion (intellisense). What is the value of this outside Visual Studio? Why you will make your javascript typed? just to compile it into something similar and get compiler errors?

Many code editors do code completion -- it is a great productivity tool for developers ramping on using modules they are not intimately familiar with. MS made the code available which makes it easier for other editors / IDEs to do the same.

For less sophisticated developers (most people, and most of the VS market), the compiler errors will remove much debugging frustration and allow them to focus on creating rather than debugging.

Code completion was a HUGE feature for Perl and Python developers when I built Komodo at ActiveState.

-- Dick

José F. Romaniello

unread,
Oct 2, 2012, 8:36:51 AM10/2/12
to nod...@googlegroups.com
+1. I come from .Net (I am C# MVP) and this is exactly my opinion. TDD saves me from debugging not statical typing.

There is also another confusion I see a lot, when talking about node and JavaScript with people that comes from .Net and Java often I heard things like:

- "it is not self documented"
- "you dont have intellisense, how do you know how to call this api? "
- "this library uses new Thing() and this other one uses thing(), how do you know which one"

Having intellisense and code completion is a great thing, but do the exercise of trying to use [N]Hibernate (which is a big ORM library) without going to the website to see the usage... Or even better try to use log4net which is an small logging library without going to the documentation. It is a plus but it is just not enough, and you have to pay a big price.


2012/10/2 greelgorke <greel...@gmail.com>

Stephen Handley

unread,
Oct 2, 2012, 1:43:52 PM10/2/12
to nod...@googlegroups.com, Isaac Schlueter
+1 on this being blogged. not into TypeScript but would be very interested in you elaborating on the two rules / js optimization info you mention in the beginning.

Mark Hahn

unread,
Oct 2, 2012, 2:07:43 PM10/2/12
to nod...@googlegroups.com
Having intellisense and code completion is a great thing,

Code completion works quite well in sublime text 2.  It just looks at all your files and makes very intelligent guesses.

José F. Romaniello

unread,
Oct 2, 2012, 2:30:17 PM10/2/12
to nod...@googlegroups.com
AFAIK Sublime doesn't look all the files, it just provide code completion for the words within the current file. I saw a while ago an extension that did something alike but it was very slow.

My point is that this code completion is useful and it is cheap;
  • I don't have to change to another language (even if is small subset of javascript) 
  • I don't need Visual Studio Professional, an expensive IDE in terms of money and in terms of resources. As my friend Gustavo said visual studio is an IDE that can be used to handle from databases to manual tests) 
  • sublime is really fast at doing this
If I choose to pay this price for having a very detailed code completion feature what's the benefit I get? And one of the things i was explaining is that people always tell me about self documented code and in my experience that doesn't work quite well. Try to use hibernate or log4j for the first time without the documentation just with eclipse code completion.
 

2012/10/2 Mark Hahn <ma...@hahnca.com>

Rick Waldron

unread,
Oct 2, 2012, 2:45:11 PM10/2/12
to nod...@googlegroups.com
On Tue, Oct 2, 2012 at 1:43 PM, Stephen Handley <stephen...@gmail.com> wrote:
+1 on this being blogged. not into TypeScript but would be very interested in you elaborating on the two rules / js optimization info you mention in the beginning.

Stephen,

Isaac was kind enough to post this yesterday: http://blog.izs.me/post/32697104162/thoughts-on-typescript

:)

Rick

Daniel Morilha

unread,
Oct 2, 2012, 7:19:36 PM10/2/12
to nod...@googlegroups.com
so all of this to end up with a type safe, which compiles, has classes and the the syntax reminds C.

So why not use C++?

On Tue, Oct 2, 2012 at 1:47 PM, Dominick Pham <domini...@gmail.com> wrote:
semi-related note, I'm very impressed that cloud9 already has TypeScript support

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en



--
Daniel Morilha (dmor...@gmail.com)
Reply all
Reply to author
Forward
0 new messages