Basic guide to setup Ruby and Ruby on Rail in Ubuntu

This beginner’s guide will set up with Ruby 1.9.3, RVM and Rails 3.2.1 and is specifically written for a development environment on Ubuntu (versions 10 through 12), but will probably work on many other operating systems, including older / newer versions of Ubuntu and Debian. YMMV.

If you’re looking for a way to set this up on a production server then I would recommend the use of the railsready script which installs all the necessary packages for Ruby 1.9.3p0 and then that version of Ruby itself, Bundler and Rails. Then it leaves it up to you to install Apache or nginx to get your application online.

If you’re not using Ubuntu then try Wayne E. Seguin’s rails_bootstrap_script which probably gets Rails 3.0.9 working for you, albeit with 1.9.1 rather than 1.9.3. But in this guide, we’re going to want to use Ruby 1.9.3 and Rails 3.2.1.

Under no circumstance should you install Ruby, Rubygems or any Ruby-related packages from apt-get. This system is out-dated and leads to major headaches. Avoid it for Ruby-related packages. We do Ruby, we know what’s best. Trust us.

Still not convinced? Read this.

This guide will go through installing the RVM (Ruby Version Manager), then a version of Ruby (1.9.3), then Rails and finally Bundler.

By the end of this guide, you will have these things installed and have some very, very easy ways to manage gem dependencies for your different applications / libraries, as well as having multiple Ruby versions installed and usable all at once.

We assume you have sudo access to your machine, and that you have an understanding of the basic concepts of Ruby, such as “What is Rubygems?” and more importantly “How do I turn this computer-thing on?”. This knowledge can be garnered by reading the first chapter of any Ruby book.

If you’re looking for a good Rails book, I wrote one called Rails 3 in Action.

Housekeeping

First of all, we’re going to run sudo apt-get update so that we have the latest sources on our box so that we don’t run into any package-related issues, such as not being able to install some packages.

Next, we’re going to install Git (a version control system) and curl which are both required to install and use RVM, and build-essential which is required to compile Ruby versions, amongst other compilable things. To install these three packages we use this command:

sudo apt-get install build-essential git-core curl

RVM

RVM is a Ruby Version Manager created by Wayne E. Seguin and is extremely helpful for installing and managing many different versions of Ruby all at once. Sometimes you could be working on a project that requires an older (1.8.7) version of Ruby but also need a new version (1.9.3) for one of your newer projects. This is a problem that RVM solves beautifully.

Another situation could be that you want to have different sets of gems on the same version of Ruby but don’t want to have to do deal with Gem Conflict Hell. RVM has gemsets for this. This is a feature you wouldn’t have if you used the packaged Ruby.

We’re going to use it to install only one version of Ruby, but we can consult the documentation if we want to install a different version of Ruby.

With git-core and curl installed we’ll be able to install RVM with this command:

curl -L get.rvm.io | bash -s stable

The beautiful part of this is that it installs Ruby to our home directory, providing a sandboxed environment just for us.

Once that’s done, we’re going to need to add a line to ~/.bashrc file (the file responsible for setting up our bash session) which will load RVM. Do this by running this command in the terminal:

echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"' >> ~/.bashrc 

Then we’ll need to reload the ~/.bashrc file which we can do with this small command:

. ~/.bashrc

The next command we run will tell us what other packages we need to install for Ruby to work:

rvm requirements
...
# For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following:
ruby: /usr/bin/apt-get install build-essential openssl libreadline6 libreadline6-dev 
curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev
libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion

A couple of these packages we’ve already installed, such as git-core and curl. They won’t be re-installed again.

These packages will lessen the pain when we’re working with Ruby. For example, the libssl-dev package will make OpenSSL support in Ruby work, libsqlite3-0 and libsqlite3-dev are required for the sqlite3-ruby gem and the libxml2-dev and libxslt-dev packages are required for the nokogiri gem. Let’s install all these packages now using this command:

sudo apt-get install build-essential openssl libreadline6 libreadline6-dev \
curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 \
libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison  \
subversion

Now our Ruby lives will be as painless as possible.

Ruby

With RVM and these packages we can install Ruby 1.9.3:

rvm install 1.9.3

This command will take a couple of minutes, so grab your $DRINKOFCHOICE and go outside or something. Once it’s done, we’ll have Ruby 1.9.3 installed. To begin using it we can use this lovely command:

rvm use 1.9.3

Please note, using ‘1.9.3’ as a default allows for when ruby is updated for that version then ALL projects using 1.9.3 as their string will be updated as well. This is a side affect people might not want. The preferred method is to include the patch level to the ’–default’ parameter so that if 1.9.3 gets updated, other projects don’t automatically have that change applied to to them as well. If, say for example, for some reason some method/action gets deprecated in a patchlevel or some method signature gets changed between patchlevels, this will affect all projects defined using the ‘1.9.3’ string. This may or may not be what people want. Please be aware of this! Now, to continue on..

Are we using 1.9.3? You betcha:

ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]

Or, even better, would be to make this the default for our user! Oooh, yes! Noting the ‘1.9.3’ side-note above, lets take note of the patchlevel, which in this case is ‘-p194’ and add that to our default selection.

rvm --default use 1.9.3-p194

Now whenever we open a new bash session for this user we’ll have Ruby available for us to use! Yay!

As an additional side-note: Users can, and should, use a gemset when possible so that they don’t pollute their ‘default’ which is what is selected when a gemset is not specified in either a project’s .rvmrc, or at the command-line. Each installed Ruby has a ‘@global’ gemset. This is used to share gems with other gemsets created under that specific Ruby, and with the ‘default’ gemset. This can be selected by running ‘rvm gemset use global’ and then installing the gems you wish to share to other gemsets including ‘default’. You can, of course simply install in each gemset but this will cause needless duplication and use up more disk-space and bandwidth.

Rails

Now that RVM and a version of Ruby is installed, we can install Rails. Because RVM is installed to our home directory, we don’t need to use that nastysudo to install things; we’ve got write-access! To install the Rails gem we’ll run this command:

gem install rails -v 3.2.3

This will install the rails gem and the other 28 gems that it and its dependencies depend on, including Bundler.

MySQL

If you’re planning on using the mysql2 gem for your application then you’ll want to install the libmysqlclient-dev package before you do that. Without it, you’ll get an error when the gem tries to compile its native extensions:

Building native extensions.  This could take a while...
ERROR:  Error installing mysql2:
	ERROR: Failed to build gem native extension.

/home/ryan/.rvm/rubies/ruby-1.9.3-p0/bin/ruby extconf.rb
checking for rb_thread_blocking_region()... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lmygcc... no
checking for mysql_query() in -lmysqlclient... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

PostgreSQL

Similar to the mysql2 gem’s error above, you’ll also get an error with the pg gem if you don’t have the libpq-dev package installed you’ll get this error:

    Building native extensions.  This could take a while...
ERROR:  Error installing pg:
	ERROR: Failed to build gem native extension.

/home/ryan/.rvm/rubies/ruby-1.9.3-p0/bin/ruby extconf.rb
checking for pg_config... no
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Fin.

And that’s it! Now you’ve got a Ruby environment you can use to write your (first?) Rails application in with such minimal effort. A good read after this would be the official guides for Ruby on Rails. Or perhaps the documentation on the RVM site which goes into using things such as gemsets and the exceptionally helpful per-project .rvmrc file. A quick way to generate an .rvmrc file is to run a command like this inside the project:

rvm use 1.9.3-p194@rails3 --rvmrc

RVM is such a powerful tool and comes in handy for day-to-day Ruby development. Use it, and not the packages from apt to live a life of development luxury.

 

Reference : http://ryanbigg.com/2010/12/ubuntu-ruby-rvm-rails-and-you/

Advertisements

Install and Configure Rhodes Application in Window x64 for cross device

If you’re running Windows, ensure that Java Development Kit is installed. The Sun JDK for Windows is available here.

Download the latest RhoStudio for Windows and run the download file to install RhoStudio.

If you use Symantec Antivirus it can warn about “Suspicious.MLApp” security risk in rubyw.exe file during installation. It is known false positive in Symantec antivirus.
Ignore this warning.
Use Motorola RhoStudio 64-bit to run RhoStudio with x64 JDK.
Use Motorola RhoStudio 32-bit to run RhoStudio with x86 JDK.

Setting path to the Java Development Kit

In RhoStudio Preferences, open RhoMobile and check that the path is set to your JDK installation.

Generating a Rhodes Application

You also can use RhoStudio to generate a RhoConnect application and source adapter. You can see an example in the RhoConnect tutorial.

In RhoStudio, select File->New->Project…

The New Project window opens. Select the RhoMobile application wizard and click the Next button.

Enter the name for your Rhodes application in Project name; in this case, “storemanager”. You may specify a specific folder for your destination where your project is stored, by default, the destination is your RhoStudio workspace folder. Uncheck the RhoElements checkbox if this is to be a strictly Rhodes application. Then press the Finish button.

After pressing the Finish button, you’ll see the Rhodes app generator script output in the output console (Rhomobile build console).

Generating a Rhodes Model

Rhodes applications support a Model-View-Controller (MVC) pattern.  To start our application, we will generate a Model. To generate a Rhodes model and create the associated Controller and View templates, right-click on the application project in the Project Explorer and select New->Rhodes model.

In the Model Information window, enter the name for your model: in this case, Product. Also enter the Model attributes as a string with no spaces and each attribute separated by a comma: in this case, name,brand,price,quantity,sku. (Whitespaces at the field name beginning and end will be trimmed and whitespaces in the middle of the field name will be replaced with an underscore character.)

Click the Finish button to create the model.

After pressing the Finish button, you’ll see the Rhodes model generator script output in the output console (Rhodes build log console).

You should now see a ‘Product’ folder below the ‘app’ folder in your storemanager application. These files constitute the Model, Views and Controller file for the Product Model we just created. The files are organized as follows:

  • product.rb –> This is the Model file which contains the Model definition. Since we are using the default PropertyBag definition, we don’t need to modify this file any further.
  • product_controller.rb –> This file contains the business logic which relates to our Model.
  • *.erb –> The .erb files are the html view template files. We’ll be modifying them in the next section.

Editing Rhodes Views

You may edit the generated ERB files to customize the HTML as you see fit. Typically you will provide links to the model index page from the home screen. In order to accomplish this, a modification needs to be made to the default view for the application, called index.erb. Below is the content for the StoreManager app’s generated top level index.erb file (app/index.erb). Open this file for editing.

Storemanager

<% if SyncEngine::logged_in > 0 %>

Sync

Logout

<% else %>
Login
<% end %>

To provide a link to the Product model’s index page and templates, replace the list item with the title ‘Add link here’ with the following:

<li>
    <a href="Product">
        <span class="title">Products</span>
    </a>
</li>

This change now means that when the index.erb view is displayed (the default view when the app starts), you will see a UI element called “Products” that will take you to the controller for the “Product” Model definition. Because no specific action is provided, the controller will default to displaying the Model’s index page, in this case the Product model’s index page. All further functionality in the app is carried out by the default scaffolding of the generated controller and view files. These generated files provide basic CRUD (Create, Read, Update, Delete) functionality for your Model.

You can edit the top level app page or any of the other view templates with any HTML you wish. We don’t attempt to teach you HTML or Ruby here, but there are many good external references for both topics.

Managing Your Build Configuration

The build.yml file for your application manages your Rhodes build time configuration. Double click on ‘build.yml’ item in your project tree to open the build.yml editor. In the editor you’ll see two tabs: Rhobuild setting for the WYSIWIG editor, and build.yml for the text editor.

Rhobuild setting WYSIWIG editor:

build.yml text editor:

You will have default values for your application name, log file (the log file will be located in your application folder after you run your application), and the path to the Rhodes gem. You can use the WYSIWIG editor to change this. For example, you might want to point to a different RHodes gem if you have more than one Rhodes gem installed.

You can add capabilities to your application, such as camera and vibrate, by pressing the Capabilities: Add button, selecting the capabilities from the popup window, and clicking the Ok button.

The selected application capabilities will appear in the Capabilities: text field in the WISIWIG editor.

Building and Running Your Application

To start the build process, create a Run Configuration: select your project in the Project Explorer, and select Run->Run Configurations… from the menu. The Run Configurations window appears.

To create a new build configuration for your application, select Rhodes Application. Then either right-click on Rhodes Application or click the New button. A new configuration appears under Rhodes Application.

Building and Running with RhoSimulator

You can run your project in RhoSimulator, a simulator type available only in RhoStudio. RhoSimulator allows you to build and run your project on the platform of your choice without having to install the SDK for that platform. Instead, RhoSImulator will mimic the platform. RhoSimulator builds and runs your application quickly, making it useful for testing and debugging.

Once you have done your application development and debugging, you will need to install the SDK to create a build for that device. Or you can upload your project to RhoHub, and use RhoHub to create the build for your device.

To run RhoSimulator for the iPhone platform, select your project from the Project Explorer (in this case, we use the storemanager project created earlier). Then select Run –> Run Configurations from the main menu. The Run Configurations window appears.

In the Run Configurations window, select RhoSimulator for the Simulator type, and select your desired platform type. For example, if you select iPhone, RhoSimulator will mimic an iPhone. The calls to the system will return as though the application was running on an actual iPhone.

Click Run to start the simulator.

In the storemanager example, we can add a couple of products. Click the Products link, then click New, enter the product attributes, and click Create.

Using the Web Inspector

The RhoSimulator also brings up a Webkit Inspector window, allowing you to inspect the web interface for your application.

For example, you can see the web code for the listview. Here is the listview of the products for the storemanager example. You can see the link for the iPhone URL, and you could change the border color and thickness for the iPhone product (changing from 1px to 3px and solid #CCC to #111 would give the iPhone link a thicker, darker border).

Using the Debugger

You can use the RhoStudio debugger to debug the Ruby code in your RHodes or Rhoconnect application.

Debugging a Rhodes Application

To run the RhoSimulator debugger for the iPhone platform, select your Rhodes project from the Project Explorer (in this case, we use the storemanager project created earlier). Then select Run –> Debug Configurations from the main menu. The Debug Configurations window appears.

Click Debug to start the debugger.

You will again get a RhoSimulator showing your device, and the Web Inspector window. And you get a Debug view in your workspace.

To debug your Ruby code in your Rhodes application, click the RhoStudio tab in your workspace, then open the Ruby file in your Rhodes application that you wish to debug.

Now click the Debug tab. You will see the Ruby file opened in the debugger.

Debugging a RhoConnect Application

To run the debugger for RhoConnect, select your RhoConnect project from the Project Explorer. Then select Run –> Debug Configurations from the main menu. The Debug Configurations window appears.

Click Debug to start the debugger.

You will see your RhoConnect project in the debugger; there will be a console window with redis server information messages. (You will not get a RhoSimulator or a Web Inspector, as you do with the Rhodes debugger.)

To debug your Ruby code in your RhoConnect application, you do the same as for a Rhodes application: click the RhoStudio tab in your workspace, then open the Ruby file in your RhoConnect project that you wish to debug.

Setting a Breakpoint

You can perform operations such as setting a breakpoint: double-click in the left margin at the line of code where you want the breakpoint.

For example, in the storemanager code, there is a rendering section in product_controller.rb.

# GET /Product
def index
  @products = Product.find(:all)
  render :back => '/app'
end

You can set a breakpoint on the line render :back => '/app', then you can go to the RhoSimulator and click on Product. The simulator will stop at the point of rendering.

If you set a breakpoint on a function definition string (the first line of a function definition), as in the following line of Ruby code, that breakpoint will always be disabled. You should not set breakpoints there.
def some_method(value='default', arr=[])

Inspecting the Variables

You can also inspect the variables. When you click “Products” In the debugger simulator, and you have a breakpoint as set earlier in the product_controller.rb on the rendering line, the application will pause just before the rendering of the product listing page. You can then inspect the variables in the variable window. The storemanager example shows that at this point int he app, the local database has been read, showing that a couple of products have been created (an iPhone and an iPhone4S).

Debugger Support for Extensions

The RhoStudio debugger supports extensions, but only pure Ruby extensions or the Ruby part of a native extension.

Debugging Ruby Framework Code

The debugger supports debugging Ruby framework code. With an older project, you may need to recreate the project in RhoStudio in order to enable the debugger. A good way to do this is as follows.

  1. Delete the project in the Project Explorer view without deleting the project content.
  2. Create a new project by creating from existing sources in the RhoMobile application wizard.
  3. Use your old project content as the existing source.

Importing a Rhodes Project from a non-RhoStudio Source

You can have a Rhodes project that you wish to import into RhoStudio. For example, you might have created a project using RhoHub and you have a local repository of that project on your computer). Or you might want to import the sample projects that came with the RhoStudio installer. The import process is similar to importing external projects with standard Eclipse.

Select File –> New –> Project…

From the New Project window, select Rhomobile –> Rhoconnect application or Rhomobile –> Rhodes application. THen click the Next button.

From the Rhodes (or Rhoconnect) application generator wizard window, click the “Create application from existing sources” checkbox.

Click the Browse button, then navigate to and select the folder containing your project. The Project name will change to the name of your project folder.

Click the Finish button. Your project will appear in the Project Explorer.

Creating a Device Build in RhoStudio

Once you have developed your application using the RhoSimulator and debugger, you will need to create a device build of your application. To do this with RhoStudio, you can do this by installing SDKs.

To create a device build with RhoStudio, you need to do the following:

  • Install the SDK for your application’s platform.
  • Set RhoStudio Preferences to that platform’s SDK.
  • In Run Configurations, set to that device, then do the device build and run.
You can do the device build with RhoHub if you wish to avoid installing the SDKs on your computer. To do your device build on RhoHub, upload your application into RhoHub, then use RhoHub to create the device build. Instructions for using RhoHub are in the Rhohub tutorial.

Installing the SDK

On Macintosh computers, once you have installed Xcode, RhoStudio will know the location of the iOS SDK. You do not set any locations.

On other platforms, such as Android, you need to install the SDK, and then set RhoStudio Preferences for that platform’s SDK. For example, on an Android device, you must download and install:

Set RhoStudio SDK Preferences

Once you have the SDK for your platform installed, set RhoStudio Preferences for that SDK. For example, to do Android device builds:

  1. In the Preferences window, open the Rhomobile item and select Android.
  2. Click the Browse button and navigate to the locations where you installed your Android SDK and NDK.

Set Run Configurations to the Device Build and Run

To start the device build process, create a Run Configuration: select your project in the Project Explorer, and select Run->Run Configurations… from the menu. The Run Configurations window appears. Set Run Configurations as follows:

  • Set the Platform to Android.
  • Set the Simulator type to either device to run on the device, or simulator to run on the simulator provided with the Android SDK.
  • If you set the Simulator type to simulator, set the Platform version number and set the AVD name for Android.

Press the Run button to build and run your application. The build output will appear in the Rhodes build output console. The application log will be available in the Rhodes application output console, and will be written into your application folder.

For complete instructions on setting up the SDKs in RhoStudio for each platform, refer to the Build instructions for Rhodes.

Editing the SDK Locations in rhobuild.yml

Use RhoStudio preferences to edit the rhobuild.yml file, which manages the location(s) of the platform SDKs/JDKs that are used to build your Rhodes application. The rhobuild.yml file is located in the Rhodes gem folder (or, if you copied Rhodes from git, in the Rhodes source code folder).

Using Intellisense for Autocompletion

IntelliSense is Microsoft’s implementation of autocompletion, best known for its use in the Microsoft Visual Studio integrated development environment. In addition to completing the symbol names the programmer is typing, IntelliSense serves as documentation and disambiguation for variable names, functions and methods using reflection.

The RhoStudio DLTK implementation supports aspects of Intellisense, such as Ruby keyword completion and block argument name completion. You can use Intellisense in RhoStudio to autocomplete your Ruby code by setting the cursor at a location in your code and pressing Ctrl+Space.

For example, to complete a Ruby keyword beginning with “re”, perform these steps.

  1. Enter “re”.
  2. Press Ctrl+Space. The completion list includes “rescue” and “return”.

Checking Progress and Canceling an Operation

You can check the progress of an operation in RhoStudio, and cancel it if you wish. Open the Progress view to see the progress bar on the left, and click the red square on the right to cancel the operation.

The following RhoStudio operations can have their progress checked and be canceled from the Progress view.

  • Main menu: RhoMobile –> Production build
  • Main menu: Project –> Clean…
  • RhoMobile Application in Project Explorer: Run Configurations, RhoMobile Application
  • RhoMobile Application in Project Explorer: Run Configurations, RhoMobile Application Test
  • RhoConnect Application in Project Explorer: Run Configurations, RhoConnect Application

You can also check progress and perform a cancel for the following operations on existing applications.

  • Create a new project, and then select RhoMobile->RhoMobile application from the New Project window.
  • Create a new project, and then select RhoMobile->RhoConnect application from the New Project window.
  • Select a RhoMobile application in the Project Explorer, and create a New->RhoMobile model.
  • Select a RhoMobile application in the Project Explorer, and create a New->RhoMobile extension.
  • Select a RhoConnect application in the Project Explorer, and create a New->RhoConnect source adapter.

Creating a Production Build in RhoStudio

To create a production build for your application, perform these steps.

  1. Select your application in the Project Explorer.
  2. Select RhoMobile->Production Build from the main menu.
  3. From the Select platform pop-up box, select the platform to which you wish to build and click “Ok”.

Reference : http://docs.rhomobile.com/rhostudio.tutorial#managing-your-build-configuration

Ruby Development Kit

DevKit Overview

The DevKit is a toolkit that makes it easy to build and use native C/C++ extensions such as RDiscount and RedCloth for Ruby on Windows.

Simply download, double-click, choose an installation directory, run the Ruby install helper script, possibly tweak a config.yml file for your system specifics, and you’re ready to start using native Ruby extensions.

DevKit Background

One of the challenges many Ruby on Windows users have is how to easily use native RubyGems from the community such as the rdiscount orcurb gems. In many cases this isn’t a problem because the extension author has provided a binary gem compatible with the users Ruby environment. In other cases, only the extension source code is available in the gem and the user is expected to have a “sane” environment installed and configured in order to build and use the native gem. A “sane” environment typically means a system with make, gcc, sh and similar *nix build tools installed.

This expectation of a “sane” build environment is not always true for Windows users and is the primary reason why the DevKit was created. The DevKit, based upon MSYS and MinGW components, is an easy-to-install and easy-to-use solution for quickly setting up a “sane” build environment, enabling you to use most native RubyGems developed by the Ruby community.

We use the DevKit internally for the RubyInstaller project. The DevKit is used to build MRI Ruby and the required dependencies needed to deliver the RubyInstaller for Windows. Many community members also use the DevKit as their “foundation” toolkit for building other native software.

The DevKit is currently available for download as a self-extracting archive and a Windows installer is in development.

Continue reading

How to write a Ruby and Rails 3 REST API

Background

I’ve always wondered how I’d go about publishing a real REST API on the web to do something. In this example, we’ll create an employee manager app-thing. It’s not particularly interesting but it shows what “API” means. In another bit, we’ll create an “API” meaning a library to interact with this web service.

The rails app

First, create a new rails app.
rails new rest_api

Edit config/database.yml:

  # MySQL
  #   gem install mysql2
  development:
    adapter: mysql2
    host: localhost
    database: rest_api
    username: rest_api
    password: rest_api
    pool: 5
    timeout: 5000

Install the mysql gem if you haven’t already. Optionally, create an RVM gemset for this project if you want to keep your gems clean.
gem install mysql2

 

Continue reading