Questions and Answers, Activities

For each chapter, you will find questions and answers allowing you to review and consolidate your understanding of the chapter. The page also proposes activities related to the chapter. This material will help you to "dig further" and deepen your knowledge of Silverlight 2.

Chapter 1

Quiz

  1. What are the “ancestors” of Silverlight in terms of Web Technologies?
  2. How can you get the Silverlight runtime updated automatically?

Answers

  1. One can mention Java applets, ActiveX controls and Flash applications as the main ancestors of Silverlight. All three technologies are add-ons to the web browser and enable rich content to be added to web pages.
  2. Right-click on any Silverlight application and use the “Update” tab to configure the way the Silverlight runtime is updated.

Chapter 2

Quiz

  1. Why do we say that XML is eXtensible?
  2. What is the difference between x:Name and x:Key?
  3. Why do Top and Left use this strange syntax Canvas.Top and Canvas.Left?
  4. Why can we write properties using a short form and an expanded form?
  5. Why can I use either a SolidColorBrush or a LinearGradientBrush to fill my Ellipse?
  6. How do I make sure that an element is always on top of all others?

Answers

  1. XML is eXtensible because you can add namespaces to eXtend the document model, using the xmlns:prefix syntax.
  2. x:Name gives a name to an element so that you can retrieve it from the code. x:Key is used in the resources collection only, to uniquely identify the stored element.
  3. Since Top and Left are applicable to any element added to a Canvas, it makes more sense to define these properties on the Canvas and to attach them to each child. This is what attached properties are for.
  4. The short attribute form is a shortcut, convenient to allow you to type less. The expanded form is needed for more complex contents, which would be impossible to express using the short form.
  5. You can use any Brush you like, because the Brush class defines some common functionalities that are available in all subclasses, for example SolidColorBrush, LinearGradientBrush, RadialGradientBrush, and so on.
  6. You cannot be 100% sure that an element will always be on top of all the others. You can assign a high value to the Canvas.ZIndex property, but you cannot really be sure that another element will not assign an even higher value.

Activities

In SilverlightPad (online), take some time to review some of the examples, and to understand how they are constructed. Review the XAML markup, try to modify it, and understand how your changes modify the display.

http://silverlight.net/samples/1.0/Silverlight-Pad/default.html

Chapter 3

Quiz

  1. How can we make sure that the center of a rotation is always in the middle of the transformed element, whatever its size is?
  2. Can you set any value as the ScaleX or ScaleY properties of a ScaleTransform?
  3. What's an affine transform? Can you modify an element any way you want?
  4. Can you animate anything?
  5. How long does an animation last?

Answers

  1. To set the origin of a transform in the center whatever the size of the element is, use the RenderTransformOrigin attribute, which is relative to the element's size.
  2. You can set ScaleX or ScaleY to almost any value: These are Double! The range is huge, noninteger numbers are okay, and you can even set them to negative values (this will reverse the element and its content).
  3. An affine transform keeps parallel sides always parallel. To create a non-affine transform, you can move the points of certain elements (Path) separately.
  4. You can only animate dependency properties. Fortunately, most properties in Silverlight elements are DPs.
  5. An animation lasts as long as you want it to. You can set the attributes BeginTime, Duration, RepeatBehavior, and AutoReverse to change the total length of the animation.

Activities

In SilverlightPad (online), open the Blocks scene. Locate the yellow block's animation and make it move twice as fast. Then, open the Media scene and edit the MediaElement like this:

<MediaElement Source="http://www.galasoft.ch/SL2U/Hour05/mov1.wmv"/>

Observe how you can even rotate videos in Silverlight (we'll use this feature again later). Modify the scene to add more animations, for example, an opacity animation. Note that because the video file must be loaded before the animation starts, the Media scene take a little longer to load the first time.

Chapter 4

Quiz

  1. What is the purpose of the Objects and Timeline category?
  2. How do you set the default Margin and Padding used in the Design panel?
  3. How can you space the GradientStops exactly when you create a gradient brush?

Answers

  1. The Objects and Timeline category is used to visualize the logical tree of the XAML content, and to create animations (we'll learn this soon!).
  2. The default Margin and Padding are set by choosing Tools, Options, Artboard from the menu.
  3. You can space the GradientStop exactly by looking at the XAML markup and setting the Offset attribute.

Activities

  • In Blend, create a new Silverlight 2 application.
  • Right click on the “LayoutRoot” Grid, and select “Change Layout Type / Canvas”.
  • Then, re-create in Blend the scene we typed in XAML in chapter 2.

Chapter 5

Quiz

  1. What is the code for the color Red?
  2. What is a raster graphic, and what problems do they cause?
  3. How do you avoid that an image is distorted?
  4. How can you "flip" an image or a video to show it "from behind"?

Answers

  1. The following codes can be used: "Red", "#FFFF0000", or "#FF0000".
  2. Raster graphics are graphics defined by pixels (as opposed to vector graphics defined by primitives). Their major problem is that they look unsmooth when a zoom effect is applied to them.
  3. The Stretch attribute can be set to None, Uniform or UniformToFill. The image may be cropped, however, depending on the container's size.
  4. You can "flip" an image or a video by applying a ScaleTransform to it with ScaleX or ScaleY set to a negative value.

Activities

Using the Thumbnails application we prepared in this hourchapter, add additional images or videos to the gallery. Make sure you save your code carefully, as we will continue to build this application later!

Chapter 6

Quiz

  1. How do you round a rectangle's corners in Blend?
  2. What do you get if, instead of a gradient brush, you use a SolidColorBrush for the OpacityMask?
  3. What path do you get if you combine two paths using the Intersect method?

Answers

  1. You can round the rectangle's corners by selecting the rectangle and then using the "scattered line" adorners near one of the rectangle's corners. This has the effect of setting the RadiusX and RadiusY properties in the XAML markup.
  2. An OpacityMask using a SolidColorBrush is not very exciting: It's the same as setting the Opacity property!
  3. The Intersect method combines two paths by preserving the area common to both paths, and erasing the other areas.

Activities

Using Blend, re-create all the transforms that we wrote in Hour Chapter 3, "Playing with XAML Transforms and Animations."

Chapter 7

Quiz

  1. What checks should you include in your Silverlight application to make sure that all conditions are there for a smooth ride?
  2. When you move a XAP file (or the HTML file referencing it) from one folder to another, what do you have to do to make sure that your application runs?
  3. What is the windowless attribute and when does it have an effect?
  4. Can you reference a XAP file located on another web server, and if yes at what conditions?

Answers

  1. To make sure that the Silverlight application works fine, you should check that Silverlight is available in the minimal version needed for the application to run. You can do this by making sure that the type attribute targets the correct version, and that alternative content is provided within the object tag.
  2. When a XAP file (or the HTML file referencing it) is moved into another folder (for example from bin\Debug into the root folder of the web application), you must make sure that you update the source parameter in the object tag to point to the XAP's new location.
  3. The windowless parameter, if set to true, allows your Silverlight content to "blend" better with the HTML content of the host page. The windowless parameter has an effect only on Windows operating systems. It is always true on the Macintosh operating system.
  4. It is possible to reference a XAP file located on another web server. However, this only works if the HTML file and the XAP file are both loaded in the same mode, either File mode or HTTP mode.

Activities

Create a new Silverlight application and integrate it in your own web page. For example, you can take the XAML "Welcome" animation we created in Chapter 3, "Playing with XAML Transforms and Animations," and create a banner for your home page. This way, you'll be spreading the good word about Silverlight and helping to get the framework installed on additional computers!

Chapter 8

Quiz

  1. How would you debug a JavaScript application if you don't have an integrated debugger?
  2. How do you assign a JavaScript event handler to a JavaScript event?
  3. What is the main advantage of using JSON to set options on JavaScript objects?
  4. How do you create static members in a JavaScript object?

Answers

  1. Debugging a JavaScript application without a debugger can be done by adding alert commands within the JavaScript code, to display the value of certain variables. It is not as comfortable as using a debugger; also the debug code must be removed before deploying the application! But it can be a lifesaver in certain situations.
  2. A JavaScript event can be handled by passing a reference to any JavaScript function (or method) to the event. You might have to use the createDelegate method to make sure that the context of the method is set correctly.
  3. There are two advantages to using JSON to pass options to a JavaScript object:
    • The notation is very compact.
    • It's easy to set only certain options, and to leave the others untouched.
  4. JavaScript doesn't really have static members, but this behavior can be simulated by setting an attribute or a method on the class instead of the prototype.

Activities

  • Design your own "Install Microsoft Silverlight" HTML code and integrate it in the GalaSoftLogo SilverlightBookCover application. Then test the code by disabling the Silverlight add-on in IE (like we did in Hour Chapter 7) or by requesting a version that doesn't exist yet (for example V3.0).
  • Advanced: Install the Venkman debugger for Firefox, and run the GalaSoftLogo SilverlightBookCover code in the debugger, understanding how the JavaScript and Silverlight objects are initialized. For more information about how to use the Venkman JavaScript debugger for Firefox, refer to the documentation.

Chapter 9

Quiz

  1. What are the main differences between the ASP.NET application and the Silverlight application?
  2. Why does (5 / 2) return 2 instead of 2.5?
  3. What is the difference between a while loop and a do … while loop?
  4. What happens if the end condition of a loop is never met?

Answers

  1. The ASP.NET application runs on the web server, while the Silverlight application runs on the web browser. There is no direct link between them. Additionally, the ASP.NET application runs on .NET 3.5, while Silverlight runs on a subset of the framework.
  2. The operation (5 / 2) returns 2 because 5 and 2 are integer numbers, so the division is also an integer division.
  3. In a do … while loop, the loop is always executed at least once, even if the condition is false from the start.
  4. If the end condition of a loop is never met, the application is in an infinite loop and cannot be recovered anymore. It is necessary to kill the process iexplore.exe.

Chapter 10

Quiz

  1. How do you make sure that a method or a property is only accessible to other classes in the same assembly, but not outside it?
  2. What should you always do before you raise an event in your class?
  3. How do you write to a text file in the isolated storage in Silverlight?

Answers

  1. You can make a method or a property available only within the assembly it is defined in by setting its visibility to internal.
  2. Before raising an event, you must check whether someone subscribed to it. If nobody did, raising the event will cause an error. You can check this by comparing the event to null. If it's not null, there is at least one subscriber, and it is safe to raise the event.
  3. First you need to get the isolated store for this application. Then you need to open a Stream on this store. Finally, if you want to write text, the easiest way is to wrap a StreamWriter around this Stream.

Activities

  • Clean up the Page constructor by storing the code to initialize the media elements and the code to set the Last Visit TextBlock each in a different method. To help you with this, you can select a section of code and then right-click. From the context menu, select the menu Refactor, Extract Method.
  • Add an indication of how many days it was since the user's last visit. To do this, follow the indications:
    • The code to calculate the number of days should be placed in a method.
    • The current Date/Time can be found by using the property DateTime.Now.
    • To calculate a duration (called a TimeSpan in .NET), you can simply substract two DateTime instances.
    • To check the number of days that a TimeSpan counts, use the TimeSpan.Days property.
    • For all other questions, refer to the Silverlight developer documentation!

Chapter 11

Quiz

  1. What is the difference between a timeline, an animation, and a storyboard?
  2. You have two animations in a storyboard, one of them lasting 2 seconds, and the other lasting 3 seconds. How do you make sure that both animations end simultaneously?
  3. What is absolutely necessary if you want a storyboard created in code to work correctly?

Answers

  1. An animation and a storyboard are both timelines. A storyboard is a group of animations.
  2. To have both animations end simultaneously, you must set the shortest animation's BeginTime property to “0:0:1”, which is 1 second.
  3. Storyboards created in code must be added to the user control's (or to any other element's) resources. Failing to do so doesn't cause an error, but the storyboard won't start.

Activities

For all the examples in this hourchapter, study the XAML markup produced by Blend. Try to match what you see with the XAML knowledge you have so far. In general, Blend is a great way to learn XAML: Create complex scenes in Blend and then check the produced XAML markup.

Chapter 12

Quiz

  1. How will you know if you can import a video, and what should you do if you cannot?
  2. How can you protect your video with a copyright?
  3. How do you add subtitle to your video application?
  4. What is a keyframe?

Answers

  1. If you can play the video on your computer, chances are good that you can also import it in Encoder; but unless you try it, you won't know for sure. If it fails, you need to look for the good codec on Internet!
  2. You can add copyright information to your video by specifying metadata information. However, this information can be removed if someone really wants to steal your work!
  3. You add subtitles by adding Script commands with the type Caption.
  4. A keyframe is a frame in the video for which the whole image information is saved. For other frames, only the changes between the previous and the current frame are saved.

Activities

Try different encoding formats and compare the result. Once you have found the perfect settings, make sure that you save the job to your hard disk. Then, encode a video with chapters and captions. In the next chapter, we publish the video you create now to the World Wide Web!

Chapter 13

Quiz

  1. Why is streaming better than downloading for videos?
  2. What kind of overlays can you add to a video file using Expression Encoder?
  3. What is a query string and how can you use it?

Answers

  1. There are two main advantages to streaming a video instead of downloading it:
    • For the web server, streaming wastes much less bandwidth than downloading (though depending on the video's content, one can argue that it's wasted anyway).
    • For the user, streaming is more dynamic than downloading, especially if the user wants to fast forward.
  2. You can use an image, a video, or an XAML animation as an overlay in Expression Encoder.
  3. A query string in a URL is everything that comes after a question mark "?". Because it can be retrieved in JavaScript, one possible use is to parameterize the web application by saving the parameters' values in the query string. When the URL is bookmarked, the query string is saved, too, so this is handy.

Activities

Modify the video player further in Blend. Understand how the XAML elements are structured, and how the designers worked to create a polished look and smooth transitions.

Advanced Activity

Follow the directions located at the following URL to publish content to Silverlight streaming servers manually. This is needed sometimes if you want a better control over the files that you are publishing, or if you don't have the Expression Encoder plug-in installed.

http://blogs.msdn.com/tims/archive/2007/04/30/silverlight-streaming-is-now-live.aspx

Chapter 14

Quiz

  1. What needs to be done to expose some members from .NET to JavaScript?
  2. What's the difference between “ScriptableMember” and “ScriptableMemberAttribute”?
  3. When you use the following syntax to call .NET methods from JavaScript, how do you get the “[control]” part? [control].Content.[objectname].[methodname]([parameters]);

Answers

  1. To expose members from .NET to JavaScript, these members need to be public, they must be "decorated" with the “ScriptableMember” attribute, and the class containing them must be registered with the HTML page, using the method “HtmlPage.RegisterScriptableObject”.
  2. “ScriptableMember” and “ScriptableMemberAttribute” mean exactly the same. Since by convention all attributes are named with the “Attribute” suffix, you can refer to attributes with or without this suffix.
  3. The Silverlight “[control]” can be fetched by setting an ID on the HTML “object” tag, and by using “document.getElementById”. Alternatively, use “sender.getHost()” in the “onload” event handler.

Chapter 15

Quiz

  1. What can you do in code-behind but not in XAML?
  2. What can you do in XAML but not in code-behind?
  3. What is probably the most exciting feature of the Grid?
  4. What kind of shapes can Expression Blend draw?

Answers

  1. There are just a couple of things that you cannot do in XAML directly, such as implementing data binding converters (we'll talk about that in hHourChapter 18) or reacting to events.
  2. Nothing! Everything you can do in XAML, you can also do in code-behind. But it's often more wordy and cannot be generated by a tool such as Expression Blend.
  3. Grids are great for many things, but maybe the most exciting feature is that their children will automatically resize when the cells containing them grow or shrink. This allows "flow layout," and not having to recalculate an element's position when the Grid's size changes.
    Note: Of course you can set an element so that its size never changes, even if it is contained in a Grid's cell.
  4. Blend can draw Ellipses, Rectangles, and Paths. As for Polygons, Polylines, and Lines, Blend uses Paths to represent them. However, if you type the XAML code markup by hand (or import it), Blend canis able to represent these shapes too.

Activities

Using Blend and the Properties pane, explore various panels. Then, check the resulting XAML codemarkup. Try to nest panels within panels to create complex layouts.

Then, spend time checking the documentation about shapes such as Polyline, Polygon, Line, and Path. Use this information in XAML and check the result.

Chapter 16

Quiz

  1. What's the difference between a ToggleButton and a CheckBox and a RadioButton?
  2. What's the difference between a CheckBox and a RadioButton?
  3. What's value coercion?

Answers

  1. Thanks to the separation of functionality and appearance, the differences between a ToggleButton and a CheckBox are limited only to the control's look and feel. Even though CheckBox is derived from ToggleButton, it doesn't define any new functionality.
  2. The only difference between a RadioButton and a CheckbBox (apart from the fact that they look different) is that if RadioButtons are placed in a group (using the “GroupName” property), they are mutually exclusive.
  3. Value coercion is a mechanism that allowsing to enforcinge of some rules and making sure, for example, that a value is always comprised between a Minimum and a Maximum.

Activities

Publish the “SilverlightDraw” application to your web server and let your friends (and your kids!!!) play with it.

Then add an “Undo” operation. Here's a tip: The Strokes are added to the InkPresenter in the “Strokes” collection in the order in which you drew them on the screen. Check the method “RemoveAt”!!

Chapter 17

Quiz

  1. What is the difference between a class, an abstract class, and an interface in .NET?
  2. What's the main difference in the usage of the StaticResource markup extension in XAML, and accessing resources in code-behind?

Answers

  1. A class has all its methods (and properties) implemented. An abstract class has at least one method (or property) that is specified, but not implemented (abstract method). An interface is a specification only; its properties and methods are specified, but none are implemented. An interface is like a contract between the class developer and the class user. You can implement multiple interfaces, but you can inherit only one class (or one abstract class).
  2. The StaticResource markup extension looks for resources in the current control. If the resource is not found, it will "walk the tree" up and try to find it in the parent, the parent's parent, and eventually in the Application and in the System. This possibility doesn't exist in code-behind, and you can only access the control's local resources. See Chapter 24 for an implementation solving this issue.

Activities

Modify the three Styles that we create in this chapter for the Thumbnails application, and see how one change affects multiple controls.

Study the default template of controls other than the CheckBox, and understand how the Silverlight designers created them and what elements compose them.

Check Corrina Barber's blog at http://blogs.msdn.com/corrinab, and search for her posts about Silverlight controls skins. Start experimenting!

Chapter 18

Quiz

  1. What are the different modes of Binding, and what do they do?
  2. What does a data object need to do to propagate a value change to a bound element?
  3. What can a data control be bound to?

Answers

  1. A Binding's mMode can be set to “OneTime” (meaning that the value will be fetched once only when the Binding is initialized), “OneWay” (the value changes are propagated from the source to the target only), or “TwoWay ” (the value changes go in both directions). The default is “OneWay”.
  2. To update the bound elements, a data object needs to implement the “INotifyPropertyChanged” interface. When a property value is set, the “PropertyChanged” event needs to be raised.
  3. A data control (ItemsControl, ListBox, DataGrid and so on) can be data bound to any class implementing IEnumerable (such as an Array, a List, and so onetc…). However, if you want changes to the collection to be propagated to the data control, you want to use an ObservableCollection.

Activities

Use the SDK documentation to learn more about the DataGrid at http://msdn.microsoft.com/en-us/library/cc189058(VS.95).aspx.

Then use your favorite Search engine to find additional samples online (the keywords "silverlight datagrid" should help).

Chapter 19

Quiz

  1. What's the difference between a uUser cControl and a cCustom cControl?
  2. How can you be notified when the value of a DP is changed?
  3. Why can you instruct the VSM to not use transitions when a state is applied?

Answers

  1. A User Control has an XAML front-end while a Custom Control is fully lookless. Apart from that, both are quite similar, but Custom Controls are better suited to be "packed" in a separate assembly and used in multiple applications.
  2. You need to pass a “PropertyChangedCallback” event handler to the “PropertyMetadata”, which you create when you register the DP.
  3. The VSM should be able to place the control in an initial state without delay. In that case, transitions should not be used.

Chapter 20

Quiz

  1. How do you define a default look and feel for your Custom Controls?
  2. Why aren't all the assemblies referenced in a project's “References” folder copied to the “bin” folder?
  3. What is one advantage of storing data in the Application object?
  4. What is one disadvantage of storing (too much) data in the Application object?

Answers

  1. You define a default look and feel by creating a file named “generic.xaml” in the a folder named Themes, in the same assembly as the control. In this file, create a ResourceDictionary, and add a Style without a key, but with the TargetType attribute set to the control's type. You can define the default appearance of the control (including transitions) there. Also, don’t forget to set the property DefaultStyleKey in the control’s constructor!
  2. Some assemblies are included in Silverlight's default installation, and must not be included in your application. They are already available on the target client.
  3. The Application object is accessible from anywhere in the application using the syntax “App.Current”.
  4. As a disadvantage, however, all data in the Application will be global. This speaks against modularity, and it can worsen the performance of your application.

Activities

In ThumbnailsViewerControl, add a new DependencyProperty (for example, named “ShortDescriptionMaxLength”) to the “MediaInfoDisplay” control, allowing a user of this control to change the length of the ShortDescription property. NoteNote the following:

  • Whenever this property is changed, the “ShortDescription” should be recalculated.
  • Because “ShortDescription” is a DP, the control's view should automatically be updated when this occurs. (Tip: tip: bBind the value through a new property in the “Settings” class.).
  • You can even try to build a test application to change the “ShortDescriptionMaxLength” during the runtime!

Chapter 21

Quiz

  1. How can JavaScript access Silverlight UI elements?
  2. In JavaScript to .NET communication, why aren't JavaScript Numbers directly converted to a .NET int?
  3. What is a partial class, and when are they especially used in Silverlight?

Answers

  1. The sender parameter passed to the JavaScript handler of the onload event in the Silverlight application gives access to the content of the Silverlight UI. You can use the findName method with the name of the element you want to access in JavaScript.
  2. JavaScript doesn't differentiate between floating point and integer numbers. Since .NET has no way to know whether the Number should be treated as a double or an int, it takes the safe path and treats all of them as double because it's the only way to avoid implicit loss of information. If the .NET developer wants to handle the Number as an int, he needs to convert explicitly.
  3. A partial class is a class spread through multiple files. In Silverlight, this is especially useful for the compiler to generate code-behind automatically and to "wire" the XAML elements and the code.

Activities

Step through the Thumbnails application and understand what the code is doing. Switch back and forth between Silverlight and JavaScript debugging.

Chapter 22

Quiz

  1. How can you filter the content of the MediaFiles folder (or of the MediaFiles.zip) to display only images?
  2. How do you make sure that the source code files placed in App_Code are compiled into the web server application?

Answers

  1. In the LINQ query, you can filter the results with a where clause. The query only returns the elements from the input collection corresponding to the filter.
  2. The special folder App_Code is not accessible for Internet users, but its content should be copied to the web server. The files it contains are compiled on demand.

Activities

Set the path of the media files folder and of the XML media information file location in a parameter for the Silverlight application (initParams).

Chapter 23

Quiz

  1. When is a server considered “cross domain” for a Silverlight application? How can this server accept service requests from the Silverlight application anyway?
  2. What are the two main classes you use to send web requests?
  3. What does “asynchronous request” mean?
  4. Why shouldn’t you simply set an unhandled exception to “handled” and let the application run?

Answers

  1. A server is considered “cross domain” for a Silverlight application when the domain is not the same, and/or the protocol is not the same, and/or the port is not the same. The server can allow service calls anyway by placing a “crossdomain.xml” file or a “clientaccesspolicy.xml” file at its root, with the corresponding permissions enabled.
  2. The two main classes for web requests are the “WebClient” class (for simple and more complex requests) and the “HttpWebRequest” class (for very complex requests).
  3. An asynchronous request is sent without blocking the user interface. The user can continue working without having to wait that the response arrives. Silverlight web requests are always asynchronous.
  4. Setting an unhandled exception to “handled” might leave the application in an unstable state, and risk an even worse crash later.

Activities

Using the method “flickr.photos.getInfo” on Flickr, send an additional request for each picture. This method returns additional information about the picture, such as the author’s name, the date taken, the tags, etc… Use this information to extend the description displayed when the picture is clicked.

http://www.flickr.com/services/api/flickr.photos.getInfo.html

Chapter 24

Quiz

  1. How can you protect critical code from prying eyes?
  2. How can you define chapters for a movie with the “MediaPlayer” ASP.NET control?
  3. What is the most important advantage of Test Driven Development TDD?

Answers

  1. You can protect your code by leaving it on the web server and creating a service (SOAP, WCF, etc…) to provide an interface to it.
  2. You can either write the chapter list in the ASPX page (with the assistance of the ASP.NET designer or by manually editing the Chapters property). Or, you can use the chapters' definition file exported from Expression Encoder, and setting the MediaDefinition property of the MediaPlayer control.
  3. The most important advantage of TDD is that if you change anything to your code (for example refactoring it, adding or removing features…), running the existing unit tests makes sure that you didn't break anything.