[GSoC 2015] Week 2-3: Implement libsolv Search


Hola Amigos,

Okay first I am going to show how you can clone and test my MacPorts Development branch and set it up safely so that it does not interfere with the installed MacPorts version. And then we will be setting up libsolv from upstream to test our search implemented using libsolv.

Setting up MacPorts libsolv branch.

Now we have set up MacPorts and libsolv. Time to do some testing using libsolv search. As of now I have added all the possible options that MacPorts inbuilt search provides, few of them would be –description, –name, –license, etc.

Before starting to work on dependency calculation, neverpanic asked me to start from smaller modules like setting up the solv’s (libsolv’s representation of the ports), add more information to the solvable like evr, license, vendor, category, etc. We kept adding the dependency information for later as we wanted to test if the solv’s are setup correctly or not.

After setting up this information, we implemented search module which will take the options, passed as arguments on command line, from port.tcl. We used relevant solv flag’s for searching the libsolv cache. Finally we finished everything and I made sure to follow “Commit early and commit often” motto. My mentor reviewed the commits and gave his inputs on how I can optimize the code. After getting desired results, I worked on clean-up of the codebase and optimizing wherever possible.

Once this was done we started figuring out how can we setup dependency information of the solvables. We looked into the PortIndex and libsolv-bindings manual and matched the appropriate flags to be used and drafted a plan.

You can also test out MacPorts libsolv search by passing -l option (to use libsolv engine).

Some example commands are:

portgsoc -l search libsolv
portgsoc -l search --category math
portgsoc -l search --exact --case-sensitive gcc5

P.S.: This post was lying around in my drafts for quite some time. From now, I will try to publish as much as of my pending drafts and also publish recent posts about my work.

Let the Windows be open, and feel the Freedom.

FUDCon ’15: A Speaker’s Diary


Hola Amigos,

It’s been quite some time now that I have updated my blog due to my busy schedule, GSoC 2015 and campus placements!. So today I am going to share my experience at FUDCon 2015, Pune.

I had proposed a session on “Python Code profiling using line_profiler” at fudcon.in. One fine day around the time of GSoC 2015 results, I got a mail from Amit Shah, one of the organizers of FUDCon APAC 2015 saying that my proposal has been accepted and I need to confirm my attendance during the conference so that they can arrange and schedule my talk.

The deadline to apply for Travel reimbursement was April 30th, 2015 and I didn’t realize it until May end after my Exams got over. I opened a ticket and the organizers were very helpful and they agreed to fund my travel as I was a speaker at the conference and the amount was small and within their budget.

FUDCon 2015, Pune was going to be held between 26th-28th June, 2015 at Maharashtra Institute of Technology, College of Engineering (MITCOE). They had a taxi scheduled on 25th afternoon and midnight.

Journey from Mumbai to Pune:

I reached Mumbai Airport by 11 A.M. on 25th June, 2015 as I stay nearby and the driver was nowhere to be found at the airport. Then after 10-15 minutes I saw a guy walking towards the terminal with FUDCon poster in hand and I understood he was our driver. I shared the taxi with Dennis Gilmore. He is a lead Release Engineer at Fedora. His flight landed by 11 A.M. so we knew that he would come out only by 12 noon.

Our travel coordinator was Rupali, she had shared the flight details with me and the taxi company but due to some issue we had different flight details and there were no flights with the number scheduled to land that day. So she contacted Kushal, who then immediately contacted us and made sure that we reach Pune properly and safely. We waited for some time and then Dennis found the driver and then we started our journey.

That day there was lot of traffic on the way and it took around 1 hour just to get outside Mumbai. After Navi Mumbai it was all clear way. Near to Lonavala, on top of the hills there were rain and the vehicles were moving slowly. There were lot of awesome tunnels too. The Mumbai-Pune expressway is really an awesome road. We saw many cars just zooming on the road, but the driver was good enough to maintain a speed of 80 kms/hr on the expressway (not too fast, not too slow).

On the way the driver asked us should he stop at McDonalds or some mall. I wanted to have something local, so I asked Dennis if he wants to have Indian food and he replied “Yes, I want to have Indian food if he has come to India” :P. We had Misal Pav at Food Mall on the expressway.

By evening we reached Pune, and traffic again. It was good that the driver was local, so he knew the roads properly. Then we reached Cocoon hotel in Magarpatta City, Pune. We got our rooms quickly and the service was good. I was sharing my room with another speaker, Kashish Bhatia. The reception contacted him and informed him that I will be coming upstairs so kindly keep the room open. The room was really good and we had a balcony too.

Cocoon Hotel

Cocoon Hotel

First Day: 26th June, 2015
I had to wake up early in the morning again :P, as they had arranged buses at 7.30 A.M. so that we were not late to the conference and everything goes on smoothly. First day was scheduled to begin by 9 A.M.

We all came down to the hotel restaurant where we had buffet breakfast, there was Pav Bhaji, juice, corn flakes, hot drinks and many more things. Didn’t quite taste everything as we woke up late as usual ;). We had breakfast and moved towards the entrance where the buses were waiting that would take us to the venue. As we stepped outside we saw that some of the organizers were carrying huge boxes and some had FUDCon bags in their hand. It was SWAG time ;). They distributed the bags in an orderly manner. We were eager to know what was there inside the bag. I got my bag and Tada there was a F22 DVD inside, a Fedora Umbrella and a Fedora Flask. There was some FUDCon guide map too.

FUDCon Swags

FUDCon Swags

We all kept our bags in our room and boarded the bus. It was around 45 minute journey from our hotel to the venue, a long ride indeed. We reached the venue by 8.45 A.M. We all went inside and we saw our Speaker tags were kept on the table and volunteers were waiting for us. They welcomed us and distributed the Speaker badges and there were some fedora tags too. Then we moved to the auditorium for the inauguration. Kushal started the day with introducing the team behind FUDCon and the day began by Keynote Speaker, Dennis Gilmore. There were some technical lags too relating to the Projector and WiFi bandwidth (very important part of our life nowadays :) ). From a students point of view, the keynote might have been a bit too complex understanding the release cycle and other stuff that goes on behind Fedora releases.

I met a B.Com student who is taking computer courses and Red Hat certification. I was really impressed by his interest in Open Source Software and computer science in general in-spite being from a commerce background. In Engineering colleges I have seen students who shy away from coding saying they are from Biology background, but it is our passion and interest that makes us do great things.

We went to our Speaker’s Room and met other speakers and got to know about them, what they do and about their sessions, workshops, etc. There was a session by Parag Nemade on “DNF package manager” which was of great interest as it was related to my GSoC project too. I got a bit late to the session as the directions there weren’t clear. Many a times we used to get lost and had to find our way back and start again.

Speaker's Lounge

Speaker’s Lounge

Food was arranged for the speakers at the venue, and there were some tasty dishes… ‘Yum’ (Fedora users would understand, Hint: DNF) ;) I met some of my juniors at the conference. They traveled all the way from Kerala to Pune (around 30 hours of train journey) and were staying at the Pune Ashram. Made a lot of friends that day. After lunch we had a round of lightning talks at the auditorium where speakers as well as participants shared about their work, ideas, etc. I met lot of “IRC handles” from #dgplug including Kushal, the man behind Waartaa – Ratnadeep, Sayan, Chandan Kumar and others. We knew each other by our IRC nicks and when we met for the first time we were like “Oh yeah, I remember you from #dgplug”. It is really great to actually meet people whom we communicate and share knowledge with on IRC. The day ended by another Keynote by Harish Pillay about FOSS Projects and Open Source project activity .

We returned to the hotel in the evening and I took some rest and then went downstairs for getting dinner with Prima Yogi and Danishka. As we went downstairs everyone was standing there and Kushal was also there. We all planned to go to some place for dinner and then it started drizzling. Fedora umbrella’s came to our rescue :). We walked for quite some time and entered a mall, finally I saw some life in Pune.

We had dinner at TJ’s Brew. They had their own brewery. We had a German friend, Sirko along with us who could tell us all about the beer that they brought in for testing just by it’s fragrance. We asked them if we could actually see their setup and I asked Sirko to explain us the real process of brewing Beer.

Brewing lessons from Sirko

Brewing lessons from Sirko

We had a great time and got to know each other. I was a Fedora user from few years now and contributor to other open source projects but after coming to FUDCon I made sure that when I go back I will surely start contributing to Fedora Project too.

I, Prima and Danishka had a long discussion about our work, culture and open source. It was a nice discussion and we shared our views and learnt a lot of things from each other.

Second Day: 27th June, 2015

I got up early as I was going to present my talk today :). We had breakfast and left for the venue. We had some surprise waiting for us. Yes, FUDCon tees :). After reaching the venue we were so sleepy that we slept during the whole of Keynote and another session in the Auditorium, where there was AC and comfortable seats. Felt good after getting some rest. I went up to the Speaker’s lounge, collected my FUDCon tee and all the speakers then signed a FUDCon tee. I prepared some example code and test cases for my presentation, did some final editing to the presentation so that it would be as simple as possible for the participants to understand.

We had photo session after lunch and just after that my session was scheduled.

18576287924_8fcce3c82f_z

19202443951_1a10d97703_z

My session began at 2.40 P.M. in the afternoon, and inspite of being sleepy after good food, a good amount of attendees were present for my talk. I kept the talking part short and I focused more on live demo. It was a great interactive session, all the participants were excited to know about line_profiler, profiling and testing their code. They wanted to know more about line_profiler and how they can use it in different scenarios. I made sure that they understood it properly by demonstrating it, as testing is one of the important step in software development. Having written some generic code helped a lot. Participants who had a laptop were along with me following the steps as I went through each step from fetching the source, building and installing, running the profiler and I really felt good that the topic is getting great response from the participants.

Dennis was present there and as he was in Release Engineering, he noticed that we had to use pip to install line_profiler so he mentioned why don’t we have a RPM package for it so that we can use yum/dnf to install it correctly. And from there my journey as a Fedora Packager began, and it was another new experience in itself.

Python Code Profiling @ FUDCon

Python Code Profiling @ FUDCon

Python Code Profiling @ FUDCon

Python Code Profiling @ FUDCon

Demo time

Demo time

Here is my Session slides:

In the evening, we had a social gathering a.k.a. FUDPub at bluO at Phoenix Market-city, Pune. We had awesome food, paneer and chicken tikka ‘Yum’ again ;). There was a huge Bowling alley, pool and lots of Beer!. We also got another surprise, Fedora socks for Bowling. There were around ~15 bowling lanes, and every lane was occupied by 3-4 people playing randomly. We had lot of fun, one guy breaks the set and other one tries for a spare if the first one doesn’t get a strike :P.

My fingers were hurting for a few days since then. I played pool for the first time and after around 20-30 shots I managed to pot a ball. Everyone had a great time and we played a lot. The whole place was booked just for us.

Third Day: 28th June, 2015

Luckily we didn’t have to get up early in the morning. We got up at 8 A.M. and I got a call from Praveen Kumar (PK) saying that one bus is waiting for us. We got ready, I packed my things as I was going back to Mumbai and we had to checkout from the hotel. We had breakfast, checked out and left for the venue.

The final day was more related to Designing. There was Inkscape workshop by Sirko, Blender by Ryan and GIMP tee-designing workshop by Yogi.

The event was well organized and I met a lot of people from the community, learnt a lot about Fedora and just now my first package got approved in Fedora :).

Thanks to the FUDCon team for an awesome job organizing such a successful FUDCon APAC 2015.

Let the Windows be open, and feel the Freedom.

[GSoC 2015] Setting up MacPorts libsolv branch


Hola Amigos,

Here I am going to show how to setup and install my MacPorts development branch (gsoc15-dependency) and libsolv.

Step 1: Clone my development branch inside ~/Development folder probably so that we do not mess up other folders/files. You are free to do it in your preferred folder too.

If you do not have ~/Development folder you can run:

mkdir ~/Development; cd ~/Development

Now we will clone our svn repository. To do so run:

svn co https://svn.macports.org/repository/macports/branches/gsoc15-dependency
cd base

Note: I will be setting up everything inside ~/Development. If you choose to do it under other folder, do remember to replace ~/Development in the following commands with your folder path.

Step 2: Installing MacPorts Development branch.

As this is a testing branch, we do not want it to install and interfere with our installed MacPorts in ${prefix} i.e. /opt/local (default).

Run the following command to make sure it is installed in ~/Development/mp_libsolv (you can give any name by replacing “mp_libsolv”) and also we will have to –disable-readline (we do not want this development version to be used by default by adding it to our PATH).

PATH=/usr/bin:/bin:/usr/sbin:/sbin ./configure --prefix ~/Development/mp_libsolv

Step 3: Adding alias for this development port.

To run this dev version of port you will have to run using “~/Development/mp_libsolv/bin/port”. So instead we will create a alias in our bash_profile. To do so run the following command.

echo 'alias portgsoc="/Users/JacksonIsaac/Development/mp_libsolv/bin/port"' >> ~/.bash_profile

You can also give some other alias instead of portgsoc and also remember to fix the absolute path i.e. “/Users/JacksonIsaac/Development/mp_libsolv” to your installed folder. You can also get that by running “pwd” inside ~/Development/mp_libsolv folder.

We will have to create a alias for sudo too if we want sudo to recognize this “portgsoc” alias (for installing and updating ports which need root access).

echo 'alias sudo="sudo "' >> ~/.bash_profile

Step 4: Test our development port

Now we will test if our development port is working fine or not. To do so I will be updating the portindex and some port operation.

sudo portgsoc -d selfupdate
portgsoc search libsolv

To add libsolv support to our Development port, we need to build libsolv.

Step 5: Cloning libsolv from upstream.

Libsolv port is available (but the current version is 0.6.10) which does not support Tcl bindings yet. So we will clone the upstream branch for now and build from source against our portgsoc-tclsh.

Under ~/Devlopment run the following commands:

git clone https://github.com/openSUSE/libsolv.git
cd libsolv
mkdir build; cd build

Now we will run cmake inside build/ so that we do not mess up the root folder with make files and if we need to delete this folder and run cmake again if something goes wrong while building.

cmake -DTCL_INCLUDE_PATH=${prefix}/libexec/macports/include -DTCL_LIBRARY=${prefix}/libexec/macports/lib/libtcl8.5.dylib -DTCL_TCLSH=${prefix}/libexec/macports/bin/tclsh8.5 -DENABLE_TCL:BOOL=ON ..

Note: Replace ${prefix} with your installation path i.e. ~/Development/mp_libsolv if you exactly followed the steps above.

Now libsolv is ready to be installed against our portgsoc-tclsh, so run the following make commands (in build/):

make
sudo make install

Okay so now we are set to use the libsolv feature in our MacPorts libsolv branch. You can test libsolv search feature by using -l option.
Example commands are:

portgsoc -l search libsolv
portgsoc -l search --category math
portgsoc -l search --exact --case-sensitive gcc5

and so on. You can also pass -d for debug options.

Let the Windows be open, and feel the Freedom.

[GSoC 2015] Week 1: Create libsolv bindings for Tcl


Hola amigos,

1stWeek: 25stMay, 2015 – 31stMay, 2015
Now we are into the coding phase of GSoC 2015. First we finished going through the pysolv, python bindings of libsolv which helped us a lot to understand what all stuff libsolv can do for us.

We had to find a way for the libsolv to work with Tcl, as MacPorts base is largely written in Tcl. So my mentor mentioned SWIG (a software development tool that connects programs written in C and C++ with a variety of high-level programming languages.) as libsolv was written in C. Then luckily we came across solv.i in the bindings/ folder. solv.i contains the interface file for SWIG which helps SWIG to convert it into the destination language (Tcl for us).

We concluded our discussion on libsolv bindings and decided to have a extra meeting on 29stMay, 2015 for adding Tcl related interface code in solv.i. Till then I went through SWIG tutorials and also tried my hand on creating python bindings for MacPorts code (src/machista1.0/machista.i). While doing so I came across a bug, #include was missing from the interface file which was then committed by my mentor with the updated machista_wrap.c file. This wrap file is used to compile against the destination languages library to get the bindings for the destination language.

Tutorials and more information on SWIG can be found SWIG.

In our extra meeting, I wrote the remaining SWIG interface Tcl code and then committed it to neverpanic (my mentors) branch. Which he merged and combined those multiple commits into one and then PR’ed (Pull Request) to the upstream libsolv branch (OpenSuSE/libsolv). Then we compiled everything and run cmake and make on the current build.

Now we had a solv.dylib which can be loaded in the correct Tclsh. We built it against out port-tclsh (A symlink to MacPorts’ copy of Tclsh) by passing some options to cmake, so we can use solv.dylib against that tclsh only as different versions/variants of Tcl would build the SWIG differently and might give errors.

To clone libsolv repository run the following command:

git clone https://github.com/openSUSE/libsolv.git

Now, it is recommended to create a build/ directory and run cmake inside build folder rather than libsolv/ itself as lot of files will be created by cmake which we would have to delete if we run into troubles or need to change the path of Tclsh against which it is built.

You can do so by running the following command in your terminal:

mkdir build; cd build

If you wish to create libsolv bindings against port-tclsh run the following cmake command (Inside libsolv/build):

cmake -DTCL_INCLUDE_PATH=${prefix}/libexec/macports/include -DTCL_LIBRARY=${prefix}/libexec/macports/lib/libtcl8.5.dylib -DTCL_TCLSH=${prefix}/libexec/macports/bin/tclsh8.5 -DENABLE_TCL:BOOL=ON ..
make
sudo make install

Note: Replace ${prefix} with your MacPorts installation path. By Default it would be /opt/local/. You may want to use a development prefix intended for testing purposes e.g. ~/Development/macports.

Then copy the solv.dylib to the directory where you want to use libsolv bindings for Tcl.

Initially we copied solv.dylib to macports1.0/ and the created a file libsolv.tcl which loads this bindings using “load abosulte/path/to/solv.dylib” and the “package require solv” in macports_libsolv.tcl

Note: The current upstream of libsolv is fixed and improvised for “Implementing Tcl Bindings” in this commit and now we just need to use “package require solv”. The bindings is automatically found by Tclsh in the path.

Let the Windows be open, and feel the Freedom.

[GSoC 2015] Community Bonding


Hola amigos,

Google Summer of Code results were announced on 27th April, 2015 and I was one of the selected students. After the results the “Community Bonding” period starts till 25th May, 2015.


What is Community Bonding?

In Community Bonding, we get to know more about the project, mentor(s), other developers, etc. It is a one month period where you get enough time to go through and understand the codebase, set up your accounts and local repositories, discuss about the project plan and strategy, look into similar implementations and get to know the awesome people working to make the project better. You are now one of them too ;)

As soon as the results were out it was something different feeling altogether. For my organization “The MacPorts Project” there were 3 students selected, including me. My Mentor, Clemens Lang, sent out official emails (Google sends official selection mail too) to us about being selected and what we will be doing ahead in community bonding period. I went through the links and what was planned ahead and took no time (excitement level was off the charts) to thank him and the community for helping us out during the pre-application period to better understand the project ideas.


First Meeting: 29th April, 2015

We (My Mentor, Clemens and I) had our first official project meeting on FaceTime the next day itself, it was something new that we had tried having meetings on FaceTime. In this meeting, we got to know each other and we discussed a tiny bit about our project and scheduled weekly meetings. At first FaceTime was lightning fast for discussions, but from the second meeting onwards we stuck to the same old IRC :). Well IRC since, it was easy to go through the previous logs and others can also participate in the discussions.


Second Meeting: 4th May, 2015

In this meeting, we went through the MacPorts (MP) codebase. neverpanic (My Mentor, Clemens) walked me through the complete macports codebase. We discussed which file provides and does what and which were the files we would have to look into and discussed about them in detail. We did skip a few files as they weren’t required at the moment and we would go though them when required. Going through the code yourself and having someone guide you with experience makes a huge difference. I tried to go through the codebase and could actually understand small portion but with the help of a mentor this process was completed in around 2-3 hours (~70-80% of codebase).

Then we also discussed where we would add the libsolv along with MP. Ideally, it would be under vendor/ directory. But then libsolv depends on cmake (a cross platform build system) and cmake isn’t distributed along OS X, Xcode CLT (Command line tools) or MacPorts. So have kept that for future discussion, whether cmake would be a pre-requisite for MP (this would mean more dependencies for MP – curl, expat, zlib, bzip2, libarchive) or should we convert it to autoconf build system or pre-generate cmake-based build system along with MP.

We went through the MP codebase following the path of the command “port install foo”. MacPorts is written in Tcl (pronounced “tickle”) and there exists some part of C. First we looked into port/ folder which contain the files port.tcl, portindex.tcl and portmirror.tcl. port.tcl is the file that is basically executed when we do something like “port install foo” or in general “port “. For the users convenience we run port without the .tcl extension i.e. “port install foo” and not “port.tcl install foo”. Files under port/ mostly deals with the front-end presentation, command line parsing and resolving expressions.

Then we moved to the core of MP i.e macports1.0 folder. Inside this macports.tcl takes care of everything and is the most important and also the largest file in MP base. This is also the file where the dependency calculation happens, hence the main file to work on since we need to work on “dependency calculation” and we will probably call libsolv functions from here. As it is already a huge file, we might probably move the new functionalities to another file, probably dependency.tcl or similar.

To install a port there exists a Portfile which defines a set of rules and metadata describing the package and how to build it. MP create a new Tcl interpreter and runs the portfile. Inside this sub-interpreter the files inside port1.0/ are executed during the respective phases like fetch, verify checksum, extract, patch, configure, build, destroot, test, archive and install. This makes the life of a Portfile maintainer easy as they would only have to configure the URL and filename to download, other things are taken care of by the port1.0/ files.

package1.0 deals with if there exists a pre-built binary archive on our mirrors and how to fetch and use these instead of building the port on the users system.

To keep track of the installed ports, etc MP uses a SQLite DB. The code that deals with handling this DB is under cregistry/ and registry2.0/, where the latter is more object oriented and east to use.

pextlib1.0/ contains the extensions for MP’s Tcl. E.g. MP’s Tcl comes with a “curl” command which internally uses the libcurl to fetch files. Various Hashing algorithms are also found under pextlib1.0/ which is used by MP to verify the checksum of the fetched files by running the checksum on the file and compare with the checksum given in the Portfile by the Portfile maintainer.

Then we had a Q&A session and we cleared some doubts regarding cmake and build system and some parts of Portfile.

We were waiting for other students to respond before we move forward with creating macports.org account for using svn. I started trying out svn on assembla.com. We also discussed about svn (C-VCS) and git (D-VCS) and concluded our second meeting.


Third Meeting: 11th May, 2015

Software Engineering exam tomorrow, but anyways the paper will be as usual difficult so moving to some Open Source :)

I went through the libsolv code and as neverpanic had also sent some links over mail to look into. I couldn’t cover the whole thing but still I got a brief idea of what the libsolv does.

In this meeting, we tried to compile and build libsolv on Mac OS X. As expected there were errors, in linker to be precise. neverpanic created a port with patches to be made to the CMakeLists.txt which is somewhat similar to ‘Makefile’. We also pushed the patch upstream and then moved to vimrc. As I was having some problems using vim so we set up a clean vimrc and then concluded the meeting.


Fourth Meeting: 18th May, 2015

The other students had replied regarding their handle for macports.org ID and neverpanic had mailed the MacOSForge admins requesting for the account creation. We actually rescheduled this meeting the next day i.e. 19th May, 2015.

Now, I had gone through the libsolv and understood the different data structures used and what the functions do and how they work. Thanks to neverpanic’s libsolv Port, man pages libsolv-bindings, libsolv-pool came handy and were very helpful. We also went through the pysolv (Python bindings for libsolv) example as it was easier to understand what the modules do and how.

At the end of meeting, we had covered almost 650 line of code, many lines were skipped too as they were not necessary at the moment.

Community Bonding period ends on 25th May, 2015 and Coding period starts but we had another meeting planned on 25th May, 2015, where we finished off with the pysolv example and moved to further planning of the project. This will be covered in the coming posts. :)

P.S: I was lazy to re-check the above. So please feel free to point out the mistakes and I’ll look into it and make sure to correct them.

Let the Windows be open, and feel the Freedom.

GSoC 2015: The MacPorts Project


Hola amigos,

I am happy to announce that I have been selected for GSoC 2015 as a student developer with ‘The MacPorts Project’. My project is titled “MacPorts: Improve Dependency Calculation using SAT solver.“.

GSoC 2015 - The MacPorts Project

GSoC 2015 – The MacPorts Project

The proposal can be found here.

I will be posting all the weekly updates over here, and also document everything. So watch out this space for more about the project.

Let the Windows be open, and feel the Freedom.

PAC-MAN on Google Maps


Hola Amigos,

I am going to show you how you can too play PAC-MAN on your browser through Google-Maps. I have also known PAC-MAN by another name, Gob-Man.*Feels Nostalgic*

Are you Ready?

Are you Ready?

So, here it goes:
Step 1: Open up Google Maps.
Step 2: Navigate to some place with lot of roads, crossroads and streets. I played it near my University :P :)

Easter egg on Bottom-left corner

Easter egg on Bottom-left corner

Note: Don’t worry if you can’t find a street. Maps will do it for you, you just need to click ‘I’m Feeling Lucky’

I'm Feeling Lucky

I’m Feeling Lucky

PAC-MAN Ready to Play

PAC-MAN Ready to Play

PAC-MAN, Gob and Run!!!

PAC-MAN, Gob and Run!!!

Step 3: Now click on the PAC-MAN icon on bottom-left corner.

Enjoy PAC-MAN on your browser :)

Let the Windows be open, and feel the Freedom.