Pushing Codepen Angular2 and Typescript to Build Component Playgrounds

There are more than 30 different sites that offer code playgrounds where you can play with HTML, CSS, and Javascript and see the results. As of today, I believe there are really two worth pursuing for the designer/developer who wants to break up a large app into more manageable components.

If I was giving out medals for code playgrounds capable of building complex components, I’d give out two silvers to Codepen and Plunker, and a bronze to jsfiddle. I believe gold is still up for grabs.

For the longest time, I preferred to do my tinkering in jsfiddle since it felt more flexible until last month when I started experimenting with Angular2 and playing with their example plunks.

Plunker strength is its ability to create multiple files and begin simulate the complex file structure which one would encounter in a large app. It beats Codepen on this front, and I believe its currently easier to develop Angular2-based components because one can create classes and import them properly.

I started an Observerables plunk to experiment with this concept new to angular 2. Unlike promises, Oberservrables can emit multiple values over time and manage unidirectional data flow as described in this nice post, Angular 2 Observable Data Services.

In my plunk, I wasn’t interested in listening to streams of data over time but I wanted to use an oberverable as a message bus which I could include in any class and have that class communicate with any other class through a pub/sub pattern. I also wanted to use named custom events which are more familiar to me than listening to data that simply changes and it allows me to apply filters on those names. As I grow my accustomed to this pattern, I’ll probably drop the named event training wheels.

While experimenting with my crude, blocky art, I got inspired to build a tool that could create blocky illustrations, the type found in indie games like Fez, Sword & Sworcery or Queen under the Mountain.

Plunker didn’t feel like the right tool to bang what I thought would initially require only 1 file of each html, css, and javascript. It was basically a coin flip between jsfiddle and codepen to build it, and heads it landed on Codepen. Subconsciously, I’m sure there were other factors that drew me to codepen over jsfiddle; many are outlined in this 2015 blog post. Codepen is doing more to promote community, celebrate their contributors and build the best code playground.

When I landed on Codepn, instead of diving right into the code, I like how they curate a selection of pens. I went a through a number of them and noticed several seem to brag about being “pure css” and when I looked at their CSS, I thought they were either using some tool that I didn’t know about it or they were painstakingly tweaking the css by hand. I couldn’t believe their attention to detail if they in fact hand coded each line by tweaking numbers as demonstrated in this post on creating art by building SCSS matrix. By hand. Madness. Of course, this is something I do all the time. Beautiful madness.

Back to my original plunk, I wanted put simple div-based art assets: tree, mountain, river, and buffalo in my scene. I didn’t want to tweak numbers. I want to design these assets by “painting” with blocks; similar to how minecraft paints with cubes but drag around 2d triangles and rectangles dropping them in place.

How hard could it be to create this tool? I sketched out a three column grid design involving a toolbar 5%, sketch pad 70%, and code catcher 25%, and began building it one pen. I came up with Buffalo Builder, a simple tool to produce minimal illustrations that can be used in apps and games. This felt like a cool and dangerous side project as it ultimately could distract from other side projects which also begged for my attention.

I spent about 2-3hrs on it every day for a week, and by fourth day it was starting to get both unwieldy and also pretty good. I was able to create crude animals, and I liked my proof concept but the code base was getting too large for a prototype.

At this point, my account was still free, but after some googling about managing external resources in code pen, I had my go-for-pro moment when I discovered that pro accounts could create multiple pens and use them as a resources within one pen. I opted for the yearly subscription price $75 and plan to show my co-workers its value, and thus make something I could easily expense. After paying, I immediately flipped the pen from public to private. Like most artists, I do get a bit uncomfortable about having eyes on my work before its ready for public consumption.

Once my monolithic pen reached a few hundred lines of code, I dismantled it and broke it up into six separate pens, one of each main component of the app including things like a tools, sketch, and image reference sections. I could open each component pen in a tab to work on them individually.

I imported the CSS and JS into the master pen to assemble the app.

Then, I used the external pens as html templates.

Buffalo Builder, as an app pen, is a buggy disaster, but I’ll share it anyway so that you can see the structure, and mind the mess. Its neat how pro members can share a public pen comprised of many private pens. I believe you are probably more interested in the basic pattern so that you can start designing and developing your own tools.

It’s basically vanilla javascript, a little jquery, and greensock’s draggable since I first found the html5 drag/drop to be too awkward for what I wanted. Part of the fun of a code playground is instilling challenges on your work to improve your skills. It becomes a game; a puzzle to unlock with the reward being that eureka of solving something or the realization that some library isn’t worth pursuing. Being able to test-drive and make these quick, petri dish experiments outside of your large application, will save you considerable time in the long run and have significant impacts on your domain expertise. For this one, I added the side quest: how far could I get with plain javascript before I had to lean on a library.

After learning how I could use external resources with plain javascript, I wanted to see how I could apply this technique to Angular2 and Typescript. On Codepen, I did a search for Angular2 examples and browsed through many until I found one that I liked; this one by Angular2 Template with TypeScript by Mikko Kämäräinen which in turn is a fork of Martin Maier-MoessMartin pen . You can see how Mikko had a nice splash of simple design to make his pen pop. It’s also well commented.

Instead of a single file, I forked this pen four times to create a pen app leveraging two external asset pens: a tools component pen and sketch component pen to build the final app pen. My fourth template is a tool component pen which is supposed to be contained in the Tools component. When I add Tool to Tools, the brush will appear, however, if I then try to run to the app, it fails throwing an error: “EXCEPTION: Unexpected directive value ‘undefined’ on the View”.

I had no problem creating deeply nested components in Plunker and this is obviously when the Angular team picked it to showcase their excellent intro to Angular2 Tour of Heroes plunk. The file tree structure is clean, familiar, and easy to browse.

Until I can figure out how to create deeply nested components, I can’t really recommend Codepen over Plunker for experimenting with Angular2 unless you’re only interested in developing one level deep, then it feels just right.

When I experiment, I personally don’t like creating To-Do list type demos but would rather work with elements from nature or pop culture. I had recently watched Revevant and really enjoy frontier stories involving spirit animals like giant grizzly bears or the white buffalo.

While this inspiration is pretty wild, all the coding concepts do directly relate back to my day job designing and developing enterprise UI where privacy is paramount. With private pens, you can safely include sanitized client data to test your components and not worry about exposing any new IP or sensitive information.

Whether you’re building an enterprise app, complex data visualization, or MMORPG,  they are all comprised of lots of individual components that work together to form the whole experience. So whether you want to build a simple fail whale or T-rex…

…or the next Stardew Valley…

consider building shallow components in Codepen or deep components in Plunker for your next project.

Codepen, when you follow through on this file system promise, the gold is yours.

Gandalf casts Marionette’s CollectionView herds ItemView hobbits


tl;dr: The benefits of extending Backbone with MarionetteJS’s CollectionView are explored in this post and Fellowship Demo

When tasked with the front-end architecture for a large application, my goal is to build many small javascript files and html templates that can be compiled to one production ready file. This makes it easier to maintain within a team instead of working with more monolithic files that can breed code merge nightmares. I will gladly write (and refactor) my code into more files if it means less code and complexity per file.

There are a few popular, open source javascript MVC libraries at your disposal. For me, the choice boiled down two main factors: my aptitude to incrementally learn a new approach and the community support behind it. This blog post will discuss my decision to go with Backbone.Marionette over Angular for a large application. For now, I’m reserving Angular for toy side projects. The short answer is simply I had more experience with Backbone, and I believe in the future, I could possibly flip this decision.

Over the course of 2012/2013, I had already put two major Backbone-based projects behind me; the last one being Voices, a Backbone and D3 based data visualization tool. I  wanted to advance that knowledge on my next project. I realized there were few things flawed with how I put the pieces together. In my google searches, I would often reference Derick Bailey’s blog about how to write better Backbone’s apps and that introduced me to his MarionetteJS project.

While reading through the MarionetteJS documentation on github, this section struck me as desirable:

Like Backbone itself, you’re not required to use all of Marionette just because you want to use some of it. You can pick and choose which features you want to use. This allows you to work with other Backbone frameworks and plugins easily. It also means that you are not required to engage in an all-or-nothing migration to begin using Marionette.

While Angular sounded like “all or nothing”; that I would have to learn all of it before getting any benefit; Marionette seemed to be saying I only had a few more things to add my existing knowledge base.

If you subscribe to Javascript weekly like I do, you’re bound to come across ads and posts declaring Angular (or any new JS codebase) as being easy to learn. For instance, this Angular pitch from Frontend Masters:

Dive into AngularJS, a framework that makes it easy to organize code using concepts like two-way binding, dependency injection and views which results in very testable code. See how easy it is to build simple jQuery directives with AngularJS in this sample lesson.

The word “easy” always seems to make me uneasy. When I came across the word “easy” tied to any library or framework, I try to think that the author is speaking in relative terms. Instead of “easy”, I’d prefer that they would say “easier”; as in this library will make your life easier than using that library and here’s why. If you are working with any framework for this first time, there is usually nothing easy about it. There is a spark of insight that attracts one to it – moth to flame – and then light suddenly burn; it’s all pain and burninating until the new pattern sinks in; you shed that charred skin; and finally think, “hey, that is easy” but not “that was easy”.

My first day approaching Marionette’s extra features wasn’t easy but, unlike Angular, I could see the proverbial light at the end of the tunnel. I knew I only had to learn a small segment which should only take a couple hours, and that was enough motivation to help push me through this learning process. While Marionette’s approach to creating sub modules, multiple routers, and it’s use of “regions” looked interesting, they were not something that I needed right away. I did want to pick up its “Controller”, missing from Backbone, and its ItemView and CollectionView, that seemed perfect for managing lists of views, and my application design called for lots of lists.

Marionette relies on inheritance, and right away I discovered a few things that are different from regular Backbone views. At first glance, I was surprised not to see “initialize” and “render” within the example of how to extend the ItemView class but knowing that ItemView inherits all the functionality of a View, I knew that they are being used in the super class. I also learned that I had to trust the library to work its magic, and I could look at the ItemView source to get a better sense of what was happening behind the scenes. Again, this is beauty of inheritance.

After setting up an ItemView, I then went on to create a CollectionView and had a similar experience where it took some fiddling  and hair pulling until I could get it to make a connection with it’s repeated ItemView. In my tests, I experimented with various lists like a table, div, ul, or ol, and they all worked as I expected them to. In this code example, you can see that it’s fairly bare bones; that most of the work is done in the super collectionView class.

// see https://github.com/headwinds/tutorials/tree/master/marionettejs/marionettejs-collection-view
], function(_, Backbone, Marionette, UserItemView, UserModel, UserCollection ) {
var UserCollectionView = Backbone.Marionette.CollectionView.extend({
el: "#users",
tagName: "tbody",
itemView: UserItemView,
onAfterItemAdded: function(itemView){
//console.log(itemView.model, "UserCollectionView - item was added");
onRender: function(){
var that = this;
// you can also loop through items here...
return UserCollectionView;
view raw gistfile1.txt hosted with ❤ by GitHub

This UserCollectionView is taken from my sandbox demo. Whenever I approach a major new library, I’ll sandbox it into an experimental tech demo and take this opportunity to step away from practical and geek out with fantasy data:
fellwoship demo

I’ll let this demo and source speak for itself, and stress that this is a time-boxed experiment; several of the interactions are unwieldy and you may encounter bugs but I believe there is enough there to demonstrate the flow and ignite your own experiments. I commandeered the base of this demo from this beginner Backbone video demo and layered on Marionette, Require, and D3 [I’ve been obsessed with SVG lately will save that for a future post especially since Adobe just released snap ]. If you view the source, you’ll notice it basically meets my goal to also compile down to one production file that consists of all the concatenated javascript and html templates.

One of my pet peeves that I see in many javascript examples is the use of lowercase file names like “user.js” “article.js”. I’ve seen this in Backbone and I thought that might also be the norm in Angular until I came across this reassuring post by Cliff Myers that other Angular developers promote explicit file names following with the name and type like “UserModel.js” or “ArticleService.js”. In Angular, I don’t know if this translates to creating new instances like it does in Backbone. I’ve used it in other languages and when I read a line like:

var userCollectionView = new UserCollectionView();

I can quickly make assumptions that userModel is an instance of the class UserModel. It takes the guesswork out of development, and even with an extremely long name like DragonFireworksController, one has only to type that out once, and then double click on it each time to make copies. A quick copy and paste command along with updating the first character to lower case, and I’m ready to use that instance. I’d never use “var dfc = ” like some do. Again, this is a personal preference which I’m recommending as it pays off in the long run when you return to the code.

How are we able to use this class pattern in a language that doesn’t support classes? Requirejs is the glue that holds everything together and enables modules which quack like classes so let’s just call them that.

In the top of the class, I can import all the files that it depends upon. I have “initialize”, a constructor function, where I can pass in arguments and finally I have series of public functions which can be called when I initiated new versions of this class. Personally, it doesn’t bother me too much that these all public functions not further subject to protected or private permissions.

MVC is the most common, most used design pattern. I’ve applied it successfully in several languages. I was looking for the same approach in Javascript and was put off by other libraries that call themselves MVVM, MV*, or the flippant MVW or MVWhatever. I know what those js hipsters are getting at but it’s not whatever to me.  I like the comfort of having a base class called “Controller” which I can extend. The fact that Marionette offers everything that Backbone does and the, on top of that, includes many other classes that extend Backbone’s view. After learning how to use the CollectionView, I’ve already graduated to the CompositeView using it build out a complicated tree structure.


While I count myself a fan of both libraries, I know that they are both built to accomplish the same thing: large, complex javascript applications. They are opinionated and take different approaches to reach this goal. At the time, I decided there was more risk in investing in something that was relatively unknown to me and would cloud my work-related estimates. I knew that I could do everything that I wanted to do with Backbone and if Marionette could improve development with extra stability and common design patterns, that would be a big win.

It’s really not about the libraries anyways; it’s about the people behind them. It’s too bad these libraries aren’t twin titans; that they aren’t complimentary; that the Fellowship is split; like you have to choose between Aragon or the white wizard to accompany you on your march to mount doom.

here be dragons WEBGL tech talk

saga comic

I attended my first @torontojs tech talk thursday night. It was held @bentomiso, my favourite co-working space.

The tech talk evening was dedicated to WEBGL and modern web browsers that can now render OpenGL in the browser through the html5 canvas tag.

I was pleasantly surprised to see the new event setup at Bento with about 20 rows of chairs and a dedicated sound guy who I believe was @RobbyDuguay. In the past, its been less formal; more of a round table talk.

Getting Started with WebGL

First up, Mike Acquino ( @maqblurb | mylifeatruntime.com ) who introduced himself as an old school graphics programmer and a 2d visual storyteller who happened to use 3D tech as his medium, referring to the way South Park developed their shows.

I thought the code side of his talk was pretty decent. He went over the history of OpenGL and its evolution on both the web and native devices (OpenGL ES). It was not overwhelming and over the head of any novice who has attempted to use a 3D library like threejs before so I felt like I was following along for the most part. I’m just going to give a shout out to the Papervison3D crew for nostalgia.

Unfortunately for me (and I’m sure many of the more visually minded developers), he paired the code discussion beside this scrolling text demo and left it up on the screen beside his code for 30 minutes. I joked with another attendee, @AliGhafour, that I could do the same thing in JQuery in less than 3 lines of code. All he had to do was spin it once to blow our minds, and then close it to calm them.

He also baited us with an image of Saga but didn’t say anything about it. Obviously he’s a fan, and if you’re not hooked too snap up Saga, Vol. 1.

This presentation ended on a high note though finally dropping the distracting text replacing it with this jaw dropping 3D gunship!

webgl gunship

He then toggled the views revealing the mesh and texture mapping. Along with this impressive interactive demo, he also recommended checking out the millionth tower project as some of the best examples WEBGL on the web today.


Next up, Rob Gilson ( github ) talked about his 3D printing project and his fascination with the internet of things; the ability for your devices to talk to other appliances like having your fridge message you if you’re low on almond milk and avoid that awkward attempt to borrow from your neighbour who only has almonds anyways.

He demoed his first prototype which had a neat WebGL view of the 3D printer and talked about how he eventually scrapped this approach for a command line interface. Dropping the rich UI didn’t really serve his hardcore coding audience and allowed him to concentrate on the functionality. He praised BDD with Mocha and Chai as vital part of testing and stabilizing his desired feature set. I will second this approach and also highly recommend both along with Should over Expect; which is hopefully obvious if you appreciate a simple, English-centric syntax.

3D models can contain massive amounts of binary data that can crash a web browser. He discussed how he used web workers to process the data in the background allowing the user to still interact with the interface. He actually proved that a browser would lock up by running a fibonacci sequence generator with and without the help of web worker while monitoring the activity of the CPU through htop on his Macbook air.

I was a bit taken back by his more complicated implementation of web workers. I’ve had some experience using them in the past to handle box2D routines and took a different, relatively easier approach which I stole from Seth Ladd’s post.

He also talked about how he packaged up his app as a Chrome extension and went over the requirements file which any node developer who find similar to a package.json file. His final act was a wild experiment involving websockets called massively multiplayer mice which you can find on his github page, and he invited anyone in the room to connect to the page with any device. So go grab a friend and duel mice.

My biggest take away from Rob’s talk was the blob, where you can now take large data sets and save them to the local file system without hitting the server. I’m currently dealing with big data that drives an SVG presentation and have been experimenting with ways to capture and share these infographic-like visuals but maintain their interactivity and instead of taking static shots with something like phantomjs.

Although its currently possible to produce 3D graphics in modern browsers, it doesn’t mean that 3D is the appropriate medium for all future content on the web. Mike’s work and the South Park example did spark some ideas though about how I could use 3D to bring more life into a largely 2D experience. I’m beginning to see the value of moments of surprise within an UI where I could manipulate the UI in 3D with WebGL or even with some of the emerging CSS3 3D translations, especially dealing with modal windows where we can provide content on both sides.


I actually wasn’t planning to review these sessions but after I couldn’t find a way to drop Mike a nice note, I decided that this might work as an indirect high five. After failing to find his contact or even a comments section on both his sites, I looked at my own site and realized I didn’t have direct contact solution either.

On my own site, I have been relying on the disqus plugin for wordpress (also available for tumblr and other blogging platforms hint hint Mike ;-D) for commenting and decided to simply add a new contact page; although there should be no reason for anyone to actually contact me just yet. Why do I even have a site then?! The plan is do some teaching next summer once this Brood King figures out how to manage my current and future zerglings [ Anyone else up late watching Jaedong dominate last night?! Pumped for the finals tonight! ].

I know I tend to duck contact from prowling recruiters who simply call me up at work anyways; but do indies also need to make a game out of direct contact? My marketing senses, hammered into me from my agency years, scream that an indie would want a strong CTA on their site to funnel requests for new business and have their website work for them when they’re not out networking. Speaking of which, if you’re also interested in joining future sessions, be sure to join the torontojs meetup.

Running with the Parkdale Mascots

Tuesday night was my first official group run of the season. I took a big, 5-month break from group runs after my Running Room clinic ended last October culminating with the ScotiaBank half-marathon and a super-stressed out achilles tendon.

Instead of the tuesday night RR group, this time I hooked up with the Parkdale Runners who have a nice instagram feed; proof that I at least left with them. I had read an article about them competing in the the ragnar rally. It actually felt like I had stepped into the article. They were actively discussing their plans. I overheard one runner mention his diet plans swearing that the best thing for him was blending beets into in his smoothies; that if they were good enough olympics athletics then surely they’d also propel him forward, risking a bout of the am-I-dying-oh-right-I-ate-beets beaturia.

With this new group, I worried a bit if I would able to keep up or would they leave me in the dust? Fortunately, for me and my well-rested, fully recovered limbs, they settled on a decent pace of around 5:30/km which still allowed for light conversation.

The pack was led by the alpha dog owner of 416 Snack Bar, a definite favourite local watering hole. Along the run, I asked him about a bit about the nights, and he told me the group is open to all types of runners and usually attracts a group of 30 people. They also run through all seasons. I’ve done winter running in the past but simply over did it last year probably combining what I’d normally do over 2 years into 4-5 months. Joining running groups tend to increase your running schedule through planning and promoting running several times a week. With sports, I could manage twice – one short and one long run a week. This season, along with Ultimate, I have a personal goal to double up my short runs (5-10K) and keep the long sunday run (15-20+K), and pray that my ankles hold up for the full marathon in October.

I was pleasantly surprised to find out a few people at the Mascots run shared this same personal goal to run their first marathon; not everyone was a hardened veteran returning with tales of horror of the Boston bombing.

Since I was meeting new people for the first time, the conversation inevitably arrived at “So what do you do?” After the first one, I realized that I really need to work on introducing and reducing that down to  20 words or less. My current pitch is that I work at Intelliresponse which provides a service that allows you to visit any website and ask a question as you normally would and unlike traditional search engines where you get thousands of results, we provide you with the best possible answer. Yeah, a mouthful.  I’d like to distill that down further to perhaps two parts. Personally, I like answering a question with a question:

“What do you do?”

“Well have you ever had trouble finding what you’re looking for on a website?”

I’ll assume the answer will most likely be yes but my response should also work with no.

“Sure,” they’d say and most likely tune back into their inner running mantra.

or better yet… I’ll make one this up and apologize to Best Buy for being my guinea pig.

“Yes, I was on Best Buy website and typed in, ‘how do I return my broken iphone?’ but got back 6,000 results and the top three were some terrible blue ray movies”.

“So”, I’d say hopefully without a hint of smugness, “if they had our service, you would get back one article about iPhone repair”.

Actually, I just tried the same question of Amazon.com with much better results. They provided 5 with the last one about Apple Care Protection probably being the best possible answered. We aim to make it the first. To me, the metaphor of a website as a window to your business is obviously fascinating, and, after years in advertising trying to dazzle people with a complicated conteet experience that coughs up a coupon, I find this focus on simple text and natural language refreshing. It’s more about enabling meaningful conversations over side show distractions. But, to any of my advertising friends reading this, I believe these two worlds could work well together. I think there are ways we can bring the oracle to the coliseum.

If I visit Nike.com, why can’t I simply ask something like “why are compression socks good for me?”. Here are the results or lack thereof:

ask nike about compression socks

Instead of nothing, wouldn’t it be better to connect the question to this nice 3D interactive compression sock product page?! Better yet, include a video featuring nike talent, even if it is randy.

But not to pick on Nike too much. I’m a big fan of Nike+; wouldn’t leave without my satellite watch nor my pair of last year’s Pegasus. Nike also sponsors several running groups in my area organizing four groups.

Anyways, work-related tangent aside, that’s basically what I’ve been doing lately and sums up some of the thinking. It’s much easier to explain than what my wife does. She’s an Actuary, which was recently voted top job. If anyone asks, I like to start by saying she’s in “re-insurance” just to watch their brains scramble to grasp that, and then let them off by adding, “she helps manage the risk involved with insuring large pools of money”. And then, depending on the person, I might make a joke about Scrooge McDuck but it’s really nothing like that at all.

As we ran the 6K along the waterfront, I met two radically different PHD students; one working on sustainable fashion and the other studying the displacement problems faced by our native american who as very young children had been separated from their parents and shipped off to boarding schools and also suffered from diabetes.

I used this opportunity to slide in a reference to Born to Run, which is currently sitting on my night stand but I’ve only read the first chapter which tells the story of these Native American “super athlete” kids who would flee their boarding schools and run back to the reserves over several days!

Our group would only be out for 30 minutes though. We basically formed a train; two loose groups with ragged sprinters (sub 5) at the lead and the slow and steady at the back. Like the running room, it’s a pace where you can run and talk freely but unlike RR they don’t frown on headphones if you desire to lone wolf for a bit.

[soundcloud url=”http://api.soundcloud.com/tracks/68093563″ params=”” width=” 100%” height=”166″ iframe=”true” /]

After I accidentally stood up too fast without realizing my Yurbuds cable were wrapped around my chair, I decided to replace them with this Sennheiser set which are far superior in both sound and price; a real steal right now since the new model is out. I highly recommend them if you’re looking for comfortable, clean sound. While staying true to their word about not ever falling out while running, the Yurbuds had too much distortion. I wish ear buds had a break away system like my Bose headphones which I managed not to learn my lesson and did the same thing; snapping them but instead of replacing the entire set for $200, I only had to order a new cable for $30.

I plan to run again with the Mascots but next Tuesday will most likely be my last time. Not because I didn’t enjoy it but simply because my wonderful wife has opted to play Ultimate on Tuesday night instead, and after having our first child we quickly tossed out the idea of playing on the same night and bringing her to the games; at least until she get can get her flick on.

My plan now is to replace that tuesday night run with a pre-work run; something I’ve never be able to do in the past but I think I’m up for it now. Wish me luck. It looks good on the screen. This is actually something I admire; people who can get up by 5 or 6 am start their day and practice this early to rise philosophy. Now, if I only I can find an 7:30 am running group starting from a nearby coffee shop; thoughts white squirrel?