OrderedCollection [
	GrafoscopioNode {
		#header : '%metadata Data Activism Techniques',
		#body : '| metadata |
metadata := 
{ 
\'title\' -> \'Live coding & agile visualization for Data Activism\'.
\'author\' -> \'Offray Vladimir Luna Cárdenas\'.
\'date\' -> Date today.
\'shortTitle\' -> \'Data Activism Techniques\'.
\'showOnHelp\' -> true.
\'docType\' -> \'tutorial\'
} asOrderedDictionary
',
		#tags : OrderedCollection [
			'código'
		],
		#children : OrderedCollection [ ],
		#parent : GrafoscopioNode {
			#header : 'Arbol principal',
			#body : '',
			#tags : OrderedCollection [
				'text'
			],
			#children : @1,
			#level : 0,
			#nodesInPreorder : OrderedCollection [
				@5,
				@2,
				GrafoscopioNode {
					#header : 'Introduction',
					#body : 'This booklet presents a set of techniques to work with data, that are useful of Data Activism.
We consider data mostly as a non-neutral human construct and we think that a more critical
code+data literacy is needed to deal  and build a common world that is, increasingly, mediated
by data and code.
Who is visible in this coming world, which voices are heard, and if we can create a plural participation
in such world will depend on such critical literacy.

The work you\'re reading is opinionated, consequently.
It presents a set of tools, devices and techniques, that has been developed in our local community, at 
HackBo, but try to become part of a wider conversation and nurtures from global communities.
This is also a work in progress, and because we take a "local first" approach, you will see that
this document is in "Spanglish", with the idea of having a full English translation in the future,
but starting from localized content originally Spanish or translated/wrote for/from Spanish speaking
communities.
If you\'re a native English speaker, any help is welcomed. 
See the Community Guidelines in the Grafoscopio Manual, to see how to offer and ask for help.

This document is made with Grafoscopio. Good familiarity with it is adviced. You can see more about
Grafoscopio at: <http://mutabit.com/grafoscopio/>

Several examples from booklet are based on Agile Visualization, and is covered by the same license.
',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [ ],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				GrafoscopioNode {
					#header : 'Documenting',
					#body : 'If you are seeing this document inside Grafoscopio, is probably that you are reading
some strange marks on it, and words surrounded by the, like `*this one*`.
Such marks correspond to what is called a [light markup language][light-markup],
which is a way to express format and structure of a document by marking it contents
with some special characters, called markup.

From the several markup languages available, Grafoscopio uses [Pandoc\'s Markdown][pandoc-md],
because of its flexibility and completeness.
This section 

[light-markup]: https://en.wikipedia.org/wiki/Lightweight_markup_language
[pandoc-md]: ',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Learning Markdown',
							#body : 'Repeat the excercises at http://docutopia.tupale.co/markdown',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [ ],
							#parent : @12,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				@15,
				GrafoscopioNode {
					#header : 'Drawing with data',
					#body : '',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'A first data draw',
							#body : 'Drawing with data is esentialy about taking data, applying a visual form to it
and presenting it with a particular layout given account of possible patterns.
Lets start with this simple example',
							#tags : OrderedCollection [
								''
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Drawing the first 20 numbers',
									#body : '"Lets define our data model"
data := 1 to: 20.
"Now define the form that we\'ll apply to that data"
shape := (RTBox new size: 30) + RTLabel.
"Now create a set of visual elements using that basic fomr on our data"
elements := shape elementsOn: data.
"Lets define the view, where the data will be displayed"
view := RTView new.
"And lets add all visual elements to our view"
view addAll: elements.
"Now define the layout to our visual elements"
RTGridLayout on: elements.
"Now lets display our view"
view ',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : @23,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								}
							],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Other data visualization examples',
							#body : 'The following examples are taken from the Agile Visualizatio book.
They follow the same logic of the first data draw example, and are a short glimpse of what you
can do with this platform.
We\'re going to learn how to use it in detail here, so don\'t worry if details escape to you in this quick overview.
',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'A tree of numbers',
									#body : 'b := RTMondrian new.
b shape label.
b nodes: (1 to: 100).
b edges connectFrom: [ :i | i // 2 ].
b layout cluster.
b',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : @31,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Visualizing the user desktop',
									#body : 'path := FileLocator desktop asFileReference.
allFilesUnderPath := path allChildren.
b := RTMondrian new.
b shape circle
\tcolor: Color gray trans;
\tif: [ :aFile | aFile path basename endsWith: \'.pdf\' ] color: Color red trans.
b nodes: allFilesUnderPath.
b edges connectFrom: #parent.
b normalizer
\tnormalizeSize: #size min: 10 max: 150 using: #sqrt.
b layout tree.
b

',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : @31,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Geographical CSV data',
									#body : '\ttab := RTTabTable new input:  \'http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_month.csv\' asUrl retrieveContents  usingDelimiter: $,.
\ttab removeFirstRow.
\ttab replaceEmptyValuesWith: \'0\' inColumns: #(2 3 4 5).
\ttab convertColumnsAsFloat: #(2 3 4 5).

\tb := RTMapLocationBuilder new.
\tb shape circle
\t\tsize: [ :m | 2 raisedTo: (m - 1) ];
\t\tcolor: (Color red alpha: 0.3).
\ttab values do: [ :row | b addPoint: row second @ row third value: row fifth ].
\tb
\t',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : @31,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Seism activity over time',
									#body : '\ttab := RTTabTable new 
\t\t\tinput: \'http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_month.csv\' asUrl retrieveContents 
\t\t\tusingDelimiter: $,.
\ttab removeFirstRow.
\ttab convertColumn: 1 to: [ :s | (DateAndTime fromString: s) julianDayNumber ].
\ttab convertColumnsAsFloat: #(5).

\tv := RTView new.
\tes := RTEllipse elementsOn: tab values.
\tv addAll: es. 
\tes @ RTPopup.

\tRTMetricNormalizer new
\t\telements: es;
\t\tnormalizeColor: #fifth using: { Color orange . Color red };
\t\talphaColor: 0.3;
\t\tnormalizeX: #first min: 0 max: 600;
\t\tnormalizeSize: #fifth min: 0 max: 80 using: [ :mag | 2 raisedTo: (mag - 1) ].
\t\t
\tes @ (RTLabeled new text: [ :row | row fifth > 6 ifTrue: [ row fifth ] ifFalse: [ \'\' ] ]).
\tv @ RTDraggableView.
\tv
\t',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : @31,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Charting',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Ploting: Ebola fatalities',
											#body : '"Preparing the data"
\ttab := RTTabTable new input: \'http://agilevisualization.com/Ebola2.csv\' asUrl retrieveContents usingDelimiter: $,.
\ttab removeFirstRow.
\ttab replaceEmptyValuesWith: \'0\' inColumns: #(10 11).
\ttab convertColumnsAsInteger: #(10 11).
\ttab convertColumnsAsDateAndTime: #(3 4).
\tdata := tab values reversed.

\t"Charting the data"
\tb := RTGrapher new.

\tds := RTData new.
\tds interaction fixedPopupText: [ :row | row value at: 12 ]. 
\tds dotShape ellipse 
\t\tcolor: (Color blue alpha: 0.3);
\t\tsize: [ :row  | (row at: 11) / 5 ].
\tds points: data.
\tds connectColor: Color blue.
\tds y: [ :r | r at: 10 ].
\tds highlightIf: [ :row | (row at: 10) > 100 ] using: [ :row | row third year ].
\tb add: ds. 

\tb axisX noLabel; numberOfTicks: tab values size.
\tb axisY noDecimal.
\tb
',
											#tags : OrderedCollection [
												'código'
											],
											#children : OrderedCollection [ ],
											#parent : @50,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Double charting: distribution of US population over 18',
											#body : 'tab := RTTabTable new input: \'http://agilevisualization.com/AgileVisualization/census.csv\' asUrl retrieveContents usingDelimiter: $,.
\ttab removeFirstRow.
\ttab convertColumnsAsInteger: #(\'POPESTIMATE2013\' \'POPEST18PLUS2013\').

\tb := RTDoubleBarBuilder new.
\tb pointName: [ :row | row at: (tab indexOfName: \'NAME\') ].
\t"Remove the first line, the sum"
\tb points: tab values allButFirst. 
\tb bottomValue: [ :row | ((row at: (tab indexOfName: \'POPESTIMATE2013\')) / 1000) asInteger ] 
\t\ttitled: \'Pop estimate (x 1000)\'.
\tb topValue: [ :row | ((row at: (tab indexOfName: \'POPEST18PLUS2013\')) / 1000) asInteger] 
\t\ttitled: \'Pop +18 estimate (x 1000)\'.
\tb
\t',
											#tags : OrderedCollection [
												'código'
											],
											#children : OrderedCollection [ ],
											#parent : @50,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Multiple graphs',
											#body : 'b := RTGrapher new.
\tnumberOfDataSets := 5.

\tcolorNormalizer := RTMultiLinearColorForIdentity new 
\t\t\t\t\t\tobjects: (1 to: numberOfDataSets).
\t1 to: numberOfDataSets do: [ :i |
\t\tds := RTData new.
\t\tds noDot.
\t\tds points: ((1 to: 500) collect: [ :ii | 50 atRandom - 25 ]) cumsum.
\t\tds connectColor: (colorNormalizer rtValue: i).
\t\tb add: ds.
\t].
\tb
\t',
											#tags : OrderedCollection [
												'código'
											],
											#children : OrderedCollection [ ],
											#parent : @50,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										}
									],
									#parent : @31,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Timeline',
									#body : 'data := #(
\t\t#(WP1 0 4)  #(WP2 4 8)
\t\t#(WP3 8 12) #(WP4 3 4) 
\t\t#(WP4 7 9) #(WP4 10 12)   
\t  ).
\tb := RTTimeline new.
\ts := RTTimelineSet new.
\ts objects: data.
\ts lineIdentifier: #first.
\ts start: #second.
\ts end: #third.
\tb add: s.
\tb axisX
\t\tnoDecimal;
\t\ttitle: \'Month\';
\t\tnumberOfLabels: 12.
\tb
\t',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : @31,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Integration with OpenStreetMap',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Example 1',
											#body : 'v := RTView new.
\tv @ RTDraggableView.
\tmap := RTOSM new.
\tv add: map element.

\t"City geographical positions obtained from Wikipedia"
\tparis := 48.8567 @ 2.3508.
\tnewyork := 40.7127 @ -74.0059.
\tlondon := 51.507222@ -0.1275.
\t
\t"Some arbitrary data"
\tdata := 
\t\t{ { paris . #(10 5 10 3 10 6 8) } .
\t\t\t{ london . #(5 3 3 -5 ) } .
\t\t\t{ newyork . #(5 -2 10 15 -10) } }.
\t
\tdata do: [ :tupple |
\t\t\t| grapher dataSet |
\t\t\tgrapher := RTGrapher new.
\t\t\tgrapher extent: 150 @ 100.
\t\t\tdataSet := RTData new.
\t\t\tdataSet points: tupple second.
\t\t\tdataSet barShape width: 10; color: Color red.
\t\t\tgrapher add: dataSet.
\t\t\tgrapher build.

\t\t\tbarElements := grapher view elements.
\t\t\tv addAll: barElements.
\t\t\tbarElements translateTo: (map latLonToRoassal: tupple first) ].
\t
\tv canvas camera translateTo: (map latLonToRoassal: paris).
\tv canvas camera noInitializationWhenOpen.
\tv canvas camera scale: 0.3.
\tv
\t',
											#tags : OrderedCollection [
												'código'
											],
											#children : OrderedCollection [ ],
											#parent : @70,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Example 2',
											#body : 'v := RTView new.
\tv @ RTDraggableView.
\tmap := RTOSM new.
\tv add: map element.

\t"Place to set the data and center the camera"
\tlondon := 51.507222@ -0.1275.
    
\t"Some arbitrary data"
\tdata := ((1 to: 500) collect: [ :i | 50 atRandom - 25 ]) cumsum.

\t"We build the graph"
\tb := RTGrapher new.
\tb extent: 100@30.
\td := RTData new.
\td noDot.
\td connectColor: Color red.
\td points: data.

\tb add: d.
\tb axisY 
\t\tlabelFontHeight: 6;
\t\tcolor: Color red; 
\t    title: \'Sale\'.

\tb axisX color: Color red; noTick; title: \'country\'.
\tb build.
\telementsAndEdges := b view elements, b view edges.

\t"We create a white background"
\twhiteBackground := (RTRoundedBox new color: Color white trans; borderRadius: 10) element.
\tv add: whiteBackground.
\tv addAll: elementsAndEdges.
\tRTNest new on: whiteBackground nest: elementsAndEdges.
\twhiteBackground translateTo: (map latLonToRoassal: london).

\tv canvas camera translateTo: (map latLonToRoassal: london).
\tv canvas camera noInitializationWhenOpen.
\tv canvas camera scale: 1.5.
\tv
\t',
											#tags : OrderedCollection [
												'código'
											],
											#children : OrderedCollection [ ],
											#parent : @70,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										}
									],
									#parent : @31,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								}
							],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				@23,
				@26,
				@31,
				@34,
				@38,
				@42,
				@46,
				@50,
				@53,
				@57,
				@61,
				@66,
				@70,
				@73,
				@77,
				GrafoscopioNode {
					#header : 'Basic interation',
					#body : 'Before going deeper into data we need some basic operation with the environment,
about three basic operations:

  - Doing: ie executing instructions also called messages.
  - Printing: Seeing the result of executing messages.
  - Inpecting: Going deeper into the objects thare hold and represent data.

',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Doing',
							#headers : OrderedCollection [ ],
							#key : '',
							#body : '"Así que vamos a la primera lección: aprender a ejecutar código. 
Para ello hay varias opciones:
  - Opción 1: Selecciona el texto debajo, o coloca el cursor luego del punto, dale clic 
    derecho y selecciona \'do it (d)\'
  - Opción 2: Haz click en el botón con el ícono de play que aparece justo cerca a la 
    esquina superior derecha de este panel

También puedes ejecutar \'Do it\' usando el comando de teclado \'ALT d\' (esto cambia de acuerdo a 
tu sistema operativo/computador: puede ser \'CMD d\' o \'CTRL d\')
"

ProfStef  openPharoZenWorkspace 


',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [ ],
							#parent : @84,
							#level : 3,
							#nodesInPreorder : OrderedCollection [
								@87
							],
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Printing',
							#headers : OrderedCollection [ ],
							#key : '',
							#body : '"Now you\'re a Do It master ! Let\'s talk about printing. 
It\'s a Do It which prints the result next to the expression you\'ve selected.
For example, select the text below, open the menu and click on \'print it (p)\':"

1 + 2.

"You\'ve seen the letter \'p\' between parentheses next to \'print it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

Try ALT-p (or CMD-p or CTRL-p) on the following expressions:"

Date today.

Time now.

"The result is selected, so you can erase it using the backspace key. Try it !"

SmalltalkImage current datedVersion.

"Ahora ve a la siguiente lección"',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [ ],
							#parent : @84,
							#level : 3,
							#nodesInPreorder : OrderedCollection [
								@93
							],
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Inspecting',
							#key : '',
							#body : '"Now you\'re a Do It and Print It master ! Let\'s talk about inspecting. 
It\'s a Do It which opens an Inspector on the result of evaluating the expression you\'ve selected. 
The Inspector is a tool that allows you to have a look inside an object.

For example, select the text below, open the menu and click on \'inspect it (i)\':"

1 / 2.

"You\'ve seen the letter \'i\' between parentheses next to \'inspect it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

You can use Ctrl+g to get and embedded inspector.

Try ALT-i (or CMD-i or CTRL-i) on the following expressions:"

DateAndTime today.

Float pi.

SystemVersion current.

"Ahora ve a la siguiente lección"',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [ ],
							#parent : @84,
							#level : 3,
							#nodesInPreorder : OrderedCollection [
								@99
							],
							#links : OrderedCollection [
								''
							]
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				@87,
				@93,
				@99,
				GrafoscopioNode {
					#header : 'Desconstructing a practical example',
					#body : 'We\'re going to start with our first practical example.
The idea is to get data from an online source, clean it a little bit, and make a simple graph.
From there, we\'re going to deconstruct the example and the properties of mensages,
and some objects, wich simple but powerful conceptual model behind Pharo.',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Peace voting in Colombia',
							#body : '',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Deconstructing the example: Toval voting for Peace in Colombia 2016',
									#body : '| tab rawData labeledData b lb |
"Geting the data"
rawData := \'http://viz.datasketch.co/beta/custom/datasketch/data/plebiscito/votacion_plebiscito_2016_consolidado.csv\' asUrl retrieveContents.
tab := RTTabTable new input: rawData  usingDelimiter: $,.
labeledData := { \'No\' -> ((tab values at: 2) at: 11) asNumber .\'Si\' -> ((tab values at: 2) at: 9) asNumber }.
"Here we build the pie"
b := RTPieBuilder new.
b interaction popup.
b objects: labeledData.
b slice: #value.
b labeled.
b normalizer distinctColor.
b.
"And add the legend"
lb := RTLegendBuilder new.
lb view: b view.
lb addText: \'Resultados del plebiscito por la Paz Colombia 2016\'.
lb build.
^ b',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : @108,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Totals by deparments (states)',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Two deparments & dummy data',
											#body : '| address rawData tab b yes1 no1 yes2 no2 location1 location2 |
address := \'http://viz.datasketch.co/beta/custom/datasketch/data/plebiscito/votacion_plebiscito_2016_deptos.csv\'.
rawData := address asUrl retrieveContents.
tab := RTTable new input: rawData usingDelimiter: $,.
yes1 := ((tab values at: 2) at: 9) asNumber.
no1 := ((tab values at: 2) at: 11) asNumber.
location1 := (tab values at:2) at: 1. 
yes2 := ((tab values at: 3) at: 9) asNumber.
no2 := ((tab values at: 3) at: 11) asNumber.
location2 := (tab values at:3) at: 1. 
b := RTStackBarPlot new.
b vertical.
b interaction popupText.
b colorPalette colors: (Array with: Color yellow with: Color red).
b add: { yes1 . no1 } title: location1.
b add: { yes2 . no2 } title: location2.
b add: #(25 29) title: \'Dummy Data 1\'.
b add: #(30 33) title: \'Dummy Data 2\'.
b addLegend: #(\'sí\' \'no\').
b barWidth: 40 height: 260.
b addLabelToBars: [ :assoc | (assoc key / b totalSum * 100) asInteger asString , \'%\' ] if: [ :assoc | assoc key > 5 ] color: Color black.
b build.
^ b view',
											#tags : OrderedCollection [
												'código'
											],
											#children : OrderedCollection [ ],
											#parent : @115,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										}
									],
									#parent : @108,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Exercises',
									#body : 'The following nodes will present you with a set of excercises. 
Each  exercise is put as a node. 
Create a playground node as child of the exercise node and use the playground to write the
code needed to solve it.',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Add two deparments',
											#body : 'Modify the \'Two deparments & dummy data\' previous example to add two more deparments to the graphic.',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Solution',
													#body : '',
													#tags : OrderedCollection [
														'código'
													],
													#children : OrderedCollection [ ],
													#parent : @126,
													#level : 5,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : @123,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Intermezzo: Sharing notebooks',
											#body : 'If the previous exercise was solved properly, you have now something interesting to share
with the world (well, also incomplete or wrong solutions are worthy to share also in a learning
context).
Go to the "Saving and sharing your code snippets and notebook via web > Fossil" node and develop
the proposed activity there to share the notebook with the world.
Don\'t worry, you will be able to come here and continue with this exercises.',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Solution',
													#body : '',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @134,
													#level : 5,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : @123,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Using blocks to modularize code',
											#body : 'Can you use blocks and basic types to make the code in our pie char example more modular?
The idea is to split the functionality of such example into chunks, and put them inside blocks,
that receive arguments. Which should be such blocks? Which are the block arguments?
Rewrite the example here using the idea of blocks and arguments.
',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Solution',
													#body : '',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @142,
													#level : 5,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : @123,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Get the name of all departments',
											#body : 'Go to the "two departments & Dummy data" and use blocks and iterators to get the name
of all departments.',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [ ],
											#parent : @123,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Add voting results for all deparments',
											#body : 'Use iterators (see the \'Representing data: Basic Types\' & \'Processing data > Cycles & Iteractors\')
to modify the Two deparments & dummy data example, including now all the data.',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Solution',
													#body : '',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @154,
													#level : 5,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : @123,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										}
									],
									#parent : @108,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Composing two visualizations',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [ ],
									#parent : @108,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Raw data link',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [ ],
									#parent : @108,
									#level : 3,
									#links : OrderedCollection [
										'',
										'https://www.datasketch.co/es/p/los-datos-ocultos-de-la-registraduria'
									]
								}
							],
							#parent : @105,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				@108,
				@111,
				@115,
				@118,
				@123,
				@126,
				@129,
				@134,
				@137,
				@142,
				@145,
				@150,
				@154,
				@157,
				@163,
				@167,
				GrafoscopioNode {
					#header : 'Representing data: Basic Types',
					#key : '',
					#body : 'Basic types are ways or represeting information inside this system. See nodes inside for more details',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Numbers',
							#key : '',
							#body : '"You now know how to execute Pharo code. 

Now let\'s talk about basic objects.

1, 2, 100, 2/3 ... are Numbers, and respond to many messages evaluating mathematical expressions.
Evaluate these ones:"

2.

20 factorial.

1000 factorial / 999 factorial.

(1/3).

(1/3) + (4/5).

(1/3) asFloat.


"Ahora ve a la siguiente lección"',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [ ],
							#parent : GrafoscopioNode {
								#header : 'Tipos básicos',
								#key : '',
								#body : Text {
									#string : '',
									#runs : RunArray {
										#runs : [ ],
										#values : [ ]
									}
								},
								#tags : OrderedCollection [
									'text'
								],
								#children : @175,
								#parent : GrafoscopioNode {
									#header : 'Introductorio: Professor Stef',
									#headers : OrderedCollection [
										'Tutorial 1',
										'Tutorial 2',
										'Tutorial 3',
										'Tutorial 4',
										'Tutorial 5.',
										'Tutorial 6',
										'Tutorial 7',
										'Tutorial 8',
										'Tutorial 9',
										'Tutorial 10',
										'Tutorial 11'
									],
									#key : '',
									#body : Text {
										#string : 'Este tutorial mostrará los aspectos básicos de la sintaxis de Smalltalk y está basado
en el tutorial ProfStef que viene integrado a Pharo, pero convertido en un cuaderno
interactivo de Grafoscopio.
Está separado por lecciones. que vienen numeradas y en ocasiones están agrupadas.
Para ver el contenido particular de una lección se debe hacer click en ella en el árbol
lateral a la izquierda.
Si están agrupadas, se verá un triangulito en el título que las agrupa.
Al hacer click en él, se mostrarán los contenidos del mismo, que podremos seguir
explorando con la misma lógica.
',
										#runs : RunArray {
											#runs : [
												586
											],
											#values : [
												[ ]
											],
											#lastIndex : 1,
											#lastRun : 1,
											#lastOffset : 0
										}
									},
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Lección 1: Bienvenida',
											#headers : OrderedCollection [ ],
											#key : '',
											#body : '"Hola!, Soy el profesor Stef. Debes querer que te ayude a aprender 
Pharo. Así que vamos a la primera lección: aprender a ejecutar código. 
Para ello hay varias opciones:
  - Opción 1: Selecciona el texto debajo, o coloca el cursor luego del punto, dale clic 
    derecho y selecciona \'do it (d)\'
  - Opción 2: Haz click en el botón con el ícono de play que aparece justo cerca a la 
    esquina superior derecha de este panel"

ProfStef  openPharoZenWorkspace 

',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @185,
											#level : 2,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Lección 2: Haciendo',
											#headers : @88,
											#key : '',
											#body : '"Excelente! (quise decir Súper)). Acabas de ejecutar una expresión de Pharo. Más precisamente,
enviaste el mensaje \'next\' a PharoTutorial class (¡soy yo!).

Nota que puedes correr este tutorial nuevamente evaluado \'PharoTutorial go\'.
\'PharoTutorial previous\' te devolverá a la lección anterior.

También puedes ejecutar \'Do it\' usando el comando de teclado \'ALT d\' (esto cambia de acuerdo a 
tu sistema operativo/computador: puede ser \'CMD d\' o \'CTRL d\').

Trata de evaluar las siguientes expresiones:"

Nautilus open.

SmalltalkImage current aboutThisSystem.

"Ahora ve a la siguiente lección"',
											#tags : 'código',
											#children : @90,
											#parent : @185,
											#level : 2,
											#links : @92
										},
										GrafoscopioNode {
											#header : 'Lección 3: Imprimiendo',
											#headers : @94,
											#key : '',
											#body : '"Now you\'re a Do It master ! Let\'s talk about printing. 
It\'s a Do It which prints the result next to the expression you\'ve selected.
For example, select the text below, open the menu and click on \'print it (p)\':"

1 + 2.

"You\'ve seen the letter \'p\' between parentheses next to \'print it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

Try ALT-p (or CMD-p or CTRL-p) on the following expressions:"

Date today.

Time now.

"The result is selected, so you can erase it using the backspace key. Try it !"

SmalltalkImage current datedVersion.

"Ahora ve a la siguiente lección"',
											#tags : 'código',
											#children : @96,
											#parent : @185,
											#level : 2,
											#links : @98
										},
										GrafoscopioNode {
											#header : 'Lección 4: Inspeccionando',
											#key : '',
											#body : '"Now you\'re a Do It and Print It master ! Let\'s talk about inspecting. 
It\'s a Do It which opens an Inspector on the result of evaluating the expression you\'ve selected. 
The Inspector is a tool that allows you to have a look inside an object.

For example, select the text below, open the menu and click on \'inspect it (i)\':"

1 / 2.

"You\'ve seen the letter \'i\' between parentheses next to \'inspect it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

You can use Ctrl+g to get and embedded inspector.

Try ALT-i (or CMD-i or CTRL-i) on the following expressions:"

DateAndTime today.

Float pi.

SystemVersion current.

"Ahora ve a la siguiente lección"',
											#tags : 'código',
											#children : @101,
											#parent : @185,
											#level : 2,
											#links : @103
										},
										@179,
										GrafoscopioNode {
											#header : 'Mensajes',
											#key : '',
											#body : '',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Lección 11:  Unarios',
													#headers : OrderedCollection [ ],
													#key : '',
													#body : '"Los mensajes son enviados a objetos. 
Hay tres tipos de mensajes: unary (unarios), binary (binary) y keyword.

Los mensajes unarios tienen la forma siguiente.

anObject aMessage

Tu ya has enviado mensajes unarios. Por ejemplo:"

1 class.
#b class.

$b class.

true not.

false not.

Time now.

Date today.

Date yesterday.

Date tomorrow.

Float pi.

"Ahora ve a la siguiente lección"
',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @201,
													#level : 3,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Lección 12: Binarios',
													#headers : OrderedCollection [ ],
													#key : '',
													#body : '"Los mensajes binarios tienen la forma siguiente:
anObjecto aMessage anotherObject"

3 + 2.

25 * 25.

1 + 1 = 2.

Date today + 3 weeks.

Date today + 3 years.

Date today - 3 years.

false | false.


true | false.


true | true.

false | true.


true & true.

true & false.

10 @ 100.

10 <= 12.


10 >= 12.

\'ab\', \'cd\'.

Date today < Date yesterday.
Date today > Date yesterday.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @201,
													#level : 3,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Lección 13: keywords',
													#key : '',
													#body : '"Los mensajes \'keyword\' son mensajes con argumentos. Tienen la siguiente forma:
    anObject akey: anotherObject akey2: anotherObject2"


4 between: 0 and: 5.

"El mensaje lo que nos dice es: si (4) esta entre (0 y 10) cuya respuesta es verdadero, pero si cambio el valor del 0 por 3, el resultado es falso"

1 max: 3.

"determina el valor máximo"

Color r:1 g:0 b:0.

"El mensaje es r:g:b: implementado en la clase Color. Note que también puede escribir"

Color
\tr: 15
\tg: 99
\tb: 100.

\t
"Si quieres usar código RGB usando valores de 0 a 255, como es la práctica usual, deberás
escribirlos como cociente, de forma que sean un número entre 0 y 1. 
Por ejemplo r: x/255 g: y/255 b: z/255, donde x,y,z son los valores entre 0 y 255 correspondientes al código que color que queremos obtener."
\t
"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @201,
													#level : 3,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Lección 14: Prioridad',
													#key : '',
													#body : '"los mensajes unarios son ejectuados primero, los mensajes binarios son ejecutados despues 
y finalmente las cadenas de mensajes:  paréntesis > Unary > Binary > Keywords"

2 + 3 raisedTo: 2.

2 + 3 + 4.


2 raisedTo: (3 + 2). 
  
(0@0) class.

0@0 corner: 100@200.

(0@0 corner: 100@200) class.

"entre mensajes de procedencia similar, las expresiones son ejectuadas de izquierda a derecha"

-3 abs negated reciprocal.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @201,
													#level : 3,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Lección 15: Cambiar prioridad de los mensajes',
													#key : '',
													#body : '"usar parentesis cambia el orden de evaluación de la sentencia, primero se ejecuta la parte interna() 
y posteriormente la sentencia"

(2 + 3) squared.

(2 raisedTo: 3) + 2.

(0@0 extent: 100@200) bottomRight.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @201,
													#level : 3,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Lección 16: Prioridad de los mensajes matemáticos',
													#key : '',
													#body : '"Las reglas tradicionales de las matematicas NO aplican dentro de Pharo."

2 * 10 + 2.

"aqui el mensaje por (*) es enviado a dos, corresponde a 20, entonces 20 reciben el mensaje +,

recuerde que todos los mensajes simpre siguen una regla precente de izquierda a derecha, sin excepciones."

2 + 2 * 10. 

2 + (2 * 10). 

(2 * 10) + 2. 

8 - 5 / 2. 

(8 - 5) / 2. 

8-(5/2).

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @201,
													#level : 3,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Lección 17: Mensajes en cascada',
													#key : '',
													#body : '"; es un operador en cascada. Es usado para enviar mensajes al mismo receptor
Abrir un Transcript (consola):"

Transcript open.

"Entonces:"

Transcript show: \'hola\'.
Transcript cr.
Transcript show: \'Pharo\'.


"Es igual a:"

Transcript 
\t   show: \'hello\';
\t   cr;
\t   show: \'Pharo\'.

"Intenta ir a la siguiente leccion con un cascada de dos mensjaes \'siguiente\'"

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @201,
													#level : 3,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 18: Perdido?',
													#key : '',
													#body : '"Esta era una lección que venía en el viejo tutorial. Fue mantenida para
preservar la numeración. No es necesario hacer nada"

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @201,
													#level : 3,
													#links : OrderedCollection [ ]
												}
											],
											#parent : @185,
											#level : 2,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Lección 19: Bloques',
											#key : '',
											#body : '"Los mensajes en cascada son chéveres. Ahora hablemos de los bloques.
Los bloques son métodos anónimos que pueden ser almacenados en variables y ejecutados por demanda.

Los bloques están delimitados por paréntesis cuadrados: []"

[Nautilus open].

"No abre un Nautilus porque el bloque no es ejecutado.

Acá hay otro bloque que suma 2 a su argumento (su argumento se llama x):"

[:x | x+2].

"Podemos ejecutar un bloque enviandole mensajes \'value\' "
[:x | x+2] value: 5.

[Nautilus open] value.

[:x | x+2] value: 10.

[:x :y | x - y] value:3 value:5.

"Ahora ve a la siguiente lección"',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @185,
											#level : 2,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Lección 20: Asignación de Bloques',
											#key : '',
											#body : '"Los bloques pueden ser asignados a variables y ejecutados después.

Note que |b| es la declaración de una variable llamada \'b\' y que \':=\' asigna un valor a una variable.

Selecciona las siguientes tres líneas e imprimelas (Print it)" 

| b |

[:x | x+2] value: 20.


b := [:x | x+2].


b value: 20. 


"Ahora ve a la siguiente lección"',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @185,
											#level : 2,
											#links : OrderedCollection [ ]
										},
										GrafoscopioNode {
											#header : 'Lección 21: Condicionales',
											#key : '',
											#body : '"Los condicionales son sólo menajes enviados a objetos Boolean (booleanos)"

1 < 2
  ifTrue: [Transcript show: \'Es cierto\']
  ifFalse: [Transcript show: \'Es falso\'].

"Aquí el mensajes es ifTrue:ifFalse

Prueba esto:"

Transcript open. 

3 > 10 
\tifTrue: [Transcript show: \'Quizás hay un error ....\']
\tifFalse: [Transcript show: \'No: 3 es menor que 10\']. 

3=3 ifTrue: [ProfStef openPharoZenWorkspace].

"Ahora ve a la siguiente lección"',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @185,
											#level : 2,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Lección22: Ciclos e Iteradores',
											#key : '',
											#body : '"Los ciclos con iteradores de alto nivel sobre las colecciones, implementados como métodos regulares."

"Ciclos básicos:
  to: do:
  to:by:do"

1 to: 10.

1 to: 15 do:
  [:i | Transcript show: i*2  "asString"; cr ]. 

1 to: 20 by: 3 do: [:i | Transcript show: i asString; cr].

30 to: 0 by: -2 do: 
    [:i | Transcript show: i asString; cr].

"Ahora ve a la siguiente lección"',
											#tags : 'código',
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : '¿Qué hacer cuando necesito tanto el índice como el objeto?',
													#key : '',
													#body : '"doWithIndex permite trabajar con los objetos y con su índice, es decir tener bloques
que reciben dos argumentos"
| colors |

colors := OrderedCollection new.
colors 
\tadd:(Color r: 1 g: 0 b: 0);
\tadd:(Color r: 0 g: 1 b: 0);
\tyourself.
olors doWithIndex: [ :color :i | Transcript show: \'El color número \', i asString, \' es: \', color name asString; cr ]
',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @240,
													#level : 3,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : @185,
											#level : 2,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Lección 23: Colecciones',
											#key : '',
											#body : '"El mensaje do: es enviado a una colección de objetos (Array, Set, OrderedCollection),
evaluando el bloque para cada elemento.

Acá queremos imprimir todos los números sobre el Transcript (una consola)"

| miColeccion |

#(11 38 3 -2 10) do: [:each |
     Transcript show: each*2; cr].

"Some other really nice iterators"

miColeccion := #(11 38 3 -2 10) collect: [:each | each abs].

#(11 38 3 -2 10) collect: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each >= 10].  

#(11 38 3 -2 10) reject: [:each | each > 10]. 

#(11 38 3 -2 10) 
     do: [:each | Transcript show: each printString]
     separatedBy: [Transcript show: \'.\'].

#(11 38 3 -2 10) detect: [ :el | el = 0 ] ifFound: 
 ifNone: [  ^ nil ]

"Ahora ve a la siguiente lección"',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @185,
											#level : 2,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Opcional',
											#key : '',
											#body : 'Las siguientes lecciones son algo más avanzadas y referidas a elementos  de interfaces gráficas
(botones, morphs) y cambios en caliente en los métodos de Smalltalk.
Si bien son importantes, las exploraremos con detalle en otros lugares, así que puedes
pasar al cierre de este tutorial y luego ir  a otros nodos como los de
código elegante en Pharo y otros ejemplos minimalistas para terminar en los distintos
proyectos del nodo titulado "Visualización de datos".',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Lección24',
													#key : '',
													#body : '"Los objetos son instancias de sus clases. Usualmente, enviamos el mensaje #new a una clase
para crear una instancia de esta clase.

El mensaje #allInstances enviado a una clase, responde un arreglo con todas las instancias de esta clase.

Por ejemplo, miremos cuántas instancias de SimpleButtonMorph existen, imprimiendo la siguiente línea:"

SimpleButtonMorph allInstances size.

"Ahora creemos una nueva instancia de él"

SimpleButtonMorph new
\tlabel: \'Un agradable botón\';
\topenCenteredInWorld.

"Ves el botón centrado en el mundo? La lista de todas las instancias debería contener una instancia más:"

SimpleButtonMorph allInstances size.

"Juguemos con él:"

SimpleButtonMorph allInstances last 
\tlabel: \'El Tutorial de Pharo es cheeevere !\';
\tcolor: Color cyan.
\t
"Borrémosla y pidámosle al sistema limpiar la memoria:"

SimpleButtonMorph allInstances last delete.
Smalltalk garbageCollect.
SimpleButtonMorph allInstances size.

"Haz click sobre el botón para ir a la siguiente lección:"

SimpleButtonMorph new
\tlabel: \'Go to next lesson\';
\ttarget: [ProfStef next. 
\t\t\tSimpleButtonMorph allInstances last delete];
\tactionSelector: #value;
\topenCenteredInWorld.
\t
"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @249,
													#level : 3,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 25',
													#key : '',
													#body : '"Puedes inspeccionar y cambiar el sistema en tiempo de ejecución.

Mira el código fuente del método #ifFalse:ifTrue: de la clase True:"

(True>>#ifFalse:ifTrue:) definition.

"O sólo su comentario:"

(True>>#ifFalse:ifTrue:) comment.

"Acá están todos los métodos que implementa el ProfStef, base de este notebook:"

ProfStef selectors.

"Creemos un nuevo método para ir a la siguiente lección:"

ProfStef class compile:\'goToNextLesson
  self next\'.

"Wow! No puedo esperar a usar mi nuevo método!"

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @249,
													#level : 3,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 26',
													#key : '',
													#body : '"Tan chévere, ¿no? Antes de ir más allá, removamos este método:"

ProfStef respondsTo: #goToNextLesson.

ProfStef class removeSelector: #goToNextLesson.

ProfStef respondsTo: #goToNextLesson.

"Ahora mover hacia adelante"



"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @249,
													#level : 3,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 27',
													#key : '',
													#body : '"Pharo is full of objects. There are windows, text, numbers, dates, colors, points and much more. You can interact with objects in a much more direct way than is possible with other programming languages.

Every object understands the message \'explore\'. As a result, you get an Explorer window that shows details about the object."

Date today explore.

"This shows that the date object consists of a point in time (start) and a duration (one day long)."

ProfStef explore.

"You see,  class has a lot of objects. Let\'s take a look at my code:"

ProfStef browse.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @249,
													#level : 3,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 28',
													#body : '',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @249,
													#level : 3,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 29',
													#body : '"This tutorial is done. Enjoy programming with Pharo. 

Don\'t forget to read \'Pharo By Example\' found here:  

\thttp://pharobyexample.org/

You can run this tutorial again by evaluating:"

ProfStef go.

"Do you want to create your own interactive tutorial with ProfStef? That\'s very easy!!  How ? There\'s a ProfStef interactive tutorial for that :D
Just evaluate the following code:"

ProfStef goOn: HowToMakeYourOwnTutorial

"But, of course, if you are reading this as a Grafoscopio notebook, you will be able to create
other tutorials as interactive notebooks, like this one in a really easy way.

Please explore the next parts of this interactive notebook or go to the Grafoscopio page to learn
more about it: 

http://mutabit.com/grafoscopio/ <~ Spanish page
http://mutabit.com/grafoscopio/index.en.html <~ Engish page

"

"See you soon !"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @249,
													#level : 3,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : @185,
											#level : 2,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Cierre',
											#body : 'Esta parte del tutorial ha introducido la sintaxis y los elementos básicos del lenguaje.
Las lecciones venideras construyen sobre ello y profundizan en Pharo, aplicándolo a
problemas cada vez más complejos y específicos, desde los cuales esperamos puedas
construir tus propias recontextualizaciones y adaptaciones.',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [ ],
											#parent : @185,
											#level : 2,
											#links : OrderedCollection [
												''
											]
										}
									],
									#parent : GrafoscopioNode {
										#header : 'Arbol principal',
										#key : '',
										#body : '',
										#tags : OrderedCollection [
											'text'
										],
										#children : OrderedCollection [
											GrafoscopioNode {
												#header : 'Presentación',
												#key : '',
												#body : Text {
													#string : 'El presente documento tiene como finalidad ayudarte a comprender el funcionamiento básico de Pharo y Grafoscopio.
Se trata de un documento rápido. Para una introducción alternativa a Grafoscopio, su historia, inspiraciones e innovación,
puedes revisar el "Manual de grafoscopio", que está disponible desde el menú  ̀Ayuda ̀ en sus distintos formatos.
Tanto este tutorial como el manual están construyéndose y podrían llegar a integrarse luego en un único documento.

Para navegar este tutorial, si lo estás viendo como un documento interactivo dentro de grafoscopio, 
(si no lo estás viendo así, te recomendamos que lo abras para hacer la experiencia más interactiva)
basta con que hagas click en cada uno de los nodos que aparecen en el árbol lateral izquierdo. 
Dichos nodos pueden contener otros subnodos lo cual se indica por un pequeño triángulo a la izquierda del nombre
del nodo, que puede estar apuntando a la derecha, para indicar que los contenidos del nodo están comprimidos
o hacia abajo, cuando están extendidos.
Para desplegar o contraer los contenidos de un nodo que agrupa a otros, haces click en dicho triángulo.
',
													#runs : RunArray {
														#runs : [
															1142
														],
														#values : [
															[ ]
														],
														#lastIndex : 1,
														#lastRun : 1,
														#lastOffset : 0
													}
												},
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [ ],
												#parent : @275,
												#level : 1,
												#links : OrderedCollection [
													''
												]
											},
											GrafoscopioNode {
												#header : 'Actos de extrañeza',
												#key : '',
												#body : Text {
													#string : 'Este tutorial puede lucir un poco extraño, particularmente si no eres programador.
Esto es porque la primera parte es la adaptación de un tutorial para programadores,
que presupone muchos conceptos familiares con la jerga de la programación.
Si eres un programador notarás que, si bien los conceptos son familiares, las maneras
de implementarlos en Smalltalk son distintas y, de hecho más puros y cercanos a las
ideas originales (allí se inició mucho de la computación actual, aunque lo que tenemos
es distinto de lo que se soño).
No te inquietes, iremos explorando y entendiendo con el tiempo esos artefactos extraños, 
y si lees esto como parte de un taller cara a cara (como el Data Week) tendremos tiempo
para conversarlos con mayor detalle.
Además las versiones de este tutorial han cambiado y mejorado con el tiempo, por
lo cual, una versión posterior de grafoscopio y su documentación tendrán mejores
formas de abordar los conceptos.

Por lo pronto te invitamos a que mires este ejercicio de manera casi que etnográfica:
Te aproximarás a un cultura (la de la programación) desde los artefactos prototípicos
que sus pobladores (los programadores) usan, pero en la medida en que lo vayas haciendo
dicha cultura te parecerá menos extraña y ayudarás a construir artefactos menos ajenos, 
que brinden bienvenidas más cálidas y conectadas con personas de culturas más diversas,
como tu.',
													#runs : RunArray {
														#runs : [
															1406
														],
														#values : [
															[ ]
														],
														#lastIndex : 1,
														#lastRun : 1,
														#lastOffset : 0
													}
												},
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [ ],
												#parent : @275,
												#level : 1,
												#links : OrderedCollection [
													''
												]
											},
											GrafoscopioNode {
												#header : 'Agradecimientos',
												#key : '',
												#body : Text {
													#string : 'Este tutorial es producto del trabajo realizado durante varios talleres en el hackerspace
 [Hackbo](http://hackbo.co) en Bogotá, Colombia, entre ellos:

  - Los talleres de indie web science, ( 1 noviembre de 2014)
  - Los talleres del [Data Week](http://mutabit.com/dataweek) y sus eventos preparatorios y posteriores.

Agradecemos a las personas que asistieron a los talleres y ayudaron con su presencia a probar este material,
Entre ellos: César Augusto Arias, Claudia Baez, Carlos Barreneche, Luis Alejandro Bernal, Fernando Castro, 
Felix Gerlof, Florencia Goldsman, Camilo Hurtado, Luis Linares, Offray Luna, Rafael Medida, Gloria Meneses, 
Fredy Pulido,  Iván Pulido, Sebastian Pulido  y David Salvador.',
													#runs : RunArray {
														#runs : [
															719
														],
														#values : [
															[ ]
														],
														#lastIndex : 1,
														#lastRun : 1,
														#lastOffset : 0
													}
												},
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [ ],
												#parent : @275,
												#level : 1,
												#links : OrderedCollection [
													''
												]
											},
											@185,
											GrafoscopioNode {
												#header : 'Intermedio: Scripting',
												#key : '',
												#body : '',
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [
													GrafoscopioNode {
														#header : '"one liners"',
														#key : '',
														#body : 'Estos scripts de una sóla línea (o "casi una" :-P) que fueron tomados de 
[elegant pharo code](https://medium.com/concerning-pharo/elegant-pharo-code-bb590f0856d0#.6kmkvmvre).
Recomendamos que le des una mirada esta excelente entrada de blog com más detalles e
ir completando los ejemplos que iniciamos acá.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Get the HTML source of a web page',
																#key : '',
																#body : '\'http://www.pharo.org\' asUrl retrieveContents
',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @308,
																#level : 3,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Compute difference in days between two dates',
																#key : '',
																#body : '(\'2014-070-01\' asDate - \'2013/2/1\' asDate) days',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @308,
																#level : 3,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Decimal digit length of 42!',
																#key : '',
																#body : '42 factorial decimalDigitLength',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @308,
																#level : 3,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Set up an HTTP server that returns the current timestamp',
																#key : '',
																#body : '(ZnServer startDefaultOn: 8080) 
  onRequestRespond: [ :request | 
    ZnResponse ok: (ZnEntity with: DateAndTime now printString) ]',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @308,
																#level : 3,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Take an email address and get its respective avatar from Gravatar when exits',
																#key : '',
																#body : '| email url |
email := \'Gpmeneses@gmail.com\'.
email trimBoth asLowercase.
(MD5 hashMessage: email trimBoth asLowercase) hex.

url := 
 \'http://www.gravatar.com/avatar/\', 
 (MD5 hashMessage: email trimBoth asLowercase) hex,
 \'.jpg\'.
(ZnEasy getJpeg: url) asMorph openInWindow 
',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @308,
																#level : 3,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Convert all JPG files in the current directory to PNG format',
																#key : '',
																#body : '(FileLocator workingDirectory filesMatching: \'*.jpg\') do: [ :each |
  (each withExtension: \'png\') writeStreamDo: [ :out |
    each readStreamDo: [ :in |
      (PNGReadWriter on: out) nextPutImage: 
        (JPEGReadWriter on: in) nextImage ] ] ]',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @308,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Sum of the primes up to 64',
																#key : '',
																#body : '(Integer primesUpTo: 64) sum',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @308,
																#level : 3,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @305,
														#level : 2,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : '"Few liners" ;-)',
														#key : '',
														#body : 'Estos son otros scripts interesantes que fueron tomados de ejemplos de la comunidad.
Los créditos al autor original están colocados en los comentarios de cada script.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Composición y escalado de morphs (elementos gráficos)',
																#key : '',
																#body : '"Este script toma una image grande, la coloca como fondo y coloca dos morphs simples, un
círculo y un rectángulo escalados sobre ella. Puede tardar un poco en ejecutarse"
| window pane board background scaler|

background := AlphaImageMorph withForm: 
\t(ZnEasy getJpeg: \'http://i.imgur.com/K1QR9vA.jpg\').
background lock.

board := PasteUpMorph new.
board 
color: Color gray;
borderWidth: 3;
borderColor: Color black;
extent: 2000@2000; 
backgroundMorph: background;
addMorph: (CircleMorph new color: Color cyan; position: 41@23; yourself);
addMorph: (Morph new color: Color orange; position: 1200@1200; yourself).

scaler := TransformMorph new.
scaler extent: 1000@1000.
scaler scale: 0.5@0.5.
scaler addMorph: board.

pane := ScrollPane new.
pane scroller addMorph: scaler.

window := pane openInWindow.
window position: 20@20; extent: 420@420.
',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @333,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Traer un avatar asociado a un correo electrónico',
																#key : '',
																#body : '| email url |
email := \'gpmeneses@gmail.com\'.
url := \'http://www.gravatar.com/avatar/\', (MD5 hashMessage: email trimBoth asLowercase) hex, \'.jpg\'.
(ZnEasy getJpeg: url) asMorph openInWindow 
',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @333,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Graficar un AST (árbol de sintaxis abstracta)',
																#key : '',
																#body : '| ast builder |
ast := RBParser parseExpression: \'self foo. super foo\'.
    builder := RTMondrian new.
    builder shape ellipse size: 15.
    builder nodes: ast allChildren.
    builder edges connectFrom: #parent.
    builder layout tree.
    builder',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @333,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'OSM: Consultar Nominatim',
																#key : '',
																#body : '"Thanks to Henrik Nergard"
"Nominatim es un motor de búsqueda para OpenStreetMap. 
Para mayor información sobre este consultar:

http://nominatim.openstreetmap.org/

Este pequeño script extrae resultados de Nominatim y entrega
un polígo que delimita una zona geográfica, reconocida por un nombre, 
por ejemplo \'Teusaquillo\',en Bogotá
"

| baseURL query settings result entries |

query := UIManager default request: \'Find location for\' .

baseURL := \'http://nominatim.openstreetmap.org/search/\'.
settings := \'?format=jsonv2&limit=10\'.

result := MCFileTreeJsonParser parse: (baseURL , query asString, settings) asZnUrl retrieveContents.

(result collect: [ :dct |
\t(dct at: \'display_name\') -> 
\t\t((dct at: \'lat\') asNumber @ (dct at: \'lon\') asNumber)
]) inspect .',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @333,
																#level : 3,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Lista de las capitales del mundo',
																#key : '',
																#body : '"Thanks to Hernán Morales Durand"
((NeoJSONReader fromString: (
    ZnEasy 
        get: \'http://api.geonames.org/countryInfoJSON\'
        username: \'demo\'
        password: \'\') contents) at: #geonames) collect: [ : d | d at: #capital ]',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @333,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Jugando un poco con Open Movie Database',
																#key : '',
																#body : 'Veremos cómo consultar la base de datos de Open
Movie Data Base y extraer datos particulares. 

Los ejemplos acá están basados en variaciones de
código provisto por Hernan Morales Durand.',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Afiche de tu película favorita',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Ejemplos',
																				#key : '',
																				#body : '',
																				#tags : '',
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Blade Runner',
																						#key : '',
																						#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Blade Runner\';
        get;
        contents)) at: #Poster))
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @357,
																						#level : 5,
																						#links : OrderedCollection [
																							''
																						]
																					},
																					GrafoscopioNode {
																						#header : 'Back to the future',
																						#key : '',
																						#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Back to the future\';
        get;
        contents)) at: #Poster))
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @357,
																						#level : 5,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Ghost in the Shell',
																						#key : '',
																						#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'ghost in the shell\';
        get;
        contents)) at: #Poster))
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @357,
																						#level : 5,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Good will hunting',
																						#key : '',
																						#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Good will hunting\';
        get;
        contents)) at: #Poster))
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @357,
																						#level : 5,
																						#links : OrderedCollection [
																							''
																						]
																					},
																					GrafoscopioNode {
																						#header : 'Magnolia',
																						#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Magnolia\';
        get;
        contents)) at: #Poster))
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @357,
																						#level : 5,
																						#links : OrderedCollection [
																							'',
																							'http://ws.stfx.eu/6IAL3JKJRYBU'
																						],
																						#output : @371
																					},
																					GrafoscopioNode {
																						#header : 'Life Is Beautiful',
																						#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Life Is Beautiful\';
        get;
        contents)) at: #Poster))
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @357,
																						#level : 5,
																						#links : OrderedCollection [
																							'',
																							'http://ws.stfx.eu/L27MW66U41R3'
																						],
																						#output : @374
																					}
																				],
																				#parent : @354,
																				#level : 5,
																				#links : OrderedCollection [
																					''
																				]
																			},
																			GrafoscopioNode {
																				#header : 'Deconstruyendo el ejemplo',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Película con variable',
																						#key : '',
																						#body : '| aTitle |

aTitle := \'Fight club\'.

(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents)) at: #Poster))
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @378,
																						#level : 6,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Con bloques para contenidos traer el JSON)',
																						#key : '',
																						#body : '| getJSONString temp myDict |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

temp := getJSONString value: \'Magnolia\'.
temp.
myDict := NeoJSONReader fromString: temp.
"myDict at: #Director."

ZnEasy getJpeg: (myDict at: #Poster)
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @378,
																						#level : 6,
																						#links : OrderedCollection [
																							'',
																							'http://ws.stfx.eu/N002L3K1ZU80'
																						]
																					},
																					GrafoscopioNode {
																						#header : 'Usando dos bloques',
																						#key : '',
																						#body : '| getJSONString movieInfoFromJSONString jsonDataString |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

jsonDataString := getJSONString value: \'Fight club\'.

movieInfoFromJSONString := [ :aJSONString | NeoJSONReader fromString: aJSONString].


ZnEasy getJpeg:((movieInfoFromJSONString value: jsonDataString) at: #Poster)
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @378,
																						#level : 6,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Con llaves para diferentes atributos de la peli',
																						#key : '',
																						#body : '| getJSONString movieInfoFromJSONString jsonDataString movieInfoForKey getPoster |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

jsonDataString := getJSONString value: \'E.T.\'.
movieInfoFromJSONString := [ :aJSONString | NeoJSONReader fromString: aJSONString].
movieInfoForKey := [ :aKey | (movieInfoFromJSONString value: jsonDataString) at: aKey ].
movieInfoForKey value: #Actors.
getPoster := [:key | ZnEasy getJpeg:(movieInfoForKey value: key)] value: #Poster
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @378,
																						#level : 6,
																						#links : OrderedCollection [ ]
																					}
																				],
																				#parent : @354,
																				#level : 5,
																				#links : OrderedCollection [
																					''
																				]
																			},
																			GrafoscopioNode {
																				#header : 'Trivia',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'And the oscar winner is...',
																						#body : '| o i |
o :=  #[76 97 32 76 97 32 76 97 110 100] asString asText.
i := GTInspector openOn: o.
[ 1 second wait.
o
    addAttribute: TextEmphasis struckOut;
    append: #[77 111 111 110 108 105 103 104 116] asString.
i model update ] fork.
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @394,
																						#level : 6,
																						#links : OrderedCollection [
																							'',
																							'http://ws.stfx.eu/6MEJ55EXLSOA'
																						]
																					}
																				],
																				#parent : @354,
																				#level : 5,
																				#links : OrderedCollection [
																					''
																				]
																			}
																		],
																		#parent : @351,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @333,
																#level : 3,
																#links : OrderedCollection [
																	''
																]
															}
														],
														#parent : @305,
														#level : 2,
														#links : OrderedCollection [ ]
													}
												],
												#parent : @275,
												#level : 1,
												#links : OrderedCollection [ ]
											},
											GrafoscopioNode {
												#header : 'CInemania: Creando el primer paquete',
												#key : '',
												#body : 'Acá tomaremos el ejemplo anterior de Open  Movie Data Base y lo convertiremos en una aplicación.
Esto nos permitirá entender la lógica con la que eso se hace y  "leer" la forma en que otras aplicaciones
están hechas.',
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [
													GrafoscopioNode {
														#header : 'Los de Offray',
														#key : '',
														#body : '',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Crear un nuevo paquete',
																#key : '',
																#body : '"Esta es la ventana que nos pide el nombre de un paquete que estamos agregando al sistema"
ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/create-new-package.png\'',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @408,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Paquete recien creado',
																#key : '',
																#body : '"Una vez hallamos creado el paquete cinemanía veremos lo siguiente:"

ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/new-package-created.png\'

"Este es el paquete vacio, aún sin ningún objeto en particular"',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @408,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Comentarios de una clase: por llenar',
																#key : '',
																#body : '"Recien se crea una clase, aparece un símbolo de admiración al lado izquierdo
de su nombre. Si hacemos click en el botón \'Comments\' podremos indicar el propósito de dicha
clase, como se muestra en la siguiente pantalla"
ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/add-comments.png\'',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @408,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Comentarios de una clase: llenándolos (dirty)',
																#key : '',
																#body : '"Reemplazamos la plantilla de comentarios que se nos da por omisión, por alguna descripción de lo que hace el paquete.
Veremos que la esquina superior derecha está resaltada, lo que indica que el comentario aún no se ha salvado,
como muestra esta pantalla"

ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/add-comments-filled.png\'

"y luego salvamos usando Comand S (Mac), Ctrl S (Windows, Gnu/Linux) o el menú"',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @408,
																#level : 3,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @405,
														#level : 2,
														#links : OrderedCollection [ ]
													}
												],
												#parent : @275,
												#level : 1,
												#links : OrderedCollection [ ]
											},
											GrafoscopioNode {
												#header : 'Nix: Instalación de software',
												#key : '',
												#body : 'En ocasiones el software que tenemos instalado en nuestra máquina es insuficiente para
realizar la tareas que queremos.
En ese caso, apelamos a sistemas de instalación de paquetes y existen distintos que son 
multiplataforma ([Zero Install]( )) o específicos de ciertas plataformas.
Por ejemplo, en plataformas Gnu/Linux contamos con sistemas como `apt-get` o `pacman`
para gestionar la instalación de software.
Sin embargo, dichos gestores de instalación de software son específicos de una distribución
y sus derivados ( ̀apt-get ̀ funciona para Debian y Ubuntu,  ̀pacman ̀ para Arch y Mnajaro) y
en ocasiones queremos instalar software que no está disponible en nuestra distribución  
o que es inconpatible con las versiones actuales de lo que tenemos instalado
(particularmente para las que manejas ramas, como Debian y sus derivados) o queremos
abstraer el proceso para que no depende de una variante particular de Linux, entre las más
de 300 distribuciones disponibles (ver [Distro Watch]()).
En dichos casos, un gestor de paquetes como Nix nos brinda una alternativa para
despreocuparnos de la distribución subyacente funcionando sobre distintas variantes del
sistema Unix, incluidos Gnu/Linux, Solaris y Mac.

Para mayor información ver:

  - [https://nixos.org/nix/manual/](https://nixos.org/nix/manual/ ).
  - [NixOS](https://nixos.org/ ): The Purely Functional Linux Distribution. Una distribución basada en este gestor de paquetes.
  - [About NixOS](https://nixos.org/nixos/about.html )',
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [ ],
												#parent : @275,
												#level : 1,
												#links : OrderedCollection [ ]
											},
											GrafoscopioNode {
												#header : 'Fossil: Colaboración y control de versiones minimalista.',
												#key : '',
												#body : '',
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [ ],
												#parent : @275,
												#level : 1,
												#links : OrderedCollection [ ]
											},
											GrafoscopioNode {
												#header : 'Mustache: automatizando la creación de HTML',
												#key : '',
												#body : '',
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [
													GrafoscopioNode {
														#header : 'Instalación',
														#key : '',
														#body : 'Gofer it
   smalltalkhubUser: \'NorbertHartl\' project: \'Mustache\';
   configuration;
   loadStable',
														#tags : 'código',
														#children : OrderedCollection [ ],
														#parent : GrafoscopioNode {
															#header : 'Mustache: automatizando la creación de HTML',
															#key : '',
															#body : Text {
																#string : '',
																#runs : RunArray {
																	#runs : [ ],
																	#values : [ ]
																}
															},
															#tags : OrderedCollection [
																'text'
															],
															#children : @435,
															#parent : GrafoscopioNode {
																#header : 'twitter.com',
																#key : '',
																#body : 'Twitter: La más popular red social de microblogging, basada en comunicación vía
mensajes de un límite de hasta 140 caracteres',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Micrositio Web',
																		#key : '',
																		#body : 'Este nodo explicará como crear un micrositio web para publicar en línea resultados de las
visualizaciones.',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Pecha Kucha',
																				#key : '',
																				#body : 'Para detalles ver: https://github.com/Pharophile/PechaKucha 

Gracias a Philippe Back por esto.',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Cargar soporte para MDL en Seaside',
																						#key : '',
																						#body : 'Metacello new
    githubUser: \'DuneSt\' project: \'MaterialDesignLite\' commitish: \'development\' path: \'src\';
    baseline: \'MaterialDesignLite\';
    onWarningLog;
    load',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @450,
																						#level : 4
																					},
																					GrafoscopioNode {
																						#header : 'Cargar soporte Pecha Kucha',
																						#key : '',
																						#body : 'Metacello new
    githubUser: \'Pharophile\' 
    project: \'PechaKucha\' 
    commitish: \'master\' 
    path: \'packages\';
    baseline: \'PechaKucha\';
    onWarningLog;
    load',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @450,
																						#level : 3
																					},
																					GrafoscopioNode {
																						#header : 'Iniciar la aplicación',
																						#key : '',
																						#body : 'PKApplication declareApplicationAndStartServer.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @450,
																						#level : 3
																					}
																				],
																				#parent : @447,
																				#level : 3
																			}
																		],
																		#parent : @444,
																		#level : 2
																	},
																	GrafoscopioNode {
																		#header : 'Prototipo Data Selfie',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Básico',
																				#key : '',
																				#body : '"Esto supone que ya se ha descargado y descompreso el archivo de mensajes de Twitter"
| profile aMessagesFile |
profile := TwitterProfileOverview new
\tscreenName: \'offrayLC\'.
profile getAvatar.
aMessagesFile := (FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'DataSelfies\' / \'Twitter\' / \'DataDumps\' / \'offrayLC\' / \'data\' / \'js\' / \'tweets\' /\'2013_02.js\') asFileReference.
profile splitMessagesByTypeFrom: aMessagesFile.
profile avatarWheel ',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @459,
																				#level : 3
																			},
																			GrafoscopioNode {
																				#header : 'Cargar mensajes',
																				#key : '',
																				#body : '"Esto supone que ya se ha descargado y descompreso el archivo de mensajes de Twitter"
| aMessagesFile |
aMessagesFile := (FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'DataSelfies\' / \'Twitter\' / \'DataDumps\' / \'offrayLC\' / \'data\' / \'js\' / \'tweets\' /\'2013_02.js\') asFileReference.
TPMessages new splitMessagesByTypeFrom: aMessagesFile.
',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @459,
																				#level : 3
																			}
																		],
																		#parent : @444,
																		#level : 2
																	}
																],
																#level : 1
															},
															#level : 2
														},
														#level : 3,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'Crear con moustache el archivo de data selfies',
														#key : '',
														#body : '| workingFolder moustacheTplFile templateContent context rendered targetFile tempStream |

"Ubicación de la plantilla en el sistema de archivos"
workingFolder := FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'TwitterDataSelfies\'..
moustacheTplFile := (workingFolder / \'templates\' / \'index.html\') asFileReference.

"Leer el template como string"
templateContent := moustacheTplFile contents asString.

"Estos datos de contexto deben ser llenados desde Twitter"
context := {
   \'screen_name\' -> \'offrayLC\'.
   \'page_title\' -> \'Mi data selfie de Twitter\'.
   \'bio_message\' -> \'Esto viene de Twitter\'.
   \'url_link\' -> \'http://algo.com\'.
\t\'month\' -> \'2013_02.png\' } asDictionary.

"Procesar la plantilla con los datos de contexto"
rendered := (MustacheTemplate on: templateContent) value: context.

"Guardar el contenido renderizado en un archivo"
targetFile := (workingFolder / \'profiles\' / (context at: #screen_name) / \'index.html\') asFileReference.
tempStream := targetFile writeStream.
tempStream nextPutAll: rendered.
tempStream close.
',
														#tags : 'código',
														#children : OrderedCollection [ ],
														#parent : @438,
														#level : 3,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'http://ws.stfx.eu/1N9FKAUI2UI0',
														#key : '',
														#body : '| profile workingFolder moustacheTplFile templateContent context rendered targetFile tempStream |

profile := TwitterProfileOverview new
\tscreenName: \'LuLinGar\'.

"Ubicación de la plantilla en el sistema de archivos"
workingFolder := FileLocator root / \'media\' / \'hackbo\' / \'memoluis\' / \'dataweek\' / \'repo-dataselfies\'.
moustacheTplFile := (workingFolder / \'templates\' / \'index.html\') asFileReference.

"Leer el template como string"
templateContent := moustacheTplFile contents asString.

"Estos datos de contexto deben ser llenados desde Twitter"
context := {
   \'screen_name\' -> (profile screenName).
   \'page_title\' -> \'Mi data selfie\'.
   \'bio_message\' -> \'Esto viene de Twitter\'.
   \'url_link\' -> \'http://algo.com\' } asDictionary.

"Procesar la plantilla con los datos de contexto"
rendered := (MustacheTemplate on: templateContent) value: context.

"Guardar el contenido renderizado en un archivo"
targetFile := (workingFolder / \'profiles\' / (profile screenName) / \'index.html\') asFileReference.
tempStream := targetFile writeStream.
tempStream nextPutAll: rendered.
tempStream close.
',
														#tags : 'código',
														#children : OrderedCollection [ ],
														#parent : @438,
														#level : 3,
														#links : OrderedCollection [ ]
													}
												],
												#parent : @275,
												#level : 1,
												#nodesInPreorder : OrderedCollection [
													@433,
													@436,
													@467,
													@470
												],
												#links : OrderedCollection [ ]
											},
											GrafoscopioNode {
												#header : 'Teapot: constructor minimalista de aplicaciones web',
												#key : '',
												#body : '',
												#tags : '',
												#children : OrderedCollection [
													GrafoscopioNode {
														#header : 'Minitutorial',
														#key : '',
														#body : '',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Instalación',
																#key : '',
																#body : 'Gofer it
    smalltalkhubUser: \'zeroflag\' project: \'Teapot\';
    configuration;
    loadStable.',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @477,
																#level : 4,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Hello World',
																#key : '',
																#body : 'Teapot on
    GET: \'/welcome\' -> \'Hello World!\';
    start.

"Do it and view at: http://localhost:1701/welcome"',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @477,
																#level : 4,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Hello User',
																#key : '',
																#body : 'Teapot on
    GET: \'/hi\' -> \'Bonjour!\';
    GET: \'/hi/<user>\' -> [:req | \'Hello \', (req at: #user)];
start',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @477,
																#level : 4,
																#links : OrderedCollection [
																	''
																]
															}
														],
														#parent : GrafoscopioNode {
															#header : 'Teapot: constructor minimalista de aplicaciones web',
															#key : '',
															#body : Text {
																#string : '',
																#runs : RunArray {
																	#runs : [ ],
																	#values : [ ]
																}
															},
															#tags : '',
															#children : @476,
															#parent : @444,
															#level : 2
														},
														#level : 3,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Tealight',
														#key : '',
														#body : '',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Instalación',
																#key : '',
																#body : 'Metacello new 
    repository: \'github://astares/Tealight/repository\';
    baseline: \'Tealight\';
    load  ',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @495,
																#level : 4,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Acceder a un Teapot por omisión',
																#key : '',
																#body : 'TLWebserver teapot',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @495,
																#level : 4,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Definir una ruta para una instancia de Teapot',
																#key : '',
																#body : 'TLWebserver teapot 
    GET: \'/hi\' -> \'HelloWorld\'',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @495,
																#level : 4,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Hola usuario',
																#key : '',
																#body : 'TLWebserver teapot 
    GET: \'/hi/<user>\' -> [:req | \'Hello \', (req at: #user)]',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @495,
																#level : 4,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Transformadores de respuestas',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'A json',
																		#key : '',
																		#body : 'TLWebserver teapot
\tGET: \'/jsonlist\' -> #(1 2 3 4); output: #json',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @510,
																		#level : 5,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'A texto plano',
																		#key : '',
																		#body : 'TLWebserver teapot
\tGET: \'/textoplano\' -> \'Esto es texto plano\'; output: #text',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @510,
																		#level : 5,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Descargas',
																		#key : '',
																		#body : 'TLWebserver teapot
\tGET: \'/descargas\' -> [\'/tmp/prueba.txt\' asFileReference readStream]; output: #stream',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @510,
																		#level : 5,
																		#links : OrderedCollection [
																			''
																		]
																	}
																],
																#parent : @495,
																#level : 4,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Plantillas',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Instalar soporte Mustache',
																		#key : '',
																		#body : 'Gofer it
   smalltalkhubUser: \'NorbertHartl\' project: \'Mustache\';
   configuration;
   loadStable',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @523,
																		#level : 5,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Usarlas',
																		#key : '',
																		#body : 'TLWebserver teapot
\tGET: \'/saludo\' -> {\'phrase\' -> \'Hello\'. \'name\' -> \'World\'};
\toutput: (TeaOutput mustacheHtml: \'<b>{{phrase}}</b> <i>{{name}}</i>!\')',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @523,
																		#level : 5,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @495,
																#level : 4,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Manejo de errores',
																#key : '',
																#body : '3',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @495,
																#level : 4,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Servir archivos locales',
																#key : '',
																#body : '<b>Hello</b> <i>World</i>!',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @495,
																#level : 4,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Mirar procesos de Tealight',
																#key : '',
																#body : 'TLWebserver teapot inspect',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @495,
																#level : 4,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @489,
														#level : 3,
														#links : OrderedCollection [
															'',
															'https://github.com/astares/Tealight'
														]
													}
												],
												#parent : @275,
												#level : 1,
												#nodesInPreorder : OrderedCollection [
													@475,
													@477,
													@480,
													@483,
													@486,
													@495,
													@498,
													@501,
													@504,
													@507,
													@510,
													@513,
													@516,
													@519,
													@523,
													@526,
													@529,
													@533,
													@536,
													@539
												],
												#links : OrderedCollection [
													''
												]
											},
											GrafoscopioNode {
												#header : 'Borradores',
												#key : '',
												#body : 'Acá encontrarás código que aún no está tan maduro como el que has visto hasta el momento.
Son algunos apuntes de diferentes prototipos que están avanzando y algún código que no continuo.
Pharo es un entorno dinámico que mejora continuamente.
Al darte una mirada de estos borradores puedes ver parte del proceso de construcción del cierto 
código y vincularte al proceso.

Futuras versiones de este cuaderno interactivo, tendrán ediciones más maduras y robustas del
código.',
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [
													GrafoscopioNode {
														#header : 'Visualización de datos',
														#key : '',
														#body : 'Acá están recopilados algunos ejemplos que hemos hecho con data scrapping (raspado de datos)',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Twitter',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Usando algunos scrappers predefinidos',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Ejemplo 1: Un perfil',
																				#key : '',
																				#body : '',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @554,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Ejemplo 2: Dos perfiles',
																				#key : '',
																				#body : '| perfil1 perfil2 perfiles |

perfil1 := TwitterProfile new.
perfil2 := TwitterProfile new.

"Vmmos a crear un nuevo perfil"
perfil1 scrapDataForProfile: \'PetroGustavo\'.
perfil2 scrapDataForProfile: \'JuanManSantos\'.

perfiles := OrderedCollection new.
perfiles 
\tadd: perfil1;
\tadd: perfil2.
perfiles.',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @554,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Ejemplo 3: Varios perfiles',
																				#key : '',
																				#body : '| perfil perfiles misPoliticos |

misPoliticos := #(\'PetroGustavo\' "Alcalde de Bogotá"
\t\t\t\t\t\t\'JuanManSantos\' "Presidente de Colombia" 
\t\t\t\t\t\t\'ginaparody\' "Ministra de educación de Colombia"
\t\t\t\t\t\t\'CFKArgentina\' "Presidenta de Argentina").

perfiles := OrderedCollection new.

misPoliticos do: [:politico |
\t  \tperfil := TwitterProfile new.
\t\tperfil scrapDataForProfile: politico.
\t\tperfiles add: perfil.].
perfiles.',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @554,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			}
																		],
																		#parent : @551,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Deconstruyendo un scrapper.',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Traerse el html',
																				#key : '',
																				#body : '\t| client anUrl aProfileName |
\taProfileName := \'dominemosLasTIC\'.
\tanUrl := \'https://twitter.com/\', aProfileName.
\tclient := ZnClient new.
\tclient get: anUrl.',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @567,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Encontrar algo dentro del html',
																				#key : '',
																				#body : '\t| client anUrl aProfileName |
\taProfileName := \'dominemosLasTIC\'.
\tanUrl := \'https://twitter.com/\', aProfileName.
\tclient := ZnClient new.
\tclient get: anUrl.',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @567,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			}
																		],
																		#parent : @551,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @548,
																#level : 2,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Contratos públicos',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Visualización Guía: Treemapping',
																		#key : '',
																		#body : 'Para mirar cómo se han realizado los gastos presupuestales, usaremos como visualización guía una que es producida por
la técnica de *treemapping* y que permite explorar cómo una jerarquía está compuesta por partes disyuntas que la conforman
(como en el caso de la división de presupuestos).
Para mayor información sobre dicha técnica véase la 
[página de la wikipedia sobre treemapping](https://en.wikipedia.org/wiki/Treemapping)',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Ejemplo 1',
																				#key : '',
																				#body : '\t| b |
\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color veryLightGray.
\t
\tb from: (1 to: 17) using: [#()].
\tb weight: #yourself.
\tb build.
\t^ b view',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @581,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Ejemplo 2',
																				#key : '',
																				#body : 'RTTreeMapExample new exampleNumber',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @581,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Integrando datos a la visualización',
																				#key : '',
																				#body : '| aFile aCharacter table b |

aFile := (FileLocator documents / \'DataWeek\' / \'query-subtotales-por-segmentos.csv\') asFileReference.
aCharacter := $,.
table := RTTabTable new input: aFile contents usingDelimiter: aCharacter.
table valuesOfColumn: 2.

\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color veryLightGray.
\tb from: (2 to: table numberOfRows) using: [#()].
\tb weight: [:n | (table valuesOfColumn: 2) at: n ].
\tb build.
\tb view.
table values',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @581,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Probando OpenSpending',
																				#key : '',
																				#body : '| contratos archivo |

archivo := (FileLocator documents / \'DataWeek\' / \'query-subtotales-por-segmentos.csv\') asFileReference.
contratos := OpenSpending new.
contratos loadDataFromCSV: archivo usingDelimiter: $,.
contratos',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @581,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Treemap con etiquetas',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Primera versión',
																						#key : '',
																						#body : '| b labels popup |
\tlabels := RTLabel elementsOn: #(\'uno\' \'dos\' \'tres\' \'cuatro\' \'cinco\').
\tpopup := RTPopup new.
\tpopup text: [:object | labels at: object  ].
\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color random.
\tb from: (1 to: 5) using: [#()].
\tb weight: [:n | n].
\tb build.
\tb view elements @ RTLabelled.
\t^ b view.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @596,
																						#level : 5,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Entendiendo popups dinámicos',
																						#key : '',
																						#body : '',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @596,
																						#level : 5,
																						#links : OrderedCollection [ ]
																					}
																				],
																				#parent : @581,
																				#level : 4,
																				#links : OrderedCollection [ ]
																			}
																		],
																		#parent : @578,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @548,
																#level : 2,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @545,
														#level : 2,
														#links : OrderedCollection [ ]
													}
												],
												#parent : @275,
												#level : 1,
												#links : OrderedCollection [ ]
											}
										],
										#level : 0,
										#nodesInPreorder : OrderedCollection [
											@275,
											@278,
											@287,
											@296,
											@185,
											@194,
											@198,
											@199,
											@200,
											@179,
											@176,
											GrafoscopioNode {
												#header : 'Characters',
												#key : '',
												#body : '"Un caracter puede ser instanciado usando el operador $"

$A.

"You can find which is the ASCII number for a character"

$@ charCode.

"There are some character that are not printable"

Character cr.

Character space.

"Puedes imprimir todos los 256 caracteres del código extendido ASCII"

Character allByteCharacters.

"If you see gliberish is because some display issue"

"Ahora ve a la siguiente lección"',
												#tags : OrderedCollection [
													'código'
												],
												#children : OrderedCollection [ ],
												#parent : @179,
												#level : 3,
												#links : OrderedCollection [
													''
												]
											},
											GrafoscopioNode {
												#header : 'Strings',
												#headers : OrderedCollection [ ],
												#key : '',
												#body : '"Un String o cadena es una colección de caracteres. 
Usa comillas simples para crear un objeto String. 
Imprime estas expresiones"

\'a\' class.

$a class.

\'PharoTutorial\'.

\'PharoTutorial\' size.

\'abc\' asUppercase.

\'NO more Hello World!\' reverse.

\'Adan no calla con nada\' reverse.

\'Anita lava la tina\' reverse.

"Puedes acceder a cada caracter usando \'at:mensaje\'"

\'PharoTutorial\' at:6.

"La concatenación de String usa el operador coma:"

[\'PharoTutorial\', \' is cool\']. "versión cambiada"

\'Pharo tutorial \', \' is cool\', \' when i active the code \'.

"Ahora ve a la siguiente lección"',
												#tags : OrderedCollection [
													'código'
												],
												#children : OrderedCollection [ ],
												#parent : @179,
												#level : 3,
												#links : OrderedCollection [
													''
												]
											},
											GrafoscopioNode {
												#header : 'Symbols',
												#headers : OrderedCollection [ ],
												#key : '',
												#body : '"Un \'Symbol\' es un String único globalmente.

Hay uno y solo un Symbol #PharoTutorial. Pueden existir varios objetos String \'PharoTutorial\'

(Message=retorna \'true\' si los dos objetos son IGUALES)"

\'PharoTutorial\' asSymbol.

#PharoTutorial asString.

"Notra: En mátemáticas hay dos tipos de igualdad:

x = 3 <- Aginación. A la variable x, le estamos asignando el valor 3.
2 = 3 <- Comparación: dados dos elementos conocidos decir si es o no el mismo.

Para Smalltalk es:

x := 3. <- Aginación.
2 = 3 <- Comparación.
a == a <- Comparación fuerte. Se trata del mismo símbolo?
"

\'PharoTutorial\' = \'PharoTutorial\'.
\'PharoTutorial\' == \'PharoTutorial\'.

#PharoTutorial = \'PharoTutorial\'.
#PharoTutorial == \'PharoTutorial\'.

(2 asString) == (2 asString).


(2 asString) asSymbol == (2 asString) asSymbol.


"Ahora ve a la siguiente lección"
',
												#tags : OrderedCollection [
													'código'
												],
												#children : OrderedCollection [ ],
												#parent : @179,
												#level : 3,
												#links : OrderedCollection [
													''
												]
											},
											GrafoscopioNode {
												#header : 'Arrays',
												#headers : OrderedCollection [ ],
												#key : '',
												#body : '"Los arreglos son maneras de guardar información información diversa.
Los hay de dos tipos, estáticos y dinámicos. Acá veremos los primeros"
#(1 2 3).

#( 1 2 3 #(4 5 6)) size.

#(1 2 4) isEmpty.

#(1 2 3) first.

#(\'hello\' \'World\') 
    at: 2 put: \'Pharo\'; 
   yourself.
',
												#tags : OrderedCollection [
													'código'
												],
												#children : OrderedCollection [ ],
												#parent : @179,
												#level : 3,
												#links : OrderedCollection [
													'',
													'http://ws.stfx.eu/7FXPZYUXWU54'
												]
											},
											GrafoscopioNode {
												#header : 'Dynamics Arrays',
												#headers : OrderedCollection [ ],
												#key : '',
												#body : '"Los arreglos dinámicos son creados durante el tiempo de ejecución, es decir que podemos
guardar en ellos cálculos que luego se ejecutarán y determinarán lo que en ellos se guarda"

{ (2+3).(6*6) }.

"Comparemos este arreglo estático"

#( (2+3)  (6+6)  \'hello\' , \'Stef\') size.  

"con este arreglo dinámico:"

{ (2+3) . (6+6) . \'hello\' , \'Stef\' } size.

"Ahora ve a la siguiente lección"
',
												#tags : OrderedCollection [
													'código'
												],
												#children : OrderedCollection [ ],
												#parent : @179,
												#level : 3,
												#links : OrderedCollection [
													''
												]
											},
											@201,
											@204,
											@208,
											@212,
											@215,
											@218,
											@221,
											@224,
											@227,
											@231,
											@234,
											@237,
											@240,
											@242,
											@246,
											@249,
											@252,
											@255,
											@258,
											@261,
											@264,
											@267,
											@271,
											@305,
											@308,
											@311,
											@314,
											@317,
											@320,
											@323,
											@326,
											@329,
											@333,
											@336,
											@339,
											@342,
											@345,
											@348,
											@351,
											@354,
											@357,
											@359,
											@362,
											@365,
											@368,
											@371,
											@374,
											@378,
											@381,
											@384,
											@387,
											@390,
											@394,
											@397,
											@405,
											@408,
											@411,
											@414,
											@417,
											@420,
											@425,
											@429,
											@433,
											@436,
											@467,
											@470,
											@475,
											@477,
											@480,
											@483,
											@486,
											@495,
											@498,
											@501,
											@504,
											@507,
											@510,
											@513,
											@516,
											@519,
											@523,
											@526,
											@529,
											@533,
											@536,
											@539,
											@545,
											@548,
											@551,
											@554,
											@557,
											@560,
											@563,
											@567,
											@570,
											@573,
											@578,
											@581,
											@584,
											@587,
											@590,
											@593,
											@596,
											@599,
											@602
										]
									},
									#level : 1,
									#links : OrderedCollection [
										''
									]
								},
								#level : 2,
								#links : OrderedCollection [
									''
								]
							},
							#level : 3,
							#links : OrderedCollection [
								''
							]
						},
						@611,
						@615,
						@620,
						@625,
						@630
					],
					#parent : @5,
					#level : 1,
					#nodesInPreorder : OrderedCollection [
						@173,
						@176,
						@611,
						@615,
						@620,
						@625,
						@630
					],
					#links : @636
				},
				@176,
				@611,
				@615,
				@620,
				@625,
				@630,
				GrafoscopioNode {
					#header : 'Processing data',
					#body : '',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Messages',
							#key : '',
							#body : 'Los mensajes son la forma en que los objetos se comunican entre sí y en que
nosotros, los humanos, nos comunicamos con el sistema. 
Hay tres tipos de mensajes: unary (unarios), binary (binary) y keyword.',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Unary',
									#headers : OrderedCollection [ ],
									#key : '',
									#body : '"
Los mensajes unarios tienen la forma siguiente.

anObject aMessage

Tu ya has enviado mensajes unarios. Por ejemplo:"

1 class.
#b class.

$b class.

true not.

false not.

Time now.

Date today.

Date yesterday.

Date tomorrow.

Float pi.

"Ahora ve a la siguiente lección"
',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : GrafoscopioNode {
										#header : 'Mensajes',
										#key : '',
										#body : Text {
											#string : '',
											#runs : RunArray {
												#runs : [ ],
												#values : [ ]
											}
										},
										#tags : @643,
										#children : @644,
										#parent : GrafoscopioNode {
											#header : 'Introductorio: Professor Stef',
											#headers : OrderedCollection [
												'Tutorial 1',
												'Tutorial 2',
												'Tutorial 3',
												'Tutorial 4',
												'Tutorial 5.',
												'Tutorial 6',
												'Tutorial 7',
												'Tutorial 8',
												'Tutorial 9',
												'Tutorial 10',
												'Tutorial 11'
											],
											#key : '',
											#body : 'Este tutorial mostrará los aspectos básicos de la sintaxis de Smalltalk y está basado
en el tutorial ProfStef que viene integrado a Pharo, pero convertido en un cuaderno
interactivo de Grafoscopio.
Está separado por lecciones. que vienen numeradas y en ocasiones están agrupadas.
Para ver el contenido particular de una lección se debe hacer click en ella en el árbol
lateral a la izquierda.
Si están agrupadas, se verá un triangulito en el título que las agrupa.
Al hacer click en él, se mostrarán los contenidos del mismo, que podremos seguir
explorando con la misma lógica.
',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Lección 1: Bienvenida',
													#headers : OrderedCollection [ ],
													#key : '',
													#body : '"Hola!, Soy el profesor Stef. Debes querer que te ayude a aprender 
Pharo. Así que vamos a la primera lección: aprender a ejecutar código. 
Para ello hay varias opciones:
  - Opción 1: Selecciona el texto debajo, o coloca el cursor luego del punto, dale clic 
    derecho y selecciona \'do it (d)\'
  - Opción 2: Haz click en el botón con el ícono de play que aparece justo cerca a la 
    esquina superior derecha de este panel"

ProfStef  openPharoZenWorkspace 

',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 2: Haciendo',
													#headers : OrderedCollection [ ],
													#key : '',
													#body : '"Excelente! (quise decir Súper)). Acabas de ejecutar una expresión de Pharo. Más precisamente,
enviaste el mensaje \'next\' a PharoTutorial class (¡soy yo!).

Nota que puedes correr este tutorial nuevamente evaluado \'PharoTutorial go\'.
\'PharoTutorial previous\' te devolverá a la lección anterior.

También puedes ejecutar \'Do it\' usando el comando de teclado \'ALT d\' (esto cambia de acuerdo a 
tu sistema operativo/computador: puede ser \'CMD d\' o \'CTRL d\').

Trata de evaluar las siguientes expresiones:"

Nautilus open.

SmalltalkImage current aboutThisSystem.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 3: Imprimiendo',
													#headers : OrderedCollection [ ],
													#key : '',
													#body : '"Now you\'re a Do It master ! Let\'s talk about printing. 
It\'s a Do It which prints the result next to the expression you\'ve selected.
For example, select the text below, open the menu and click on \'print it (p)\':"

1 + 2.

"You\'ve seen the letter \'p\' between parentheses next to \'print it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

Try ALT-p (or CMD-p or CTRL-p) on the following expressions:"

Date today.

Time now.

"The result is selected, so you can erase it using the backspace key. Try it !"

SmalltalkImage current datedVersion.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 4: Inspeccionando',
													#key : '',
													#body : '"Now you\'re a Do It and Print It master ! Let\'s talk about inspecting. 
It\'s a Do It which opens an Inspector on the result of evaluating the expression you\'ve selected. 
The Inspector is a tool that allows you to have a look inside an object.

For example, select the text below, open the menu and click on \'inspect it (i)\':"

1 / 2.

"You\'ve seen the letter \'i\' between parentheses next to \'inspect it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

You can use Ctrl+g to get and embedded inspector.

Try ALT-i (or CMD-i or CTRL-i) on the following expressions:"

DateAndTime today.

Float pi.

SystemVersion current.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Tipos básicos',
													#key : '',
													#body : '',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'Lección 5: Números',
															#key : '',
															#body : '"You now know how to execute Pharo code. 

Now let\'s talk about basic objects.

1, 2, 100, 2/3 ... are Numbers, and respond to many messages evaluating mathematical expressions.
Evaluate these ones:"

2.

20 factorial.

1000 factorial / 999 factorial.

(1/3).

(1/3) + (4/5).

(1/3) asFloat.

1 class.

1 class maxVal class.

.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @673,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 6: Caracteres',
															#key : '',
															#body : '"Un caracter puede ser instanciado usando el operador $"

$A.

$A class.

$@ charCode.

Character cr.

Character space.

"Puedes imprimir todos los 256 caracteres del código extendido ASCII"

Character allByteCharacters.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @673,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 7: Cadenas',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Un String o cadena es una colección de caracteres. 
Usa comillas simples para crear un objeto String. 
Imprime estas expresiones"

\'a\' class.

$a class.

\'PharoTutorial\'.

\'PharoTutorial\' size.

\'abc\' asUppercase.

\'NO more Hello World!\' reverse.

\'Adan no calla con nada\' reverse.

\'Anita lava la tina\' reverse.

"Puedes acceder a cada caracter usando \'at:mensaje\'"

\'PharoTutorial\' at:6.

"La concatenación de String usa el operador coma:"

[\'PharoTutorial\', \' is cool\']. "versión cambiada"

\'Pharo tutorial \', \' is cool\', \' when i active the code \'.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @673,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 8: Símbolos',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Un \'Symbol\' es un String único globalmente.

Hay uno y solo un Symbol #PharoTutorial. Pueden existir varios objetos String \'PharoTutorial\'

(Message=retorna \'true\' si los dos objetos son IGUALES)"

\'PharoTutorial\' asSymbol.

#PharoTutorial asString.

"Notra: En mátemáticas hay dos tipos de igualdad:

x = 3 <- Aginación. A la variable x, le estamos asignando el valor 3.
2 = 3 <- Comparación: dados dos elementos conocidos decir si es o no el mismo.

Para Smalltalk es:

x := 3. <- Aginación.
2 = 3 <- Comparación.
a == a <- Comparación fuerte. Se trata del mismo símbolo?
"

\'PharoTutorial\' = \'PharoTutorial\'.
\'PharoTutorial\' == \'PharoTutorial\'.

#PharoTutorial = \'PharoTutorial\'.
#PharoTutorial == \'PharoTutorial\'.

(2 asString) == (2 asString).


(2 asString) asSymbol == (2 asString) asSymbol.


"Ahora ve a la siguiente lección"
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @673,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 9: Arreglos',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Los arreglos son maneras de guardar información información diversa.
Los hay de dos tipos, estáticos y dinámicos. Acá veremos los primeros"
#(1 2 3).

#( 1 2 3 #(4 5 6)) size.

#(1 2 4) isEmpty.

#(1 2 3) first.

#(\'hello\' \'World\') 
    at: 2 put: \'Pharo\'; 
   yourself.
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @673,
															#level : 3,
															#links : OrderedCollection [
																'',
																'http://ws.stfx.eu/7FXPZYUXWU54'
															]
														},
														GrafoscopioNode {
															#header : 'Lección 10: Arreglos dinámicos',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Los arreglos dinámicos son creados durante el tiempo de ejecución, es decir que podemos
guardar en ellos cálculos que luego se ejecutarán y determinarán lo que en ellos se guarda"

{ (2+3).(6*6) }.

"Comparemos este arreglo estático"

#( (2+3)  (6+6)  \'hello\' , \'Stef\') size.  

"con este arreglo dinámico:"

{ (2+3) . (6+6) . \'hello\' , \'Stef\' } size.

"Ahora ve a la siguiente lección"
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @673,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														}
													],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												@649,
												GrafoscopioNode {
													#header : 'Lección 19: Bloques',
													#key : '',
													#body : '"Los mensajes en cascada son chéveres. Ahora hablemos de los bloques.
Los bloques son métodos anónimos que pueden ser almacenados en variables y ejecutados por demanda.

Los bloques están delimitados por paréntesis cuadrados: []"

[Nautilus open].

"No abre un Nautilus porque el bloque no es ejecutado.

Acá hay otro bloque que suma 2 a su argumento (su argumento se llama x):"

[:x | x+2].

"Podemos ejecutar un bloque enviandole mensajes \'value\' "
[:x | x+2] value: 5.

[Nautilus open] value.

[:x | x+2] value: 10.

[:x :y | x - y] value:3 value:5.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 20: Asignación de Bloques',
													#key : '',
													#body : '"Los bloques pueden ser asignados a variables y ejecutados después.

Note que |b| es la declaración de una variable llamada \'b\' y que \':=\' asigna un valor a una variable.

Selecciona las siguientes tres líneas e imprimelas (Print it)" 

| b |

[:x | x+2] value: 20.


b := [:x | x+2].


b value: 20. 


"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Lección 21: Condicionales',
													#key : '',
													#body : '"Los condicionales son sólo menajes enviados a objetos Boolean (booleanos)"

1 < 2
  ifTrue: [Transcript show: \'Es cierto\']
  ifFalse: [Transcript show: \'Es falso\'].

"Aquí el mensajes es ifTrue:ifFalse

Prueba esto:"

Transcript open. 

3 > 10 
\tifTrue: [Transcript show: \'Quizás hay un error ....\']
\tifFalse: [Transcript show: \'No: 3 es menor que 10\']. 

3=3 ifTrue: [ProfStef openPharoZenWorkspace].

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección22: Ciclos e Iteradores',
													#key : '',
													#body : '"Los ciclos con iteradores de alto nivel sobre las colecciones, implementados como métodos regulares."

"Ciclos básicos:
  to: do:
  to:by:do"

1 to: 10.

1 to: 15 do:
  [:i | Transcript show: i*2  "asString"; cr ]. 

1 to: 20 by: 3 do: [:i | Transcript show: i asString; cr].

30 to: 0 by: -2 do: 
    [:i | Transcript show: i asString; cr].

"Ahora ve a la siguiente lección"',
													#tags : OrderedCollection [
														'código'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : '¿Qué hacer cuando necesito tanto el índice como el objeto?',
															#key : '',
															#body : '"doWithIndex permite trabajar con los objetos y con su índice, es decir tener bloques
que reciben dos argumentos"
| colors |

colors := OrderedCollection new.
colors 
\tadd:(Color r: 1 g: 0 b: 0);
\tadd:(Color r: 0 g: 1 b: 0);
\tyourself.
colors doWithIndex: [ :color :i | Transcript show: \'El color número \', i asString, \' es: \', color name asString; cr ]

',
															#tags : OrderedCollection [
																'código'
															],
															#children : OrderedCollection [ ],
															#parent : @708,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														}
													],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 23: Colecciones',
													#key : '',
													#body : '"El mensaje do: es enviado a una colección de objetos (Array, Set, OrderedCollection),
evaluando el bloque para cada elemento.

Acá queremos imprimir todos los números sobre el Transcript (una consola)"

| miColeccion |

#(11 38 3 -2 10) do: [:each |
     Transcript show: each*2; cr].

"Some other really nice iterators"

miColeccion := #(11 38 3 -2 10) collect: [:each | each abs].

#(11 38 3 -2 10) collect: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each >= 10].  

#(11 38 3 -2 10) reject: [:each | each > 10]. 

#(11 38 3 -2 10) 
     do: [:each | Transcript show: each printString]
     separatedBy: [Transcript show: \'.\'].

#(11 38 3 -2 10) detect: [ :el | el = 0 ] 
\tifFound: [ Transcript show: \'Encontrado\' ]
 \tifNone: [  ^ nil ]

"Ahora ve a la siguiente lección"',
													#tags : OrderedCollection [
														'código'
													],
													#children : OrderedCollection [ ],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Opcional',
													#key : '',
													#body : 'Las siguientes lecciones son algo más avanzadas y referidas a elementos  de interfaces gráficas
(botones, morphs) y cambios en caliente en los métodos de Smalltalk.
Si bien son importantes, las exploraremos con detalle en otros lugares, así que puedes
pasar al cierre de este tutorial y luego ir  a otros nodos como los de
código elegante en Pharo y otros ejemplos minimalistas para terminar en los distintos
proyectos del nodo titulado "Visualización de datos".',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'Lección24',
															#key : '',
															#body : '"Los objetos son instancias de sus clases. Usualmente, enviamos el mensaje #new a una clase
para crear una instancia de esta clase.

El mensaje #allInstances enviado a una clase, responde un arreglo con todas las instancias de esta clase.

Por ejemplo, miremos cuántas instancias de SimpleButtonMorph existen, imprimiendo la siguiente línea:"

SimpleButtonMorph allInstances size.

"Ahora creemos una nueva instancia de él"

SimpleButtonMorph new
\tlabel: \'Un agradable botón\';
\topenCenteredInWorld.

"Ves el botón centrado en el mundo? La lista de todas las instancias debería contener una instancia más:"

SimpleButtonMorph allInstances size.

"Juguemos con él:"

SimpleButtonMorph allInstances last 
\tlabel: \'El Tutorial de Pharo es cheeevere !\';
\tcolor: Color cyan.
\t
"Borrémosla y pidámosle al sistema limpiar la memoria:"

SimpleButtonMorph allInstances last delete.
Smalltalk garbageCollect.
SimpleButtonMorph allInstances size.

"Haz click sobre el botón para ir a la siguiente lección:"

SimpleButtonMorph new
\tlabel: \'Go to next lesson\';
\ttarget: [ProfStef next. 
\t\t\tSimpleButtonMorph allInstances last delete];
\tactionSelector: #value;
\topenCenteredInWorld.
\t
"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @720,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 25',
															#key : '',
															#body : '"Puedes inspeccionar y cambiar el sistema en tiempo de ejecución.

Mira el código fuente del método #ifFalse:ifTrue: de la clase True:"

(True>>#ifFalse:ifTrue:) definition.

"O sólo su comentario:"

(True>>#ifFalse:ifTrue:) comment.

"Acá están todos los métodos que implementa el ProfStef, base de este notebook:"

ProfStef selectors.

"Creemos un nuevo método para ir a la siguiente lección:"

ProfStef class compile:\'goToNextLesson
  self next\'.

"Wow! No puedo esperar a usar mi nuevo método!"

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @720,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 26',
															#key : '',
															#body : '"Tan chévere, ¿no? Antes de ir más allá, removamos este método:"

ProfStef respondsTo: #goToNextLesson.

ProfStef class removeSelector: #goToNextLesson.

ProfStef respondsTo: #goToNextLesson.

"Ahora mover hacia adelante"



"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @720,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 27',
															#key : '',
															#body : '"Pharo is full of objects. There are windows, text, numbers, dates, colors, points and much more. You can interact with objects in a much more direct way than is possible with other programming languages.

Every object understands the message \'explore\'. As a result, you get an Explorer window that shows details about the object."

Date today explore.

"This shows that the date object consists of a point in time (start) and a duration (one day long)."

ProfStef explore.

"You see,  class has a lot of objects. Let\'s take a look at my code:"

ProfStef browse.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @720,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 28',
															#body : '',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @720,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 29',
															#body : '"This tutorial is done. Enjoy programming with Pharo. 

Don\'t forget to read \'Pharo By Example\' found here:  

\thttp://pharobyexample.org/

You can run this tutorial again by evaluating:"

ProfStef go.

"Do you want to create your own interactive tutorial with ProfStef? That\'s very easy!!  How ? There\'s a ProfStef interactive tutorial for that :D
Just evaluate the following code:"

ProfStef goOn: HowToMakeYourOwnTutorial

"But, of course, if you are reading this as a Grafoscopio notebook, you will be able to create
other tutorials as interactive notebooks, like this one in a really easy way.

Please explore the next parts of this interactive notebook or go to the Grafoscopio page to learn
more about it: 

http://mutabit.com/grafoscopio/ <~ Spanish page
http://mutabit.com/grafoscopio/index.en.html <~ Engish page

"

"See you soon !"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @720,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														}
													],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Cierre',
													#body : 'Esta parte del tutorial ha introducido la sintaxis y los elementos básicos del lenguaje.
Las lecciones venideras construyen sobre ello y profundizan en Pharo, aplicándolo a
problemas cada vez más complejos y específicos, desde los cuales esperamos puedas
construir tus propias recontextualizaciones y adaptaciones.',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @654,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : GrafoscopioNode {
												#header : 'Arbol principal',
												#key : '',
												#body : '',
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [
													GrafoscopioNode {
														#header : 'Presentación',
														#key : '',
														#body : 'El presente documento tiene como finalidad ayudarte a comprender el funcionamiento básico de Pharo y Grafoscopio.
Se trata de un documento rápido. Para una introducción alternativa a Grafoscopio, su historia, inspiraciones e innovación,
puedes revisar el "Manual de grafoscopio", que está disponible desde el menú  ̀Ayuda ̀ en sus distintos formatos.
Tanto este tutorial como el manual están construyéndose y podrían llegar a integrarse luego en un único documento.

Para navegar este tutorial, si lo estás viendo como un documento interactivo dentro de grafoscopio, 
(si no lo estás viendo así, te recomendamos que lo abras para hacer la experiencia más interactiva)
basta con que hagas click en cada uno de los nodos que aparecen en el árbol lateral izquierdo. 
Dichos nodos pueden contener otros subnodos lo cual se indica por un pequeño triángulo a la izquierda del nombre
del nodo, que puede estar apuntando a la derecha, para indicar que los contenidos del nodo están comprimidos
o hacia abajo, cuando están extendidos.
Para desplegar o contraer los contenidos de un nodo que agrupa a otros, haces click en dicho triángulo.
',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @746,
														#level : 1,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Actos de extrañeza',
														#key : '',
														#body : 'Este tutorial puede lucir un poco extraño, particularmente si no eres programador.
Esto es porque la primera parte es la adaptación de un tutorial para programadores,
que presupone muchos conceptos familiares con la jerga de la programación.
Si eres un programador notarás que, si bien los conceptos son familiares, las maneras
de implementarlos en Smalltalk son distintas y, de hecho más puros y cercanos a las
ideas originales (allí se inició mucho de la computación actual, aunque lo que tenemos
es distinto de lo que se soño).
No te inquietes, iremos explorando y entendiendo con el tiempo esos artefactos extraños, 
y si lees esto como parte de un taller cara a cara (como el Data Week) tendremos tiempo
para conversarlos con mayor detalle.
Además las versiones de este tutorial han cambiado y mejorado con el tiempo, por
lo cual, una versión posterior de grafoscopio y su documentación tendrán mejores
formas de abordar los conceptos.

Por lo pronto te invitamos a que mires este ejercicio de manera casi que etnográfica:
Te aproximarás a un cultura (la de la programación) desde los artefactos prototípicos
que sus pobladores (los programadores) usan, pero en la medida en que lo vayas haciendo
dicha cultura te parecerá menos extraña y ayudarás a construir artefactos menos ajenos, 
que brinden bienvenidas más cálidas y conectadas con personas de culturas más diversas,
como tu.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @746,
														#level : 1,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Agradecimientos',
														#key : '',
														#body : 'Este tutorial es producto del trabajo realizado durante varios talleres en el hackerspace
 [Hackbo](http://hackbo.co) en Bogotá, Colombia, entre ellos:

  - Los talleres de indie web science, ( 1 noviembre de 2014)
  - Los talleres del [Data Week](http://mutabit.com/dataweek) y sus eventos preparatorios y posteriores.

Agradecemos a las personas que asistieron a los talleres y ayudaron con su presencia a probar este material,
Entre ellos: César Augusto Arias, Claudia Baez, Carlos Barreneche, Luis Alejandro Bernal, Fernando Castro, 
Felix Gerlof, Florencia Goldsman, Camilo Hurtado, Luis Linares, Offray Luna, Rafael Medida, Gloria Meneses, 
Fredy Pulido,  Iván Pulido, Sebastian Pulido  y David Salvador.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @746,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													@654,
													GrafoscopioNode {
														#header : 'Intermedio: Scripting',
														#key : '',
														#body : '',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : '"one liners"',
																#key : '',
																#body : 'Estos scripts de una sóla línea (o "casi una" :-P) que fueron tomados de 
[elegant pharo code](https://medium.com/concerning-pharo/elegant-pharo-code-bb590f0856d0#.6kmkvmvre).
Recomendamos que le des una mirada esta excelente entrada de blog com más detalles e
ir completando los ejemplos que iniciamos acá.',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Get the HTML source of a web page',
																		#key : '',
																		#body : '\'http://www.pharo.org\' asUrl retrieveContents
',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @764,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Compute difference in days between two dates',
																		#key : '',
																		#body : '(\'2014-070-01\' asDate - \'2013/2/1\' asDate) days',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @764,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Decimal digit length of 42!',
																		#key : '',
																		#body : '42 factorial decimalDigitLength',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @764,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Set up an HTTP server that returns the current timestamp',
																		#key : '',
																		#body : '(ZnServer startDefaultOn: 8080) 
  onRequestRespond: [ :request | 
    ZnResponse ok: (ZnEntity with: DateAndTime now printString) ]',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @764,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Take an email address and get its respective avatar from Gravatar when exits',
																		#key : '',
																		#body : '| email url |
email := \'Gpmeneses@gmail.com\'.
email trimBoth asLowercase.
(MD5 hashMessage: email trimBoth asLowercase) hex.

url := 
 \'http://www.gravatar.com/avatar/\', 
 (MD5 hashMessage: email trimBoth asLowercase) hex,
 \'.jpg\'.
(ZnEasy getJpeg: url) asMorph openInWindow 
',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @764,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Convert all JPG files in the current directory to PNG format',
																		#key : '',
																		#body : '(FileLocator workingDirectory filesMatching: \'*.jpg\') do: [ :each |
  (each withExtension: \'png\') writeStreamDo: [ :out |
    each readStreamDo: [ :in |
      (PNGReadWriter on: out) nextPutImage: 
        (JPEGReadWriter on: in) nextImage ] ] ]',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @764,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Sum of the primes up to 64',
																		#key : '',
																		#body : '(Integer primesUpTo: 64) sum',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @764,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @761,
																#level : 2,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : '"Few liners" ;-)',
																#key : '',
																#body : 'Estos son otros scripts interesantes que fueron tomados de ejemplos de la comunidad.
Los créditos al autor original están colocados en los comentarios de cada script.',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Composición y escalado de morphs (elementos gráficos)',
																		#key : '',
																		#body : '"Este script toma una image grande, la coloca como fondo y coloca dos morphs simples, un
círculo y un rectángulo escalados sobre ella. Puede tardar un poco en ejecutarse"
| window pane board background scaler|

background := AlphaImageMorph withForm: 
\t(ZnEasy getJpeg: \'http://i.imgur.com/K1QR9vA.jpg\').
background lock.

board := PasteUpMorph new.
board 
color: Color gray;
borderWidth: 3;
borderColor: Color black;
extent: 2000@2000; 
backgroundMorph: background;
addMorph: (CircleMorph new color: Color cyan; position: 41@23; yourself);
addMorph: (Morph new color: Color orange; position: 1200@1200; yourself).

scaler := TransformMorph new.
scaler extent: 1000@1000.
scaler scale: 0.5@0.5.
scaler addMorph: board.

pane := ScrollPane new.
pane scroller addMorph: scaler.

window := pane openInWindow.
window position: 20@20; extent: 420@420.
',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @789,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Traer un avatar asociado a un correo electrónico',
																		#key : '',
																		#body : '| email url |
email := \'gpmeneses@gmail.com\'.
url := \'http://www.gravatar.com/avatar/\', (MD5 hashMessage: email trimBoth asLowercase) hex, \'.jpg\'.
(ZnEasy getJpeg: url) asMorph openInWindow 
',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @789,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Graficar un AST (árbol de sintaxis abstracta)',
																		#key : '',
																		#body : '| ast builder |
ast := RBParser parseExpression: \'self foo. super foo\'.
    builder := RTMondrian new.
    builder shape ellipse size: 15.
    builder nodes: ast allChildren.
    builder edges connectFrom: #parent.
    builder layout tree.
    builder',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @789,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'OSM: Consultar Nominatim',
																		#key : '',
																		#body : '"Thanks to Henrik Nergard"
"Nominatim es un motor de búsqueda para OpenStreetMap. 
Para mayor información sobre este consultar:

http://nominatim.openstreetmap.org/

Este pequeño script extrae resultados de Nominatim y entrega
un polígo que delimita una zona geográfica, reconocida por un nombre, 
por ejemplo \'Teusaquillo\',en Bogotá
"

| baseURL query settings result entries |

query := UIManager default request: \'Find location for\' .

baseURL := \'http://nominatim.openstreetmap.org/search/\'.
settings := \'?format=jsonv2&limit=10\'.

result := MCFileTreeJsonParser parse: (baseURL , query asString, settings) asZnUrl retrieveContents.

(result collect: [ :dct |
\t(dct at: \'display_name\') -> 
\t\t((dct at: \'lat\') asNumber @ (dct at: \'lon\') asNumber)
]) inspect .',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @789,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Lista de las capitales del mundo',
																		#key : '',
																		#body : '"Thanks to Hernán Morales Durand"
((NeoJSONReader fromString: (
    ZnEasy 
        get: \'http://api.geonames.org/countryInfoJSON\'
        username: \'demo\'
        password: \'\') contents) at: #geonames) collect: [ : d | d at: #capital ]',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @789,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Jugando un poco con Open Movie Database',
																		#key : '',
																		#body : 'Veremos cómo consultar la base de datos de Open
Movie Data Base y extraer datos particulares. 

Los ejemplos acá están basados en variaciones de
código provisto por Hernan Morales Durand.',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Afiche de tu película favorita',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Ejemplos',
																						#key : '',
																						#body : '',
																						#tags : '',
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'Blade Runner',
																								#key : '',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Blade Runner\';
        get;
        contents)) at: #Poster))
',
																								#tags : OrderedCollection [
																									'código'
																								],
																								#children : OrderedCollection [ ],
																								#parent : @813,
																								#level : 5,
																								#links : OrderedCollection [
																									''
																								]
																							},
																							GrafoscopioNode {
																								#header : 'Back to the future',
																								#key : '',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Back to the future\';
        get;
        contents)) at: #Poster))
',
																								#tags : OrderedCollection [
																									'código'
																								],
																								#children : OrderedCollection [ ],
																								#parent : @813,
																								#level : 5,
																								#links : OrderedCollection [
																									''
																								]
																							},
																							GrafoscopioNode {
																								#header : 'Ghost in the Shell',
																								#key : '',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'ghost in the shell\';
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @813,
																								#level : 5,
																								#links : OrderedCollection [ ]
																							},
																							GrafoscopioNode {
																								#header : 'Good will hunting',
																								#key : '',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Good will hunting\';
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @813,
																								#level : 5,
																								#links : OrderedCollection [
																									''
																								]
																							},
																							GrafoscopioNode {
																								#header : 'Magnolia',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Magnolia\';
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @813,
																								#level : 5,
																								#links : OrderedCollection [
																									'',
																									'http://ws.stfx.eu/6IAL3JKJRYBU'
																								],
																								#output : @829
																							},
																							GrafoscopioNode {
																								#header : 'Life Is Beautiful',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Life Is Beautiful\';
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @813,
																								#level : 5,
																								#links : OrderedCollection [
																									'',
																									'http://ws.stfx.eu/L27MW66U41R3'
																								],
																								#output : @832
																							}
																						],
																						#parent : @810,
																						#level : 5,
																						#links : OrderedCollection [
																							''
																						]
																					},
																					GrafoscopioNode {
																						#header : 'Deconstruyendo el ejemplo',
																						#key : '',
																						#body : '',
																						#tags : OrderedCollection [
																							'text'
																						],
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'Película con variable',
																								#key : '',
																								#body : '| aTitle |

aTitle := \'Fight club\'.

(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @836,
																								#level : 6,
																								#links : OrderedCollection [ ]
																							},
																							GrafoscopioNode {
																								#header : 'Con bloques para contenidos traer el JSON)',
																								#key : '',
																								#body : '| getJSONString temp myDict |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

temp := getJSONString value: \'Magnolia\'.
temp.
myDict := NeoJSONReader fromString: temp.
"myDict at: #Director."

ZnEasy getJpeg: (myDict at: #Poster)
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @836,
																								#level : 6,
																								#links : OrderedCollection [
																									'',
																									'http://ws.stfx.eu/N002L3K1ZU80'
																								]
																							},
																							GrafoscopioNode {
																								#header : 'Usando dos bloques',
																								#key : '',
																								#body : '| getJSONString movieInfoFromJSONString jsonDataString |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

jsonDataString := getJSONString value: \'Fight club\'.

movieInfoFromJSONString := [ :aJSONString | NeoJSONReader fromString: aJSONString].


ZnEasy getJpeg:((movieInfoFromJSONString value: jsonDataString) at: #Poster)
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @836,
																								#level : 6,
																								#links : OrderedCollection [ ]
																							},
																							GrafoscopioNode {
																								#header : 'Con llaves para diferentes atributos de la peli',
																								#key : '',
																								#body : '| getJSONString movieInfoFromJSONString jsonDataString movieInfoForKey getPoster |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

jsonDataString := getJSONString value: \'E.T.\'.
movieInfoFromJSONString := [ :aJSONString | NeoJSONReader fromString: aJSONString].
movieInfoForKey := [ :aKey | (movieInfoFromJSONString value: jsonDataString) at: aKey ].
movieInfoForKey value: #Actors.
getPoster := [:key | ZnEasy getJpeg:(movieInfoForKey value: key)] value: #Poster
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @836,
																								#level : 6,
																								#links : OrderedCollection [ ]
																							}
																						],
																						#parent : @810,
																						#level : 5,
																						#links : OrderedCollection [
																							''
																						]
																					},
																					GrafoscopioNode {
																						#header : 'Trivia',
																						#body : '',
																						#tags : OrderedCollection [
																							'text'
																						],
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'And the oscar winner is...',
																								#body : '| o i |
o :=  #[76 97 32 76 97 32 76 97 110 100] asString asText.
i := GTInspector openOn: o.
[ 1 second wait.
o
    addAttribute: TextEmphasis struckOut;
    append: #[77 111 111 110 108 105 103 104 116] asString.
i model update ] fork.
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @852,
																								#level : 6,
																								#links : OrderedCollection [
																									'',
																									'http://ws.stfx.eu/6MEJ55EXLSOA'
																								]
																							}
																						],
																						#parent : @810,
																						#level : 5,
																						#links : OrderedCollection [
																							''
																						]
																					}
																				],
																				#parent : @807,
																				#level : 4,
																				#links : OrderedCollection [
																					''
																				]
																			}
																		],
																		#parent : @789,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	}
																],
																#parent : @761,
																#level : 2,
																#links : OrderedCollection [
																	''
																]
															}
														],
														#parent : @746,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'CInemania: Creando el primer paquete',
														#key : '',
														#body : 'Acá tomaremos el ejemplo anterior de Open  Movie Data Base y lo convertiremos en una aplicación.
Esto nos permitirá entender la lógica con la que eso se hace y  "leer" la forma en que otras aplicaciones
están hechas.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Los de Offray',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Crear un nuevo paquete',
																		#key : '',
																		#body : '"Esta es la ventana que nos pide el nombre de un paquete que estamos agregando al sistema"
ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/create-new-package.png\'',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @866,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Paquete recien creado',
																		#key : '',
																		#body : '"Una vez hallamos creado el paquete cinemanía veremos lo siguiente:"

ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/new-package-created.png\'

"Este es el paquete vacio, aún sin ningún objeto en particular"',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @866,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Comentarios de una clase: por llenar',
																		#key : '',
																		#body : '"Recien se crea una clase, aparece un símbolo de admiración al lado izquierdo
de su nombre. Si hacemos click en el botón \'Comments\' podremos indicar el propósito de dicha
clase, como se muestra en la siguiente pantalla"
ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/add-comments.png\'',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @866,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Comentarios de una clase: llenándolos (dirty)',
																		#key : '',
																		#body : '"Reemplazamos la plantilla de comentarios que se nos da por omisión, por alguna descripción de lo que hace el paquete.
Veremos que la esquina superior derecha está resaltada, lo que indica que el comentario aún no se ha salvado,
como muestra esta pantalla"

ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/add-comments-filled.png\'

"y luego salvamos usando Comand S (Mac), Ctrl S (Windows, Gnu/Linux) o el menú"',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @866,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @863,
																#level : 2,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @746,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'Nix: Instalación de software',
														#key : '',
														#body : 'En ocasiones el software que tenemos instalado en nuestra máquina es insuficiente para
realizar la tareas que queremos.
En ese caso, apelamos a sistemas de instalación de paquetes y existen distintos que son 
multiplataforma ([Zero Install]( )) o específicos de ciertas plataformas.
Por ejemplo, en plataformas Gnu/Linux contamos con sistemas como `apt-get` o `pacman`
para gestionar la instalación de software.
Sin embargo, dichos gestores de instalación de software son específicos de una distribución
y sus derivados ( ̀apt-get ̀ funciona para Debian y Ubuntu,  ̀pacman ̀ para Arch y Mnajaro) y
en ocasiones queremos instalar software que no está disponible en nuestra distribución  
o que es inconpatible con las versiones actuales de lo que tenemos instalado
(particularmente para las que manejas ramas, como Debian y sus derivados) o queremos
abstraer el proceso para que no depende de una variante particular de Linux, entre las más
de 300 distribuciones disponibles (ver [Distro Watch]()).
En dichos casos, un gestor de paquetes como Nix nos brinda una alternativa para
despreocuparnos de la distribución subyacente funcionando sobre distintas variantes del
sistema Unix, incluidos Gnu/Linux, Solaris y Mac.

Para mayor información ver:

  - [https://nixos.org/nix/manual/](https://nixos.org/nix/manual/ ).
  - [NixOS](https://nixos.org/ ): The Purely Functional Linux Distribution. Una distribución basada en este gestor de paquetes.
  - [About NixOS](https://nixos.org/nixos/about.html )',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @746,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'Fossil: Colaboración y control de versiones minimalista.',
														#key : '',
														#body : '',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @746,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'Mustache: automatizando la creación de HTML',
														#key : '',
														#body : '',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Instalación',
																#key : '',
																#body : 'Gofer it
   smalltalkhubUser: \'NorbertHartl\' project: \'Mustache\';
   configuration;
   loadStable',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : GrafoscopioNode {
																	#header : 'Mustache: automatizando la creación de HTML',
																	#key : '',
																	#body : Text {
																		#string : '',
																		#runs : RunArray {
																			#runs : [ ],
																			#values : [ ]
																		}
																	},
																	#tags : OrderedCollection [
																		'text'
																	],
																	#children : @893,
																	#parent : GrafoscopioNode {
																		#header : 'twitter.com',
																		#key : '',
																		#body : 'Twitter: La más popular red social de microblogging, basada en comunicación vía
mensajes de un límite de hasta 140 caracteres',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Micrositio Web',
																				#key : '',
																				#body : 'Este nodo explicará como crear un micrositio web para publicar en línea resultados de las
visualizaciones.',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Pecha Kucha',
																						#key : '',
																						#body : 'Para detalles ver: https://github.com/Pharophile/PechaKucha 

Gracias a Philippe Back por esto.',
																						#tags : OrderedCollection [
																							'text'
																						],
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'Cargar soporte para MDL en Seaside',
																								#key : '',
																								#body : 'Metacello new
    githubUser: \'DuneSt\' project: \'MaterialDesignLite\' commitish: \'development\' path: \'src\';
    baseline: \'MaterialDesignLite\';
    onWarningLog;
    load',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @908,
																								#level : 4
																							},
																							GrafoscopioNode {
																								#header : 'Cargar soporte Pecha Kucha',
																								#key : '',
																								#body : 'Metacello new
    githubUser: \'Pharophile\' 
    project: \'PechaKucha\' 
    commitish: \'master\' 
    path: \'packages\';
    baseline: \'PechaKucha\';
    onWarningLog;
    load',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @908,
																								#level : 3
																							},
																							GrafoscopioNode {
																								#header : 'Iniciar la aplicación',
																								#key : '',
																								#body : 'PKApplication declareApplicationAndStartServer.',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @908,
																								#level : 3
																							}
																						],
																						#parent : @905,
																						#level : 3
																					}
																				],
																				#parent : @902,
																				#level : 2
																			},
																			GrafoscopioNode {
																				#header : 'Prototipo Data Selfie',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Básico',
																						#key : '',
																						#body : '"Esto supone que ya se ha descargado y descompreso el archivo de mensajes de Twitter"
| profile aMessagesFile |
profile := TwitterProfileOverview new
\tscreenName: \'offrayLC\'.
profile getAvatar.
aMessagesFile := (FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'DataSelfies\' / \'Twitter\' / \'DataDumps\' / \'offrayLC\' / \'data\' / \'js\' / \'tweets\' /\'2013_02.js\') asFileReference.
profile splitMessagesByTypeFrom: aMessagesFile.
profile avatarWheel ',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @917,
																						#level : 3
																					},
																					GrafoscopioNode {
																						#header : 'Cargar mensajes',
																						#key : '',
																						#body : '"Esto supone que ya se ha descargado y descompreso el archivo de mensajes de Twitter"
| aMessagesFile |
aMessagesFile := (FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'DataSelfies\' / \'Twitter\' / \'DataDumps\' / \'offrayLC\' / \'data\' / \'js\' / \'tweets\' /\'2013_02.js\') asFileReference.
TPMessages new splitMessagesByTypeFrom: aMessagesFile.
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @917,
																						#level : 3
																					}
																				],
																				#parent : @902,
																				#level : 2
																			}
																		],
																		#level : 1
																	},
																	#level : 2
																},
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Crear con moustache el archivo de data selfies',
																#key : '',
																#body : '| workingFolder moustacheTplFile templateContent context rendered targetFile tempStream |

"Ubicación de la plantilla en el sistema de archivos"
workingFolder := FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'TwitterDataSelfies\'..
moustacheTplFile := (workingFolder / \'templates\' / \'index.html\') asFileReference.

"Leer el template como string"
templateContent := moustacheTplFile contents asString.

"Estos datos de contexto deben ser llenados desde Twitter"
context := {
   \'screen_name\' -> \'offrayLC\'.
   \'page_title\' -> \'Mi data selfie de Twitter\'.
   \'bio_message\' -> \'Esto viene de Twitter\'.
   \'url_link\' -> \'http://algo.com\'.
\t\'month\' -> \'2013_02.png\' } asDictionary.

"Procesar la plantilla con los datos de contexto"
rendered := (MustacheTemplate on: templateContent) value: context.

"Guardar el contenido renderizado en un archivo"
targetFile := (workingFolder / \'profiles\' / (context at: #screen_name) / \'index.html\') asFileReference.
tempStream := targetFile writeStream.
tempStream nextPutAll: rendered.
tempStream close.
',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @896,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'http://ws.stfx.eu/1N9FKAUI2UI0',
																#key : '',
																#body : '| profile workingFolder moustacheTplFile templateContent context rendered targetFile tempStream |

profile := TwitterProfileOverview new
\tscreenName: \'LuLinGar\'.

"Ubicación de la plantilla en el sistema de archivos"
workingFolder := FileLocator root / \'media\' / \'hackbo\' / \'memoluis\' / \'dataweek\' / \'repo-dataselfies\'.
moustacheTplFile := (workingFolder / \'templates\' / \'index.html\') asFileReference.

"Leer el template como string"
templateContent := moustacheTplFile contents asString.

"Estos datos de contexto deben ser llenados desde Twitter"
context := {
   \'screen_name\' -> (profile screenName).
   \'page_title\' -> \'Mi data selfie\'.
   \'bio_message\' -> \'Esto viene de Twitter\'.
   \'url_link\' -> \'http://algo.com\' } asDictionary.

"Procesar la plantilla con los datos de contexto"
rendered := (MustacheTemplate on: templateContent) value: context.

"Guardar el contenido renderizado en un archivo"
targetFile := (workingFolder / \'profiles\' / (profile screenName) / \'index.html\') asFileReference.
tempStream := targetFile writeStream.
tempStream nextPutAll: rendered.
tempStream close.
',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @896,
																#level : 3,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @746,
														#level : 1,
														#nodesInPreorder : OrderedCollection [
															@891,
															@894,
															@925,
															@928
														],
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'Teapot: constructor minimalista de aplicaciones web',
														#key : '',
														#body : '',
														#tags : '',
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Minitutorial',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Instalación',
																		#key : '',
																		#body : 'Gofer it
    smalltalkhubUser: \'zeroflag\' project: \'Teapot\';
    configuration;
    loadStable.',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @935,
																		#level : 4,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Hello World',
																		#key : '',
																		#body : 'Teapot on
    GET: \'/welcome\' -> \'Hello World!\';
    start.

"Do it and view at: http://localhost:1701/welcome"',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @935,
																		#level : 4,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Hello User',
																		#key : '',
																		#body : 'Teapot on
    GET: \'/hi\' -> \'Bonjour!\';
    GET: \'/hi/<user>\' -> [:req | \'Hello \', (req at: #user)];
start',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @935,
																		#level : 4,
																		#links : OrderedCollection [
																			''
																		]
																	}
																],
																#parent : GrafoscopioNode {
																	#header : 'Teapot: constructor minimalista de aplicaciones web',
																	#key : '',
																	#body : Text {
																		#string : '',
																		#runs : RunArray {
																			#runs : [ ],
																			#values : [ ]
																		}
																	},
																	#tags : '',
																	#children : @934,
																	#parent : @902,
																	#level : 2
																},
																#level : 3,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Tealight',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Instalación',
																		#key : '',
																		#body : 'Metacello new 
    repository: \'github://astares/Tealight/repository\';
    baseline: \'Tealight\';
    load  ',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @953,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Acceder a un Teapot por omisión',
																		#key : '',
																		#body : 'TLWebserver teapot',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @953,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Definir una ruta para una instancia de Teapot',
																		#key : '',
																		#body : 'TLWebserver teapot 
    GET: \'/hi\' -> \'HelloWorld\'',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @953,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Hola usuario',
																		#key : '',
																		#body : 'TLWebserver teapot 
    GET: \'/hi/<user>\' -> [:req | \'Hello \', (req at: #user)]',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @953,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Transformadores de respuestas',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'A json',
																				#key : '',
																				#body : 'TLWebserver teapot
\tGET: \'/jsonlist\' -> #(1 2 3 4); output: #json',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @968,
																				#level : 5,
																				#links : OrderedCollection [
																					''
																				]
																			},
																			GrafoscopioNode {
																				#header : 'A texto plano',
																				#key : '',
																				#body : 'TLWebserver teapot
\tGET: \'/textoplano\' -> \'Esto es texto plano\'; output: #text',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @968,
																				#level : 5,
																				#links : OrderedCollection [
																					''
																				]
																			},
																			GrafoscopioNode {
																				#header : 'Descargas',
																				#key : '',
																				#body : 'TLWebserver teapot
\tGET: \'/descargas\' -> [\'/tmp/prueba.txt\' asFileReference readStream]; output: #stream',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @968,
																				#level : 5,
																				#links : OrderedCollection [
																					''
																				]
																			}
																		],
																		#parent : @953,
																		#level : 4,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Plantillas',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Instalar soporte Mustache',
																				#key : '',
																				#body : 'Gofer it
   smalltalkhubUser: \'NorbertHartl\' project: \'Mustache\';
   configuration;
   loadStable',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @981,
																				#level : 5,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Usarlas',
																				#key : '',
																				#body : 'TLWebserver teapot
\tGET: \'/saludo\' -> {\'phrase\' -> \'Hello\'. \'name\' -> \'World\'};
\toutput: (TeaOutput mustacheHtml: \'<b>{{phrase}}</b> <i>{{name}}</i>!\')',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @981,
																				#level : 5,
																				#links : OrderedCollection [ ]
																			}
																		],
																		#parent : @953,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Manejo de errores',
																		#key : '',
																		#body : '3',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @953,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Servir archivos locales',
																		#key : '',
																		#body : '<b>Hello</b> <i>World</i>!',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @953,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Mirar procesos de Tealight',
																		#key : '',
																		#body : 'TLWebserver teapot inspect',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @953,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @947,
																#level : 3,
																#links : OrderedCollection [
																	'',
																	'https://github.com/astares/Tealight'
																]
															}
														],
														#parent : @746,
														#level : 1,
														#nodesInPreorder : OrderedCollection [
															@933,
															@935,
															@938,
															@941,
															@944,
															@953,
															@956,
															@959,
															@962,
															@965,
															@968,
															@971,
															@974,
															@977,
															@981,
															@984,
															@987,
															@991,
															@994,
															@997
														],
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Borradores',
														#key : '',
														#body : 'Acá encontrarás código que aún no está tan maduro como el que has visto hasta el momento.
Son algunos apuntes de diferentes prototipos que están avanzando y algún código que no continuo.
Pharo es un entorno dinámico que mejora continuamente.
Al darte una mirada de estos borradores puedes ver parte del proceso de construcción del cierto 
código y vincularte al proceso.

Futuras versiones de este cuaderno interactivo, tendrán ediciones más maduras y robustas del
código.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Visualización de datos',
																#key : '',
																#body : 'Acá están recopilados algunos ejemplos que hemos hecho con data scrapping (raspado de datos)',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Twitter',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Usando algunos scrappers predefinidos',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Ejemplo 1: Un perfil',
																						#key : '',
																						#body : '',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1012,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Ejemplo 2: Dos perfiles',
																						#key : '',
																						#body : '| perfil1 perfil2 perfiles |

perfil1 := TwitterProfile new.
perfil2 := TwitterProfile new.

"Vmmos a crear un nuevo perfil"
perfil1 scrapDataForProfile: \'PetroGustavo\'.
perfil2 scrapDataForProfile: \'JuanManSantos\'.

perfiles := OrderedCollection new.
perfiles 
\tadd: perfil1;
\tadd: perfil2.
perfiles.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1012,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Ejemplo 3: Varios perfiles',
																						#key : '',
																						#body : '| perfil perfiles misPoliticos |

misPoliticos := #(\'PetroGustavo\' "Alcalde de Bogotá"
\t\t\t\t\t\t\'JuanManSantos\' "Presidente de Colombia" 
\t\t\t\t\t\t\'ginaparody\' "Ministra de educación de Colombia"
\t\t\t\t\t\t\'CFKArgentina\' "Presidenta de Argentina").

perfiles := OrderedCollection new.

misPoliticos do: [:politico |
\t  \tperfil := TwitterProfile new.
\t\tperfil scrapDataForProfile: politico.
\t\tperfiles add: perfil.].
perfiles.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1012,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					}
																				],
																				#parent : @1009,
																				#level : 3,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Deconstruyendo un scrapper.',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Traerse el html',
																						#key : '',
																						#body : '\t| client anUrl aProfileName |
\taProfileName := \'dominemosLasTIC\'.
\tanUrl := \'https://twitter.com/\', aProfileName.
\tclient := ZnClient new.
\tclient get: anUrl.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1025,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Encontrar algo dentro del html',
																						#key : '',
																						#body : '\t| client anUrl aProfileName |
\taProfileName := \'dominemosLasTIC\'.
\tanUrl := \'https://twitter.com/\', aProfileName.
\tclient := ZnClient new.
\tclient get: anUrl.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1025,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					}
																				],
																				#parent : @1009,
																				#level : 3,
																				#links : OrderedCollection [ ]
																			}
																		],
																		#parent : @1006,
																		#level : 2,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Contratos públicos',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Visualización Guía: Treemapping',
																				#key : '',
																				#body : 'Para mirar cómo se han realizado los gastos presupuestales, usaremos como visualización guía una que es producida por
la técnica de *treemapping* y que permite explorar cómo una jerarquía está compuesta por partes disyuntas que la conforman
(como en el caso de la división de presupuestos).
Para mayor información sobre dicha técnica véase la 
[página de la wikipedia sobre treemapping](https://en.wikipedia.org/wiki/Treemapping)',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Ejemplo 1',
																						#key : '',
																						#body : '\t| b |
\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color veryLightGray.
\t
\tb from: (1 to: 17) using: [#()].
\tb weight: #yourself.
\tb build.
\t^ b view',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1039,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Ejemplo 2',
																						#key : '',
																						#body : 'RTTreeMapExample new exampleNumber',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1039,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Integrando datos a la visualización',
																						#key : '',
																						#body : '| aFile aCharacter table b |

aFile := (FileLocator documents / \'DataWeek\' / \'query-subtotales-por-segmentos.csv\') asFileReference.
aCharacter := $,.
table := RTTabTable new input: aFile contents usingDelimiter: aCharacter.
table valuesOfColumn: 2.

\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color veryLightGray.
\tb from: (2 to: table numberOfRows) using: [#()].
\tb weight: [:n | (table valuesOfColumn: 2) at: n ].
\tb build.
\tb view.
table values',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1039,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Probando OpenSpending',
																						#key : '',
																						#body : '| contratos archivo |

archivo := (FileLocator documents / \'DataWeek\' / \'query-subtotales-por-segmentos.csv\') asFileReference.
contratos := OpenSpending new.
contratos loadDataFromCSV: archivo usingDelimiter: $,.
contratos',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1039,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Treemap con etiquetas',
																						#key : '',
																						#body : '',
																						#tags : OrderedCollection [
																							'text'
																						],
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'Primera versión',
																								#key : '',
																								#body : '| b labels popup |
\tlabels := RTLabel elementsOn: #(\'uno\' \'dos\' \'tres\' \'cuatro\' \'cinco\').
\tpopup := RTPopup new.
\tpopup text: [:object | labels at: object  ].
\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color random.
\tb from: (1 to: 5) using: [#()].
\tb weight: [:n | n].
\tb build.
\tb view elements @ RTLabelled.
\t^ b view.',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1054,
																								#level : 5,
																								#links : OrderedCollection [ ]
																							},
																							GrafoscopioNode {
																								#header : 'Entendiendo popups dinámicos',
																								#key : '',
																								#body : '',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1054,
																								#level : 5,
																								#links : OrderedCollection [ ]
																							}
																						],
																						#parent : @1039,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					}
																				],
																				#parent : @1036,
																				#level : 3,
																				#links : OrderedCollection [ ]
																			}
																		],
																		#parent : @1006,
																		#level : 2,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @1003,
																#level : 2,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @746,
														#level : 1,
														#links : OrderedCollection [ ]
													}
												],
												#level : 0,
												#nodesInPreorder : OrderedCollection [
													@746,
													@749,
													@753,
													@757,
													@654,
													@658,
													@662,
													@666,
													@670,
													@673,
													@676,
													@679,
													@682,
													@686,
													@690,
													@694,
													@649,
													@645,
													GrafoscopioNode {
														#header : 'Binary',
														#headers : OrderedCollection [ ],
														#key : '',
														#body : '"Los mensajes binarios tienen la forma siguiente:
anObjecto aMessage anotherObject"

3 + 2.

25 * 25.

1 + 1 = 2.

Date today + 3 weeks.

Date today + 3 years.

Date today - 3 years.

false | false.


true | false.


true | true.

false | true.


true & true.

true & false.

10 @ 100.

10 <= 12.


10 >= 12.

\'ab\', \'cd\'.

Date today < Date yesterday.
Date today > Date yesterday.

"Ahora ve a la siguiente lección"',
														#tags : OrderedCollection [
															'código'
														],
														#children : OrderedCollection [ ],
														#parent : @649,
														#level : 3,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Keyword',
														#key : '',
														#body : '"Los mensajes \'keyword\' son mensajes con argumentos. Tienen la siguiente forma:
    anObject akey: anotherObject akey2: anotherObject2"

4 between: 0 and: 5.

"estaEntre(4,0,5)"

"El mensaje lo que nos dice es: si (4) esta entre (0 y 10) cuya respuesta es verdadero, pero si cambio el valor del 0 por 3, el resultado es falso"

1 max: 3.

"determina el valor máximo"

Color r:1 g:0 b:0.

"El mensaje es r:g:b: implementado en la clase Color. Note que también puede escribir"

Color
\tr: 15
\tg: 99
\tb: 100.

\t
"Si quieres usar código RGB usando valores de 0 a 255, como es la práctica usual, deberás
escribirlos como cociente, de forma que sean un número entre 0 y 1. 
Por ejemplo r: x/255 g: y/255 b: z/255, donde x,y,z son los valores entre 0 y 255 correspondientes al código que color que queremos obtener."
\t
"Ahora ve a la siguiente lección"',
														#tags : OrderedCollection [
															'código'
														],
														#children : OrderedCollection [ ],
														#parent : @649,
														#level : 3,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Priority',
														#key : '',
														#body : '"los mensajes unarios son ejectuados primero, los mensajes binarios son ejecutados despues 
y finalmente las cadenas de mensajes:  paréntesis > Unary > Binary > Keywords"

2 negated + (3 raisedTo: 2).

2 + 3 + 4.


2 raisedTo: (3 + 2). 
  
(0@0) class.

0@0 corner: 100@200.

(0@0 corner: 100@200) class.

"entre mensajes de procedencia similar, las expresiones son ejectuadas de izquierda a derecha"

-3 abs negated reciprocal.

"Ahora ve a la siguiente lección"',
														#tags : OrderedCollection [
															'código'
														],
														#children : OrderedCollection [ ],
														#parent : @649,
														#level : 3,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Changing messages priority',
														#key : '',
														#body : '"usar parentesis cambia el orden de evaluación de la sentencia, primero se ejecuta la parte interna() 
y posteriormente la sentencia"

(2 + 3) squared.

(2 raisedTo: 3) + 2.

(0@0 extent: 100@200) bottomRight.

"Ahora ve a la siguiente lección"',
														#tags : OrderedCollection [
															'código'
														],
														#children : OrderedCollection [ ],
														#parent : @649,
														#level : 3,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Mathematical messages priority ',
														#key : '',
														#body : '"Las reglas tradicionales de las matematicas NO aplican dentro de Pharo."

2 * 10 + 2.

"aqui el mensaje por (*) es enviado a dos, corresponde a 20, entonces 20 reciben el mensaje +,

recuerde que todos los mensajes simpre siguen una regla precente de izquierda a derecha, sin excepciones."

2 + 2 * 10. 

2 + (2 * 10). 

(2 * 10) + 2. 

8 - 5 / 2. 

(8 - 5) / 2. 

8-(5/2).

"Ahora ve a la siguiente lección"',
														#tags : OrderedCollection [
															'código'
														],
														#children : OrderedCollection [ ],
														#parent : @649,
														#level : 3,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Cascade messages',
														#key : '',
														#body : '"; es un operador en cascada. Es usado para enviar mensajes al mismo receptor
Abrir un Transcript (consola):"

Transcript open.

"Entonces:"

Transcript show: \'hola\'.
Transcript cr.
Transcript show: \'Pharo\'.


"Es igual a:"

Transcript
\topen; 
\tshow: \'hello\';
\tcr;
show: \'Pharo\'.

"Intenta ir a la siguiente leccion con un cascada de dos mensjaes \'siguiente\'"

"Ahora ve a la siguiente lección"',
														#tags : OrderedCollection [
															'código'
														],
														#children : OrderedCollection [ ],
														#parent : @649,
														#level : 3,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Lección 18: Perdido?',
														#key : '',
														#body : '"Esta era una lección que venía en el viejo tutorial. Fue mantenida para
preservar la numeración. No es necesario hacer nada"

"Ahora ve a la siguiente lección"',
														#tags : OrderedCollection [
															'código'
														],
														#children : OrderedCollection [ ],
														#parent : @649,
														#level : 3,
														#links : OrderedCollection [
															''
														]
													},
													@699,
													@702,
													@705,
													@708,
													@711,
													@716,
													@720,
													@723,
													@726,
													@729,
													@732,
													@735,
													@738,
													@742,
													@761,
													@764,
													@767,
													@770,
													@773,
													@776,
													@779,
													@782,
													@785,
													@789,
													@792,
													@795,
													@798,
													@801,
													@804,
													@807,
													@810,
													@813,
													@815,
													@819,
													@823,
													@826,
													@829,
													@832,
													@836,
													@839,
													@842,
													@845,
													@848,
													@852,
													@855,
													@863,
													@866,
													@869,
													@872,
													@875,
													@878,
													@883,
													@887,
													@891,
													@894,
													@925,
													@928,
													@933,
													@935,
													@938,
													@941,
													@944,
													@953,
													@956,
													@959,
													@962,
													@965,
													@968,
													@971,
													@974,
													@977,
													@981,
													@984,
													@987,
													@991,
													@994,
													@997,
													@1003,
													@1006,
													@1009,
													@1012,
													@1015,
													@1018,
													@1021,
													@1025,
													@1028,
													@1031,
													@1036,
													@1039,
													@1042,
													@1045,
													@1048,
													@1051,
													@1054,
													@1057,
													@1060
												]
											},
											#level : 1,
											#links : OrderedCollection [ ]
										},
										#level : 2,
										#links : OrderedCollection [
											''
										]
									},
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								@1069,
								@1074,
								@1078,
								@1082,
								@1086,
								@1090
							],
							#parent : @639,
							#level : 2,
							#nodesInPreorder : OrderedCollection [
								@642,
								@645,
								@1069,
								@1074,
								@1078,
								@1082,
								@1086,
								@1090,
								@1094
							],
							#links : @1099
						},
						GrafoscopioNode {
							#header : 'Blocks',
							#key : '',
							#body : '"For this part a Basic understanding of Basic Types is recommended.
If you have not done that part yet, please go to that subtree and run the code there"
"Ahora hablemos de los bloques.
Piensa en los bloques como una manera de \'congelar\' código que luego podremos ejecutar por demanda,
cuando queramos y/o las condiciones para su ejecución se cumplan.
Los bloques son métodos anónimos, lo cual quiere decir que no es necesario ponerles nombres para invocarlos
(como ocurre con las operaciones sobre objetos que hemos visto hasta el momento) y
pueden pueden ser almacenados en variables.
Los bloques están delimitados por paréntesis cuadrados: []"

[ProfStef openPharoZenWorkspace].

"El bloque anterior no abre el Zen de Pharo, porque el bloque, por omisión, no es ejecutado.
Ahora ejecuta:"

[ProfStef openPharoZenWorkspace] value.

"Acá hay otro bloque que suma 2 a su argumento (su argumento se llama x):"

[:x | x+2].

"Los argumentos, son las variables internas de los bloques, están precedidas por \':\' 
y la barra vertical \'|\' separa la parte en que se definen los argumentos, de la parte en que se dice
que hacer con ellos."

"Podemos ejecutar un bloque enviandole mensajes \'value\' "

[:y | y/2 asFloat] value: 5.

[Nautilus open] value.

[:x | x+2] value: 10.

"Podemos tener además bloques que reciban varios argumentos, por ejemplo:"

[:y :x | x - y] value:3 value:5.

"Ahora ve a la siguiente lección"',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [ ],
							#parent : @639,
							#level : 2,
							#nodesInPreorder : OrderedCollection [
								@1102
							],
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Blocks assignment',
							#key : '',
							#body : '"Los bloques pueden ser asignados a variables y ejecutados después.

Note que |b| es la declaración de una variable llamada \'b\' y que \':=\' asigna un valor a una variable.

Selecciona las siguientes tres líneas e imprimelas (Print it)" 

| b |

[:x | x+2] value: 20.


b := [:x | x+2].


b value: 20. 


"Ahora ve a la siguiente lección"',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [ ],
							#parent : @639,
							#level : 2,
							#nodesInPreorder : OrderedCollection [
								@1107
							],
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Conditionals',
							#key : '',
							#body : '"Los condicionales son sólo menajes enviados a objetos Boolean (booleanos)"

1 < 2
  ifTrue: [Transcript show: \'Es cierto\']
  ifFalse: [Transcript show: \'Es falso\'].

"Aquí el mensajes es ifTrue:ifFalse

Prueba esto:"

Transcript open. 

3 > 10 
\tifTrue: [Transcript show: \'Quizás hay un error ....\']
\tifFalse: [Transcript show: \'No: 3 es menor que 10\']. 

3=3 ifTrue: [ProfStef openPharoZenWorkspace].

"Ahora ve a la siguiente lección"',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [ ],
							#parent : @639,
							#level : 2,
							#nodesInPreorder : OrderedCollection [
								@1112
							],
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Cycles & Iterators',
							#key : '',
							#body : '"Los ciclos con iteradores de alto nivel sobre las colecciones, implementados como métodos regulares."

"Ciclos básicos:
  to: do:
  to:by:do"

1 to: 10.

1 to: 10 do:
  [:i | Transcript show: i*2  "asString"; cr ]. 

1 to: 20 by: 3 do: [:i | Transcript show: i asString; cr].

30 to: 0 by: -2 do: 
    [:i | Transcript show: i asString; cr].

"Ahora ve a la siguiente lección"',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : '¿Qué hacer cuando necesito tanto el índice como el objeto?',
									#key : '',
									#body : '"doWithIndex permite trabajar con los objetos y con su índice, es decir tener bloques
que reciben dos argumentos"
| colors |

colors := OrderedCollection new.
colors 
\tadd:(Color r: 1 g: 0 b: 0);
\tadd:(Color r: 0 g: 1 b: 0);
\tyourself.
colors doWithIndex: [ :color :i | Transcript show: \'El color número \', i asString, \' es: \', color name asString; cr ]

',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : GrafoscopioNode {
										#header : 'Lección22: Ciclos e Iteradores',
										#key : '',
										#body : '"Los ciclos con iteradores de alto nivel sobre las colecciones, implementados como métodos regulares."

"Ciclos básicos:
  to: do:
  to:by:do"

1 to: 10.

1 to: 15 do:
  [:i | Transcript show: i*2  "asString"; cr ]. 

1 to: 20 by: 3 do: [:i | Transcript show: i asString; cr].

30 to: 0 by: -2 do: 
    [:i | Transcript show: i asString; cr].

"Ahora ve a la siguiente lección"',
										#tags : @1118,
										#children : @1119,
										#parent : GrafoscopioNode {
											#header : 'Introductorio: Professor Stef',
											#headers : OrderedCollection [
												'Tutorial 1',
												'Tutorial 2',
												'Tutorial 3',
												'Tutorial 4',
												'Tutorial 5.',
												'Tutorial 6',
												'Tutorial 7',
												'Tutorial 8',
												'Tutorial 9',
												'Tutorial 10',
												'Tutorial 11'
											],
											#key : '',
											#body : 'Este tutorial mostrará los aspectos básicos de la sintaxis de Smalltalk y está basado
en el tutorial ProfStef que viene integrado a Pharo, pero convertido en un cuaderno
interactivo de Grafoscopio.
Está separado por lecciones. que vienen numeradas y en ocasiones están agrupadas.
Para ver el contenido particular de una lección se debe hacer click en ella en el árbol
lateral a la izquierda.
Si están agrupadas, se verá un triangulito en el título que las agrupa.
Al hacer click en él, se mostrarán los contenidos del mismo, que podremos seguir
explorando con la misma lógica.
',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Lección 1: Bienvenida',
													#headers : OrderedCollection [ ],
													#key : '',
													#body : '"Hola!, Soy el profesor Stef. Debes querer que te ayude a aprender 
Pharo. Así que vamos a la primera lección: aprender a ejecutar código. 
Para ello hay varias opciones:
  - Opción 1: Selecciona el texto debajo, o coloca el cursor luego del punto, dale clic 
    derecho y selecciona \'do it (d)\'
  - Opción 2: Haz click en el botón con el ícono de play que aparece justo cerca a la 
    esquina superior derecha de este panel"

ProfStef  openPharoZenWorkspace 

',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @1124,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 2: Haciendo',
													#headers : OrderedCollection [ ],
													#key : '',
													#body : '"Excelente! (quise decir Súper)). Acabas de ejecutar una expresión de Pharo. Más precisamente,
enviaste el mensaje \'next\' a PharoTutorial class (¡soy yo!).

Nota que puedes correr este tutorial nuevamente evaluado \'PharoTutorial go\'.
\'PharoTutorial previous\' te devolverá a la lección anterior.

También puedes ejecutar \'Do it\' usando el comando de teclado \'ALT d\' (esto cambia de acuerdo a 
tu sistema operativo/computador: puede ser \'CMD d\' o \'CTRL d\').

Trata de evaluar las siguientes expresiones:"

Nautilus open.

SmalltalkImage current aboutThisSystem.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @1124,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 3: Imprimiendo',
													#headers : OrderedCollection [ ],
													#key : '',
													#body : '"Now you\'re a Do It master ! Let\'s talk about printing. 
It\'s a Do It which prints the result next to the expression you\'ve selected.
For example, select the text below, open the menu and click on \'print it (p)\':"

1 + 2.

"You\'ve seen the letter \'p\' between parentheses next to \'print it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

Try ALT-p (or CMD-p or CTRL-p) on the following expressions:"

Date today.

Time now.

"The result is selected, so you can erase it using the backspace key. Try it !"

SmalltalkImage current datedVersion.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @1124,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 4: Inspeccionando',
													#key : '',
													#body : '"Now you\'re a Do It and Print It master ! Let\'s talk about inspecting. 
It\'s a Do It which opens an Inspector on the result of evaluating the expression you\'ve selected. 
The Inspector is a tool that allows you to have a look inside an object.

For example, select the text below, open the menu and click on \'inspect it (i)\':"

1 / 2.

"You\'ve seen the letter \'i\' between parentheses next to \'inspect it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

You can use Ctrl+g to get and embedded inspector.

Try ALT-i (or CMD-i or CTRL-i) on the following expressions:"

DateAndTime today.

Float pi.

SystemVersion current.

"Ahora ve a la siguiente lección"',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @1124,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Tipos básicos',
													#key : '',
													#body : '',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'Lección 5: Números',
															#key : '',
															#body : '"You now know how to execute Pharo code. 

Now let\'s talk about basic objects.

1, 2, 100, 2/3 ... are Numbers, and respond to many messages evaluating mathematical expressions.
Evaluate these ones:"

2.

20 factorial.

1000 factorial / 999 factorial.

(1/3).

(1/3) + (4/5).

(1/3) asFloat.

1 class.

1 class maxVal class.

.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1143,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 6: Caracteres',
															#key : '',
															#body : '"Un caracter puede ser instanciado usando el operador $"

$A.

$A class.

$@ charCode.

Character cr.

Character space.

"Puedes imprimir todos los 256 caracteres del código extendido ASCII"

Character allByteCharacters.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1143,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 7: Cadenas',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Un String o cadena es una colección de caracteres. 
Usa comillas simples para crear un objeto String. 
Imprime estas expresiones"

\'a\' class.

$a class.

\'PharoTutorial\'.

\'PharoTutorial\' size.

\'abc\' asUppercase.

\'NO more Hello World!\' reverse.

\'Adan no calla con nada\' reverse.

\'Anita lava la tina\' reverse.

"Puedes acceder a cada caracter usando \'at:mensaje\'"

\'PharoTutorial\' at:6.

"La concatenación de String usa el operador coma:"

[\'PharoTutorial\', \' is cool\']. "versión cambiada"

\'Pharo tutorial \', \' is cool\', \' when i active the code \'.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1143,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 8: Símbolos',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Un \'Symbol\' es un String único globalmente.

Hay uno y solo un Symbol #PharoTutorial. Pueden existir varios objetos String \'PharoTutorial\'

(Message=retorna \'true\' si los dos objetos son IGUALES)"

\'PharoTutorial\' asSymbol.

#PharoTutorial asString.

"Notra: En mátemáticas hay dos tipos de igualdad:

x = 3 <- Aginación. A la variable x, le estamos asignando el valor 3.
2 = 3 <- Comparación: dados dos elementos conocidos decir si es o no el mismo.

Para Smalltalk es:

x := 3. <- Aginación.
2 = 3 <- Comparación.
a == a <- Comparación fuerte. Se trata del mismo símbolo?
"

\'PharoTutorial\' = \'PharoTutorial\'.
\'PharoTutorial\' == \'PharoTutorial\'.

#PharoTutorial = \'PharoTutorial\'.
#PharoTutorial == \'PharoTutorial\'.

(2 asString) == (2 asString).


(2 asString) asSymbol == (2 asString) asSymbol.


"Ahora ve a la siguiente lección"
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1143,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 9: Arreglos',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Los arreglos son maneras de guardar información información diversa.
Los hay de dos tipos, estáticos y dinámicos. Acá veremos los primeros"
#(1 2 3).

#( 1 2 3 #(4 5 6)) size.

#(1 2 4) isEmpty.

#(1 2 3) first.

#(\'hello\' \'World\') 
    at: 2 put: \'Pharo\'; 
   yourself.
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1143,
															#level : 3,
															#links : OrderedCollection [
																'',
																'http://ws.stfx.eu/7FXPZYUXWU54'
															]
														},
														GrafoscopioNode {
															#header : 'Lección 10: Arreglos dinámicos',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Los arreglos dinámicos son creados durante el tiempo de ejecución, es decir que podemos
guardar en ellos cálculos que luego se ejecutarán y determinarán lo que en ellos se guarda"

{ (2+3).(6*6) }.

"Comparemos este arreglo estático"

#( (2+3)  (6+6)  \'hello\' , \'Stef\') size.  

"con este arreglo dinámico:"

{ (2+3) . (6+6) . \'hello\' , \'Stef\' } size.

"Ahora ve a la siguiente lección"
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1143,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														}
													],
													#parent : @1124,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Mensajes',
													#key : '',
													#body : '',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'Lección 11:  Unarios',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Los mensajes son enviados a objetos. 
Hay tres tipos de mensajes: unary (unarios), binary (binary) y keyword.

Los mensajes unarios tienen la forma siguiente.

anObject aMessage

Tu ya has enviado mensajes unarios. Por ejemplo:"

1 class.
#b class.

$b class.

true not.

false not.

Time now.

Date today.

Date yesterday.

Date tomorrow.

Float pi.

"Ahora ve a la siguiente lección"
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1169,
															#level : 3,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Lección 12: Binarios',
															#headers : OrderedCollection [ ],
															#key : '',
															#body : '"Los mensajes binarios tienen la forma siguiente:
anObjecto aMessage anotherObject"

3 + 2.

25 * 25.

1 + 1 = 2.

Date today + 3 weeks.

Date today + 3 years.

Date today - 3 years.

false | false.


true | false.


true | true.

false | true.


true & true.

true & false.

10 @ 100.

10 <= 12.


10 >= 12.

\'ab\', \'cd\'.

Date today < Date yesterday.
Date today > Date yesterday.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1169,
															#level : 3,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Lección 13: keywords',
															#key : '',
															#body : '"Los mensajes \'keyword\' son mensajes con argumentos. Tienen la siguiente forma:
    anObject akey: anotherObject akey2: anotherObject2"


4 between: 0 and: 5.

"El mensaje lo que nos dice es: si (4) esta entre (0 y 10) cuya respuesta es verdadero, pero si cambio el valor del 0 por 3, el resultado es falso"

1 max: 3.

"determina el valor máximo"

Color r:1 g:0 b:0.

"El mensaje es r:g:b: implementado en la clase Color. Note que también puede escribir"

Color
\tr: 15
\tg: 99
\tb: 100.

\t
"Si quieres usar código RGB usando valores de 0 a 255, como es la práctica usual, deberás
escribirlos como cociente, de forma que sean un número entre 0 y 1. 
Por ejemplo r: x/255 g: y/255 b: z/255, donde x,y,z son los valores entre 0 y 255 correspondientes al código que color que queremos obtener."
\t
"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1169,
															#level : 3,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Lección 14: Prioridad',
															#key : '',
															#body : '"los mensajes unarios son ejectuados primero, los mensajes binarios son ejecutados despues 
y finalmente las cadenas de mensajes:  paréntesis > Unary > Binary > Keywords"

2 + 3 raisedTo: 2.

2 + 3 + 4.


2 raisedTo: (3 + 2). 
  
(0@0) class.

0@0 corner: 100@200.

(0@0 corner: 100@200) class.

"entre mensajes de procedencia similar, las expresiones son ejectuadas de izquierda a derecha"

-3 abs negated reciprocal.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1169,
															#level : 3,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Lección 15: Cambiar prioridad de los mensajes',
															#key : '',
															#body : '"usar parentesis cambia el orden de evaluación de la sentencia, primero se ejecuta la parte interna() 
y posteriormente la sentencia"

(2 + 3) squared.

(2 raisedTo: 3) + 2.

(0@0 extent: 100@200) bottomRight.

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1169,
															#level : 3,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Lección 16: Prioridad de los mensajes matemáticos',
															#key : '',
															#body : '"Las reglas tradicionales de las matematicas NO aplican dentro de Pharo."

2 * 10 + 2.

"aqui el mensaje por (*) es enviado a dos, corresponde a 20, entonces 20 reciben el mensaje +,

recuerde que todos los mensajes simpre siguen una regla precente de izquierda a derecha, sin excepciones."

2 + 2 * 10. 

2 + (2 * 10). 

(2 * 10) + 2. 

8 - 5 / 2. 

(8 - 5) / 2. 

8-(5/2).

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1169,
															#level : 3,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Lección 17: Mensajes en cascada',
															#key : '',
															#body : '"; es un operador en cascada. Es usado para enviar mensajes al mismo receptor
Abrir un Transcript (consola):"

Transcript open.

"Entonces:"

Transcript show: \'hola\'.
Transcript cr.
Transcript show: \'Pharo\'.


"Es igual a:"

Transcript 
\t   show: \'hello\';
\t   cr;
\t   show: \'Pharo\'.

"Intenta ir a la siguiente leccion con un cascada de dos mensjaes \'siguiente\'"

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1169,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 18: Perdido?',
															#key : '',
															#body : '"Esta era una lección que venía en el viejo tutorial. Fue mantenida para
preservar la numeración. No es necesario hacer nada"

"Ahora ve a la siguiente lección"',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @1169,
															#level : 3,
															#links : OrderedCollection [ ]
														}
													],
													#parent : @1124,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Lección 19: Bloques',
													#key : '',
													#body : '"Los mensajes en cascada son chéveres. Ahora hablemos de los bloques.
Los bloques son métodos anónimos que pueden ser almacenados en variables y ejecutados por demanda.

Los bloques están delimitados por paréntesis cuadrados: []"

[Nautilus open].

"No abre un Nautilus porque el bloque no es ejecutado.

Acá hay otro bloque que suma 2 a su argumento (su argumento se llama x):"

[:x | x+2].

"Podemos ejecutar un bloque enviandole mensajes \'value\' "
[:x | x+2] value: 5.

[Nautilus open] value.

[:x | x+2] value: 10.

[:x :y | x - y] value:3 value:5.

"Ahora ve a la siguiente lección"',
													#tags : @1103,
													#children : @1104,
													#parent : @1124,
													#level : 2,
													#links : @1106
												},
												GrafoscopioNode {
													#header : 'Lección 20: Asignación de Bloques',
													#key : '',
													#body : '"Los bloques pueden ser asignados a variables y ejecutados después.

Note que |b| es la declaración de una variable llamada \'b\' y que \':=\' asigna un valor a una variable.

Selecciona las siguientes tres líneas e imprimelas (Print it)" 

| b |

[:x | x+2] value: 20.


b := [:x | x+2].


b value: 20. 


"Ahora ve a la siguiente lección"',
													#tags : @1108,
													#children : @1109,
													#parent : @1124,
													#level : 2,
													#links : @1111
												},
												GrafoscopioNode {
													#header : 'Lección 21: Condicionales',
													#key : '',
													#body : '"Los condicionales son sólo menajes enviados a objetos Boolean (booleanos)"

1 < 2
  ifTrue: [Transcript show: \'Es cierto\']
  ifFalse: [Transcript show: \'Es falso\'].

"Aquí el mensajes es ifTrue:ifFalse

Prueba esto:"

Transcript open. 

3 > 10 
\tifTrue: [Transcript show: \'Quizás hay un error ....\']
\tifFalse: [Transcript show: \'No: 3 es menor que 10\']. 

3=3 ifTrue: [ProfStef openPharoZenWorkspace].

"Ahora ve a la siguiente lección"',
													#tags : @1113,
													#children : @1114,
													#parent : @1124,
													#level : 2,
													#links : @1116
												},
												@1123,
												GrafoscopioNode {
													#header : 'Lección 23: Colecciones',
													#key : '',
													#body : '"El mensaje do: es enviado a una colección de objetos (Array, Set, OrderedCollection),
evaluando el bloque para cada elemento.

Acá queremos imprimir todos los números sobre el Transcript (una consola)"

| miColeccion |

#(11 38 3 -2 10) do: [:each |
     Transcript show: each*2; cr].

"Some other really nice iterators"

miColeccion := #(11 38 3 -2 10) collect: [:each | each abs].

#(11 38 3 -2 10) collect: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each >= 10].  

#(11 38 3 -2 10) reject: [:each | each > 10]. 

#(11 38 3 -2 10) 
     do: [:each | Transcript show: each printString]
     separatedBy: [Transcript show: \'.\'].

#(11 38 3 -2 10) detect: [ :el | el = 0 ] 
\tifFound: [ Transcript show: \'Encontrado\' ]
 \tifNone: [  ^ nil ]

"Ahora ve a la siguiente lección"',
													#tags : OrderedCollection [
														'código'
													],
													#children : OrderedCollection [ ],
													#parent : @1124,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Opcional',
													#key : '',
													#body : Text {
														#string : 'Las siguientes lecciones son algo más avanzadas y referidas a elementos  de interfaces gráficas
(botones, morphs) y cambios en caliente en los métodos de Smalltalk.
Si bien son importantes, las exploraremos con detalle en otros lugares, así que puedes
pasar al cierre de este tutorial y luego ir  a otros nodos como los de
código elegante en Pharo y otros ejemplos minimalistas para terminar en los distintos
proyectos del nodo titulado "Visualización de datos".',
														#runs : RunArray {
															#runs : [
																467
															],
															#values : [
																[ ]
															],
															#lastIndex : 1,
															#lastRun : 1,
															#lastOffset : 0
														}
													},
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'Buttons example',
															#key : '',
															#body : '"Los objetos son instancias de sus clases. Usualmente, enviamos el mensaje #new a una clase
para crear una instancia de esta clase.

El mensaje #allInstances enviado a una clase, responde un arreglo con todas las instancias de esta clase.

Por ejemplo, miremos cuántas instancias de SimpleButtonMorph existen, imprimiendo la siguiente línea:"

SimpleButtonMorph allInstances size.

"Ahora creemos una nueva instancia de él"

SimpleButtonMorph new
\tlabel: \'Un agradable botón\';
\topenCenteredInWorld.

"Ves el botón centrado en el mundo? La lista de todas las instancias debería contener una instancia más:"

SimpleButtonMorph allInstances size.

"Juguemos con él:"

SimpleButtonMorph allInstances last 
\tlabel: \'El Tutorial de Pharo es cheeevere !\';
\tcolor: Color cyan.
\t
"Borrémosla y pidámosle al sistema limpiar la memoria:"

SimpleButtonMorph allInstances last delete.
Smalltalk garbageCollect.
SimpleButtonMorph allInstances size.

"Haz click sobre el botón para ir a la siguiente lección:"

SimpleButtonMorph new
\tlabel: \'Go to next lesson\';
\ttarget: [ProfStef next. 
\t\t\tSimpleButtonMorph allInstances last delete];
\tactionSelector: #value;
\topenCenteredInWorld.
\t
"Ahora ve a la siguiente lección"',
															#tags : OrderedCollection [
																'código'
															],
															#children : OrderedCollection [ ],
															#parent : @1206,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Chaning a live running system',
															#key : '',
															#body : '"Puedes inspeccionar y cambiar el sistema en tiempo de ejecución.

Mira el código fuente del método #ifFalse:ifTrue: de la clase True:"

(True>>#ifFalse:ifTrue:) definition.

"O sólo su comentario:"

(True>>#ifFalse:ifTrue:) comment.

"Acá están todos los métodos que implementa el ProfStef, base de este notebook:"

ProfStef selectors.

"Creemos un nuevo método para ir a la siguiente lección:"

ProfStef class compile:\'goToNextLesson
  self next\'.

"Wow! No puedo esperar a usar mi nuevo método!"

"Ahora ve a la siguiente lección"',
															#tags : OrderedCollection [
																'código'
															],
															#children : OrderedCollection [ ],
															#parent : @1206,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Cleaning methods',
															#key : '',
															#body : '"Tan chévere, ¿no? Antes de ir más allá, removamos este método:"

ProfStef respondsTo: #goToNextLesson.

ProfStef class removeSelector: #goToNextLesson.

ProfStef respondsTo: #goToNextLesson.

"Ahora mover hacia adelante"



"Ahora ve a la siguiente lección"',
															#tags : OrderedCollection [
																'código'
															],
															#children : OrderedCollection [ ],
															#parent : @1206,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Exploring objects',
															#key : '',
															#body : '"Pharo is full of objects. There are windows, text, numbers, dates, colors, points and much more. You can interact with objects in a much more direct way than is possible with other programming languages.

Every object understands the message \'explore\'. As a result, you get an Explorer window that shows details about the object."

Date today explore.

"This shows that the date object consists of a point in time (start) and a duration (one day long)."

ProfStef explore.

"You see,  class has a lot of objects. Let\'s take a look at my code:"

ProfStef browse.

"Ahora ve a la siguiente lección"',
															#tags : OrderedCollection [
																'código'
															],
															#children : OrderedCollection [ ],
															#parent : @1206,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Lección 28',
															#body : '',
															#tags : OrderedCollection [
																'código'
															],
															#children : OrderedCollection [ ],
															#parent : @1206,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Making your own tutorials',
															#body : '"This tutorial is done. Enjoy programming with Pharo. 

Don\'t forget to read \'Pharo By Example\' found here:  

\thttp://pharobyexample.org/

You can run this tutorial again by evaluating:"

ProfStef go.

"Do you want to create your own interactive tutorial with ProfStef? That\'s very easy!!  How ? There\'s a ProfStef interactive tutorial for that :D
Just evaluate the following code:"

ProfStef goOn: HowToMakeYourOwnTutorial

"But, of course, if you are reading this as a Grafoscopio notebook, you will be able to create
other tutorials as interactive notebooks, like this one in a really easy way.

Please explore the next parts of this interactive notebook or go to the Grafoscopio page to learn
more about it: 

http://mutabit.com/grafoscopio/ <~ Spanish page
http://mutabit.com/grafoscopio/index.en.html <~ Engish page

"

"See you soon !"',
															#tags : OrderedCollection [
																'código'
															],
															#children : OrderedCollection [ ],
															#parent : @1206,
															#level : 3,
															#links : OrderedCollection [
																''
															]
														}
													],
													#parent : @1124,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Cierre',
													#body : 'Esta parte del tutorial ha introducido la sintaxis y los elementos básicos del lenguaje.
Las lecciones venideras construyen sobre ello y profundizan en Pharo, aplicándolo a
problemas cada vez más complejos y específicos, desde los cuales esperamos puedas
construir tus propias recontextualizaciones y adaptaciones.',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @1124,
													#level : 2,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : GrafoscopioNode {
												#header : 'Arbol principal',
												#key : '',
												#body : '',
												#tags : OrderedCollection [
													'text'
												],
												#children : OrderedCollection [
													GrafoscopioNode {
														#header : 'Presentación',
														#key : '',
														#body : 'El presente documento tiene como finalidad ayudarte a comprender el funcionamiento básico de Pharo y Grafoscopio.
Se trata de un documento rápido. Para una introducción alternativa a Grafoscopio, su historia, inspiraciones e innovación,
puedes revisar el "Manual de grafoscopio", que está disponible desde el menú  ̀Ayuda ̀ en sus distintos formatos.
Tanto este tutorial como el manual están construyéndose y podrían llegar a integrarse luego en un único documento.

Para navegar este tutorial, si lo estás viendo como un documento interactivo dentro de grafoscopio, 
(si no lo estás viendo así, te recomendamos que lo abras para hacer la experiencia más interactiva)
basta con que hagas click en cada uno de los nodos que aparecen en el árbol lateral izquierdo. 
Dichos nodos pueden contener otros subnodos lo cual se indica por un pequeño triángulo a la izquierda del nombre
del nodo, que puede estar apuntando a la derecha, para indicar que los contenidos del nodo están comprimidos
o hacia abajo, cuando están extendidos.
Para desplegar o contraer los contenidos de un nodo que agrupa a otros, haces click en dicho triángulo.
',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @1243,
														#level : 1,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Actos de extrañeza',
														#key : '',
														#body : 'Este tutorial puede lucir un poco extraño, particularmente si no eres programador.
Esto es porque la primera parte es la adaptación de un tutorial para programadores,
que presupone muchos conceptos familiares con la jerga de la programación.
Si eres un programador notarás que, si bien los conceptos son familiares, las maneras
de implementarlos en Smalltalk son distintas y, de hecho más puros y cercanos a las
ideas originales (allí se inició mucho de la computación actual, aunque lo que tenemos
es distinto de lo que se soño).
No te inquietes, iremos explorando y entendiendo con el tiempo esos artefactos extraños, 
y si lees esto como parte de un taller cara a cara (como el Data Week) tendremos tiempo
para conversarlos con mayor detalle.
Además las versiones de este tutorial han cambiado y mejorado con el tiempo, por
lo cual, una versión posterior de grafoscopio y su documentación tendrán mejores
formas de abordar los conceptos.

Por lo pronto te invitamos a que mires este ejercicio de manera casi que etnográfica:
Te aproximarás a un cultura (la de la programación) desde los artefactos prototípicos
que sus pobladores (los programadores) usan, pero en la medida en que lo vayas haciendo
dicha cultura te parecerá menos extraña y ayudarás a construir artefactos menos ajenos, 
que brinden bienvenidas más cálidas y conectadas con personas de culturas más diversas,
como tu.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @1243,
														#level : 1,
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Agradecimientos',
														#key : '',
														#body : 'Este tutorial es producto del trabajo realizado durante varios talleres en el hackerspace
 [Hackbo](http://hackbo.co) en Bogotá, Colombia, entre ellos:

  - Los talleres de indie web science, ( 1 noviembre de 2014)
  - Los talleres del [Data Week](http://mutabit.com/dataweek) y sus eventos preparatorios y posteriores.

Agradecemos a las personas que asistieron a los talleres y ayudaron con su presencia a probar este material,
Entre ellos: César Augusto Arias, Claudia Baez, Carlos Barreneche, Luis Alejandro Bernal, Fernando Castro, 
Felix Gerlof, Florencia Goldsman, Camilo Hurtado, Luis Linares, Offray Luna, Rafael Medida, Gloria Meneses, 
Fredy Pulido,  Iván Pulido, Sebastian Pulido  y David Salvador.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @1243,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													@1124,
													GrafoscopioNode {
														#header : 'Intermedio: Scripting',
														#key : '',
														#body : '',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : '"one liners"',
																#key : '',
																#body : 'Estos scripts de una sóla línea (o "casi una" :-P) que fueron tomados de 
[elegant pharo code](https://medium.com/concerning-pharo/elegant-pharo-code-bb590f0856d0#.6kmkvmvre).
Recomendamos que le des una mirada esta excelente entrada de blog com más detalles e
ir completando los ejemplos que iniciamos acá.',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Get the HTML source of a web page',
																		#key : '',
																		#body : '\'http://www.pharo.org\' asUrl retrieveContents
',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1261,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Compute difference in days between two dates',
																		#key : '',
																		#body : '(\'2014-070-01\' asDate - \'2013/2/1\' asDate) days',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1261,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Decimal digit length of 42!',
																		#key : '',
																		#body : '42 factorial decimalDigitLength',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1261,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Set up an HTTP server that returns the current timestamp',
																		#key : '',
																		#body : '(ZnServer startDefaultOn: 8080) 
  onRequestRespond: [ :request | 
    ZnResponse ok: (ZnEntity with: DateAndTime now printString) ]',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1261,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Take an email address and get its respective avatar from Gravatar when exits',
																		#key : '',
																		#body : '| email url |
email := \'Gpmeneses@gmail.com\'.
email trimBoth asLowercase.
(MD5 hashMessage: email trimBoth asLowercase) hex.

url := 
 \'http://www.gravatar.com/avatar/\', 
 (MD5 hashMessage: email trimBoth asLowercase) hex,
 \'.jpg\'.
(ZnEasy getJpeg: url) asMorph openInWindow 
',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1261,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Convert all JPG files in the current directory to PNG format',
																		#key : '',
																		#body : '(FileLocator workingDirectory filesMatching: \'*.jpg\') do: [ :each |
  (each withExtension: \'png\') writeStreamDo: [ :out |
    each readStreamDo: [ :in |
      (PNGReadWriter on: out) nextPutImage: 
        (JPEGReadWriter on: in) nextImage ] ] ]',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1261,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Sum of the primes up to 64',
																		#key : '',
																		#body : '(Integer primesUpTo: 64) sum',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1261,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @1258,
																#level : 2,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : '"Few liners" ;-)',
																#key : '',
																#body : 'Estos son otros scripts interesantes que fueron tomados de ejemplos de la comunidad.
Los créditos al autor original están colocados en los comentarios de cada script.',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Composición y escalado de morphs (elementos gráficos)',
																		#key : '',
																		#body : '"Este script toma una image grande, la coloca como fondo y coloca dos morphs simples, un
círculo y un rectángulo escalados sobre ella. Puede tardar un poco en ejecutarse"
| window pane board background scaler|

background := AlphaImageMorph withForm: 
\t(ZnEasy getJpeg: \'http://i.imgur.com/K1QR9vA.jpg\').
background lock.

board := PasteUpMorph new.
board 
color: Color gray;
borderWidth: 3;
borderColor: Color black;
extent: 2000@2000; 
backgroundMorph: background;
addMorph: (CircleMorph new color: Color cyan; position: 41@23; yourself);
addMorph: (Morph new color: Color orange; position: 1200@1200; yourself).

scaler := TransformMorph new.
scaler extent: 1000@1000.
scaler scale: 0.5@0.5.
scaler addMorph: board.

pane := ScrollPane new.
pane scroller addMorph: scaler.

window := pane openInWindow.
window position: 20@20; extent: 420@420.
',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1286,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Traer un avatar asociado a un correo electrónico',
																		#key : '',
																		#body : '| email url |
email := \'gpmeneses@gmail.com\'.
url := \'http://www.gravatar.com/avatar/\', (MD5 hashMessage: email trimBoth asLowercase) hex, \'.jpg\'.
(ZnEasy getJpeg: url) asMorph openInWindow 
',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1286,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Graficar un AST (árbol de sintaxis abstracta)',
																		#key : '',
																		#body : '| ast builder |
ast := RBParser parseExpression: \'self foo. super foo\'.
    builder := RTMondrian new.
    builder shape ellipse size: 15.
    builder nodes: ast allChildren.
    builder edges connectFrom: #parent.
    builder layout tree.
    builder',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1286,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'OSM: Consultar Nominatim',
																		#key : '',
																		#body : '"Thanks to Henrik Nergard"
"Nominatim es un motor de búsqueda para OpenStreetMap. 
Para mayor información sobre este consultar:

http://nominatim.openstreetmap.org/

Este pequeño script extrae resultados de Nominatim y entrega
un polígo que delimita una zona geográfica, reconocida por un nombre, 
por ejemplo \'Teusaquillo\',en Bogotá
"

| baseURL query settings result entries |

query := UIManager default request: \'Find location for\' .

baseURL := \'http://nominatim.openstreetmap.org/search/\'.
settings := \'?format=jsonv2&limit=10\'.

result := MCFileTreeJsonParser parse: (baseURL , query asString, settings) asZnUrl retrieveContents.

(result collect: [ :dct |
\t(dct at: \'display_name\') -> 
\t\t((dct at: \'lat\') asNumber @ (dct at: \'lon\') asNumber)
]) inspect .',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1286,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Lista de las capitales del mundo',
																		#key : '',
																		#body : '"Thanks to Hernán Morales Durand"
((NeoJSONReader fromString: (
    ZnEasy 
        get: \'http://api.geonames.org/countryInfoJSON\'
        username: \'demo\'
        password: \'\') contents) at: #geonames) collect: [ : d | d at: #capital ]',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1286,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Jugando un poco con Open Movie Database',
																		#key : '',
																		#body : 'Veremos cómo consultar la base de datos de Open
Movie Data Base y extraer datos particulares. 

Los ejemplos acá están basados en variaciones de
código provisto por Hernan Morales Durand.',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Afiche de tu película favorita',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Ejemplos',
																						#key : '',
																						#body : '',
																						#tags : '',
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'Blade Runner',
																								#key : '',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Blade Runner\';
        get;
        contents)) at: #Poster))
',
																								#tags : OrderedCollection [
																									'código'
																								],
																								#children : OrderedCollection [ ],
																								#parent : @1310,
																								#level : 5,
																								#links : OrderedCollection [
																									''
																								]
																							},
																							GrafoscopioNode {
																								#header : 'Back to the future',
																								#key : '',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Back to the future\';
        get;
        contents)) at: #Poster))
',
																								#tags : OrderedCollection [
																									'código'
																								],
																								#children : OrderedCollection [ ],
																								#parent : @1310,
																								#level : 5,
																								#links : OrderedCollection [
																									''
																								]
																							},
																							GrafoscopioNode {
																								#header : 'Ghost in the Shell',
																								#key : '',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'ghost in the shell\';
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1310,
																								#level : 5,
																								#links : OrderedCollection [ ]
																							},
																							GrafoscopioNode {
																								#header : 'Good will hunting',
																								#key : '',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Good will hunting\';
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1310,
																								#level : 5,
																								#links : OrderedCollection [
																									''
																								]
																							},
																							GrafoscopioNode {
																								#header : 'Magnolia',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Magnolia\';
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1310,
																								#level : 5,
																								#links : OrderedCollection [
																									'',
																									'http://ws.stfx.eu/6IAL3JKJRYBU'
																								],
																								#output : @1326
																							},
																							GrafoscopioNode {
																								#header : 'Life Is Beautiful',
																								#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Life Is Beautiful\';
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1310,
																								#level : 5,
																								#links : OrderedCollection [
																									'',
																									'http://ws.stfx.eu/L27MW66U41R3'
																								],
																								#output : @1329
																							}
																						],
																						#parent : @1307,
																						#level : 5,
																						#links : OrderedCollection [
																							''
																						]
																					},
																					GrafoscopioNode {
																						#header : 'Deconstruyendo el ejemplo',
																						#key : '',
																						#body : '',
																						#tags : OrderedCollection [
																							'text'
																						],
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'Película con variable',
																								#key : '',
																								#body : '| aTitle |

aTitle := \'Fight club\'.

(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents)) at: #Poster))
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1333,
																								#level : 6,
																								#links : OrderedCollection [ ]
																							},
																							GrafoscopioNode {
																								#header : 'Con bloques para contenidos traer el JSON)',
																								#key : '',
																								#body : '| getJSONString temp myDict |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

temp := getJSONString value: \'Magnolia\'.
temp.
myDict := NeoJSONReader fromString: temp.
"myDict at: #Director."

ZnEasy getJpeg: (myDict at: #Poster)
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1333,
																								#level : 6,
																								#links : OrderedCollection [
																									'',
																									'http://ws.stfx.eu/N002L3K1ZU80'
																								]
																							},
																							GrafoscopioNode {
																								#header : 'Usando dos bloques',
																								#key : '',
																								#body : '| getJSONString movieInfoFromJSONString jsonDataString |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

jsonDataString := getJSONString value: \'Fight club\'.

movieInfoFromJSONString := [ :aJSONString | NeoJSONReader fromString: aJSONString].


ZnEasy getJpeg:((movieInfoFromJSONString value: jsonDataString) at: #Poster)
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1333,
																								#level : 6,
																								#links : OrderedCollection [ ]
																							},
																							GrafoscopioNode {
																								#header : 'Con llaves para diferentes atributos de la peli',
																								#key : '',
																								#body : '| getJSONString movieInfoFromJSONString jsonDataString movieInfoForKey getPoster |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

jsonDataString := getJSONString value: \'E.T.\'.
movieInfoFromJSONString := [ :aJSONString | NeoJSONReader fromString: aJSONString].
movieInfoForKey := [ :aKey | (movieInfoFromJSONString value: jsonDataString) at: aKey ].
movieInfoForKey value: #Actors.
getPoster := [:key | ZnEasy getJpeg:(movieInfoForKey value: key)] value: #Poster
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1333,
																								#level : 6,
																								#links : OrderedCollection [ ]
																							}
																						],
																						#parent : @1307,
																						#level : 5,
																						#links : OrderedCollection [
																							''
																						]
																					},
																					GrafoscopioNode {
																						#header : 'Trivia',
																						#body : '',
																						#tags : OrderedCollection [
																							'text'
																						],
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'And the oscar winner is...',
																								#body : '| o i |
o :=  #[76 97 32 76 97 32 76 97 110 100] asString asText.
i := GTInspector openOn: o.
[ 1 second wait.
o
    addAttribute: TextEmphasis struckOut;
    append: #[77 111 111 110 108 105 103 104 116] asString.
i model update ] fork.
',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1349,
																								#level : 6,
																								#links : OrderedCollection [
																									'',
																									'http://ws.stfx.eu/6MEJ55EXLSOA'
																								]
																							}
																						],
																						#parent : @1307,
																						#level : 5,
																						#links : OrderedCollection [
																							''
																						]
																					}
																				],
																				#parent : @1304,
																				#level : 4,
																				#links : OrderedCollection [
																					''
																				]
																			}
																		],
																		#parent : @1286,
																		#level : 3,
																		#links : OrderedCollection [
																			''
																		]
																	}
																],
																#parent : @1258,
																#level : 2,
																#links : OrderedCollection [
																	''
																]
															}
														],
														#parent : @1243,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'CInemania: Creando el primer paquete',
														#key : '',
														#body : 'Acá tomaremos el ejemplo anterior de Open  Movie Data Base y lo convertiremos en una aplicación.
Esto nos permitirá entender la lógica con la que eso se hace y  "leer" la forma en que otras aplicaciones
están hechas.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Los de Offray',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Crear un nuevo paquete',
																		#key : '',
																		#body : '"Esta es la ventana que nos pide el nombre de un paquete que estamos agregando al sistema"
ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/create-new-package.png\'',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1363,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Paquete recien creado',
																		#key : '',
																		#body : '"Una vez hallamos creado el paquete cinemanía veremos lo siguiente:"

ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/new-package-created.png\'

"Este es el paquete vacio, aún sin ningún objeto en particular"',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1363,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Comentarios de una clase: por llenar',
																		#key : '',
																		#body : '"Recien se crea una clase, aparece un símbolo de admiración al lado izquierdo
de su nombre. Si hacemos click en el botón \'Comments\' podremos indicar el propósito de dicha
clase, como se muestra en la siguiente pantalla"
ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/add-comments.png\'',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1363,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Comentarios de una clase: llenándolos (dirty)',
																		#key : '',
																		#body : '"Reemplazamos la plantilla de comentarios que se nos da por omisión, por alguna descripción de lo que hace el paquete.
Veremos que la esquina superior derecha está resaltada, lo que indica que el comentario aún no se ha salvado,
como muestra esta pantalla"

ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/add-comments-filled.png\'

"y luego salvamos usando Comand S (Mac), Ctrl S (Windows, Gnu/Linux) o el menú"',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1363,
																		#level : 3,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @1360,
																#level : 2,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @1243,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'Nix: Instalación de software',
														#key : '',
														#body : 'En ocasiones el software que tenemos instalado en nuestra máquina es insuficiente para
realizar la tareas que queremos.
En ese caso, apelamos a sistemas de instalación de paquetes y existen distintos que son 
multiplataforma ([Zero Install]( )) o específicos de ciertas plataformas.
Por ejemplo, en plataformas Gnu/Linux contamos con sistemas como `apt-get` o `pacman`
para gestionar la instalación de software.
Sin embargo, dichos gestores de instalación de software son específicos de una distribución
y sus derivados ( ̀apt-get ̀ funciona para Debian y Ubuntu,  ̀pacman ̀ para Arch y Mnajaro) y
en ocasiones queremos instalar software que no está disponible en nuestra distribución  
o que es inconpatible con las versiones actuales de lo que tenemos instalado
(particularmente para las que manejas ramas, como Debian y sus derivados) o queremos
abstraer el proceso para que no depende de una variante particular de Linux, entre las más
de 300 distribuciones disponibles (ver [Distro Watch]()).
En dichos casos, un gestor de paquetes como Nix nos brinda una alternativa para
despreocuparnos de la distribución subyacente funcionando sobre distintas variantes del
sistema Unix, incluidos Gnu/Linux, Solaris y Mac.

Para mayor información ver:

  - [https://nixos.org/nix/manual/](https://nixos.org/nix/manual/ ).
  - [NixOS](https://nixos.org/ ): The Purely Functional Linux Distribution. Una distribución basada en este gestor de paquetes.
  - [About NixOS](https://nixos.org/nixos/about.html )',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @1243,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'Fossil: Colaboración y control de versiones minimalista.',
														#key : '',
														#body : '',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [ ],
														#parent : @1243,
														#level : 1,
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'Mustache: automatizando la creación de HTML',
														#key : '',
														#body : '',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Instalación',
																#key : '',
																#body : 'Gofer it
   smalltalkhubUser: \'NorbertHartl\' project: \'Mustache\';
   configuration;
   loadStable',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : GrafoscopioNode {
																	#header : 'Mustache: automatizando la creación de HTML',
																	#key : '',
																	#body : Text {
																		#string : '',
																		#runs : RunArray {
																			#runs : [ ],
																			#values : [ ]
																		}
																	},
																	#tags : OrderedCollection [
																		'text'
																	],
																	#children : @1390,
																	#parent : GrafoscopioNode {
																		#header : 'twitter.com',
																		#key : '',
																		#body : 'Twitter: La más popular red social de microblogging, basada en comunicación vía
mensajes de un límite de hasta 140 caracteres',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Micrositio Web',
																				#key : '',
																				#body : 'Este nodo explicará como crear un micrositio web para publicar en línea resultados de las
visualizaciones.',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Pecha Kucha',
																						#key : '',
																						#body : 'Para detalles ver: https://github.com/Pharophile/PechaKucha 

Gracias a Philippe Back por esto.',
																						#tags : OrderedCollection [
																							'text'
																						],
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'Cargar soporte para MDL en Seaside',
																								#key : '',
																								#body : 'Metacello new
    githubUser: \'DuneSt\' project: \'MaterialDesignLite\' commitish: \'development\' path: \'src\';
    baseline: \'MaterialDesignLite\';
    onWarningLog;
    load',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1405,
																								#level : 4
																							},
																							GrafoscopioNode {
																								#header : 'Cargar soporte Pecha Kucha',
																								#key : '',
																								#body : 'Metacello new
    githubUser: \'Pharophile\' 
    project: \'PechaKucha\' 
    commitish: \'master\' 
    path: \'packages\';
    baseline: \'PechaKucha\';
    onWarningLog;
    load',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1405,
																								#level : 3
																							},
																							GrafoscopioNode {
																								#header : 'Iniciar la aplicación',
																								#key : '',
																								#body : 'PKApplication declareApplicationAndStartServer.',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1405,
																								#level : 3
																							}
																						],
																						#parent : @1402,
																						#level : 3
																					}
																				],
																				#parent : @1399,
																				#level : 2
																			},
																			GrafoscopioNode {
																				#header : 'Prototipo Data Selfie',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Básico',
																						#key : '',
																						#body : '"Esto supone que ya se ha descargado y descompreso el archivo de mensajes de Twitter"
| profile aMessagesFile |
profile := TwitterProfileOverview new
\tscreenName: \'offrayLC\'.
profile getAvatar.
aMessagesFile := (FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'DataSelfies\' / \'Twitter\' / \'DataDumps\' / \'offrayLC\' / \'data\' / \'js\' / \'tweets\' /\'2013_02.js\') asFileReference.
profile splitMessagesByTypeFrom: aMessagesFile.
profile avatarWheel ',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1414,
																						#level : 3
																					},
																					GrafoscopioNode {
																						#header : 'Cargar mensajes',
																						#key : '',
																						#body : '"Esto supone que ya se ha descargado y descompreso el archivo de mensajes de Twitter"
| aMessagesFile |
aMessagesFile := (FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'DataSelfies\' / \'Twitter\' / \'DataDumps\' / \'offrayLC\' / \'data\' / \'js\' / \'tweets\' /\'2013_02.js\') asFileReference.
TPMessages new splitMessagesByTypeFrom: aMessagesFile.
',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1414,
																						#level : 3
																					}
																				],
																				#parent : @1399,
																				#level : 2
																			}
																		],
																		#level : 1
																	},
																	#level : 2
																},
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'Crear con moustache el archivo de data selfies',
																#key : '',
																#body : '| workingFolder moustacheTplFile templateContent context rendered targetFile tempStream |

"Ubicación de la plantilla en el sistema de archivos"
workingFolder := FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'TwitterDataSelfies\'..
moustacheTplFile := (workingFolder / \'templates\' / \'index.html\') asFileReference.

"Leer el template como string"
templateContent := moustacheTplFile contents asString.

"Estos datos de contexto deben ser llenados desde Twitter"
context := {
   \'screen_name\' -> \'offrayLC\'.
   \'page_title\' -> \'Mi data selfie de Twitter\'.
   \'bio_message\' -> \'Esto viene de Twitter\'.
   \'url_link\' -> \'http://algo.com\'.
\t\'month\' -> \'2013_02.png\' } asDictionary.

"Procesar la plantilla con los datos de contexto"
rendered := (MustacheTemplate on: templateContent) value: context.

"Guardar el contenido renderizado en un archivo"
targetFile := (workingFolder / \'profiles\' / (context at: #screen_name) / \'index.html\') asFileReference.
tempStream := targetFile writeStream.
tempStream nextPutAll: rendered.
tempStream close.
',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @1393,
																#level : 3,
																#links : OrderedCollection [ ]
															},
															GrafoscopioNode {
																#header : 'http://ws.stfx.eu/1N9FKAUI2UI0',
																#key : '',
																#body : '| profile workingFolder moustacheTplFile templateContent context rendered targetFile tempStream |

profile := TwitterProfileOverview new
\tscreenName: \'LuLinGar\'.

"Ubicación de la plantilla en el sistema de archivos"
workingFolder := FileLocator root / \'media\' / \'hackbo\' / \'memoluis\' / \'dataweek\' / \'repo-dataselfies\'.
moustacheTplFile := (workingFolder / \'templates\' / \'index.html\') asFileReference.

"Leer el template como string"
templateContent := moustacheTplFile contents asString.

"Estos datos de contexto deben ser llenados desde Twitter"
context := {
   \'screen_name\' -> (profile screenName).
   \'page_title\' -> \'Mi data selfie\'.
   \'bio_message\' -> \'Esto viene de Twitter\'.
   \'url_link\' -> \'http://algo.com\' } asDictionary.

"Procesar la plantilla con los datos de contexto"
rendered := (MustacheTemplate on: templateContent) value: context.

"Guardar el contenido renderizado en un archivo"
targetFile := (workingFolder / \'profiles\' / (profile screenName) / \'index.html\') asFileReference.
tempStream := targetFile writeStream.
tempStream nextPutAll: rendered.
tempStream close.
',
																#tags : 'código',
																#children : OrderedCollection [ ],
																#parent : @1393,
																#level : 3,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @1243,
														#level : 1,
														#nodesInPreorder : OrderedCollection [
															@1388,
															@1391,
															@1422,
															@1425
														],
														#links : OrderedCollection [ ]
													},
													GrafoscopioNode {
														#header : 'Teapot: constructor minimalista de aplicaciones web',
														#key : '',
														#body : '',
														#tags : '',
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Minitutorial',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Instalación',
																		#key : '',
																		#body : 'Gofer it
    smalltalkhubUser: \'zeroflag\' project: \'Teapot\';
    configuration;
    loadStable.',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1432,
																		#level : 4,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Hello World',
																		#key : '',
																		#body : 'Teapot on
    GET: \'/welcome\' -> \'Hello World!\';
    start.

"Do it and view at: http://localhost:1701/welcome"',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1432,
																		#level : 4,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Hello User',
																		#key : '',
																		#body : 'Teapot on
    GET: \'/hi\' -> \'Bonjour!\';
    GET: \'/hi/<user>\' -> [:req | \'Hello \', (req at: #user)];
start',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1432,
																		#level : 4,
																		#links : OrderedCollection [
																			''
																		]
																	}
																],
																#parent : GrafoscopioNode {
																	#header : 'Teapot: constructor minimalista de aplicaciones web',
																	#key : '',
																	#body : Text {
																		#string : '',
																		#runs : RunArray {
																			#runs : [ ],
																			#values : [ ]
																		}
																	},
																	#tags : '',
																	#children : @1431,
																	#parent : @1399,
																	#level : 2
																},
																#level : 3,
																#links : OrderedCollection [
																	''
																]
															},
															GrafoscopioNode {
																#header : 'Tealight',
																#key : '',
																#body : '',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Instalación',
																		#key : '',
																		#body : 'Metacello new 
    repository: \'github://astares/Tealight/repository\';
    baseline: \'Tealight\';
    load  ',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1450,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Acceder a un Teapot por omisión',
																		#key : '',
																		#body : 'TLWebserver teapot',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1450,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Definir una ruta para una instancia de Teapot',
																		#key : '',
																		#body : 'TLWebserver teapot 
    GET: \'/hi\' -> \'HelloWorld\'',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1450,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Hola usuario',
																		#key : '',
																		#body : 'TLWebserver teapot 
    GET: \'/hi/<user>\' -> [:req | \'Hello \', (req at: #user)]',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1450,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Transformadores de respuestas',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'A json',
																				#key : '',
																				#body : 'TLWebserver teapot
\tGET: \'/jsonlist\' -> #(1 2 3 4); output: #json',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @1465,
																				#level : 5,
																				#links : OrderedCollection [
																					''
																				]
																			},
																			GrafoscopioNode {
																				#header : 'A texto plano',
																				#key : '',
																				#body : 'TLWebserver teapot
\tGET: \'/textoplano\' -> \'Esto es texto plano\'; output: #text',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @1465,
																				#level : 5,
																				#links : OrderedCollection [
																					''
																				]
																			},
																			GrafoscopioNode {
																				#header : 'Descargas',
																				#key : '',
																				#body : 'TLWebserver teapot
\tGET: \'/descargas\' -> [\'/tmp/prueba.txt\' asFileReference readStream]; output: #stream',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @1465,
																				#level : 5,
																				#links : OrderedCollection [
																					''
																				]
																			}
																		],
																		#parent : @1450,
																		#level : 4,
																		#links : OrderedCollection [
																			''
																		]
																	},
																	GrafoscopioNode {
																		#header : 'Plantillas',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Instalar soporte Mustache',
																				#key : '',
																				#body : 'Gofer it
   smalltalkhubUser: \'NorbertHartl\' project: \'Mustache\';
   configuration;
   loadStable',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @1478,
																				#level : 5,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Usarlas',
																				#key : '',
																				#body : 'TLWebserver teapot
\tGET: \'/saludo\' -> {\'phrase\' -> \'Hello\'. \'name\' -> \'World\'};
\toutput: (TeaOutput mustacheHtml: \'<b>{{phrase}}</b> <i>{{name}}</i>!\')',
																				#tags : 'código',
																				#children : OrderedCollection [ ],
																				#parent : @1478,
																				#level : 5,
																				#links : OrderedCollection [ ]
																			}
																		],
																		#parent : @1450,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Manejo de errores',
																		#key : '',
																		#body : '3',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1450,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Servir archivos locales',
																		#key : '',
																		#body : '<b>Hello</b> <i>World</i>!',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1450,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Mirar procesos de Tealight',
																		#key : '',
																		#body : 'TLWebserver teapot inspect',
																		#tags : 'código',
																		#children : OrderedCollection [ ],
																		#parent : @1450,
																		#level : 4,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @1444,
																#level : 3,
																#links : OrderedCollection [
																	'',
																	'https://github.com/astares/Tealight'
																]
															}
														],
														#parent : @1243,
														#level : 1,
														#nodesInPreorder : OrderedCollection [
															@1430,
															@1432,
															@1435,
															@1438,
															@1441,
															@1450,
															@1453,
															@1456,
															@1459,
															@1462,
															@1465,
															@1468,
															@1471,
															@1474,
															@1478,
															@1481,
															@1484,
															@1488,
															@1491,
															@1494
														],
														#links : OrderedCollection [
															''
														]
													},
													GrafoscopioNode {
														#header : 'Borradores',
														#key : '',
														#body : 'Acá encontrarás código que aún no está tan maduro como el que has visto hasta el momento.
Son algunos apuntes de diferentes prototipos que están avanzando y algún código que no continuo.
Pharo es un entorno dinámico que mejora continuamente.
Al darte una mirada de estos borradores puedes ver parte del proceso de construcción del cierto 
código y vincularte al proceso.

Futuras versiones de este cuaderno interactivo, tendrán ediciones más maduras y robustas del
código.',
														#tags : OrderedCollection [
															'text'
														],
														#children : OrderedCollection [
															GrafoscopioNode {
																#header : 'Visualización de datos',
																#key : '',
																#body : 'Acá están recopilados algunos ejemplos que hemos hecho con data scrapping (raspado de datos)',
																#tags : OrderedCollection [
																	'text'
																],
																#children : OrderedCollection [
																	GrafoscopioNode {
																		#header : 'Twitter',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Usando algunos scrappers predefinidos',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Ejemplo 1: Un perfil',
																						#key : '',
																						#body : '',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1509,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Ejemplo 2: Dos perfiles',
																						#key : '',
																						#body : '| perfil1 perfil2 perfiles |

perfil1 := TwitterProfile new.
perfil2 := TwitterProfile new.

"Vmmos a crear un nuevo perfil"
perfil1 scrapDataForProfile: \'PetroGustavo\'.
perfil2 scrapDataForProfile: \'JuanManSantos\'.

perfiles := OrderedCollection new.
perfiles 
\tadd: perfil1;
\tadd: perfil2.
perfiles.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1509,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Ejemplo 3: Varios perfiles',
																						#key : '',
																						#body : '| perfil perfiles misPoliticos |

misPoliticos := #(\'PetroGustavo\' "Alcalde de Bogotá"
\t\t\t\t\t\t\'JuanManSantos\' "Presidente de Colombia" 
\t\t\t\t\t\t\'ginaparody\' "Ministra de educación de Colombia"
\t\t\t\t\t\t\'CFKArgentina\' "Presidenta de Argentina").

perfiles := OrderedCollection new.

misPoliticos do: [:politico |
\t  \tperfil := TwitterProfile new.
\t\tperfil scrapDataForProfile: politico.
\t\tperfiles add: perfil.].
perfiles.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1509,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					}
																				],
																				#parent : @1506,
																				#level : 3,
																				#links : OrderedCollection [ ]
																			},
																			GrafoscopioNode {
																				#header : 'Deconstruyendo un scrapper.',
																				#key : '',
																				#body : '',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Traerse el html',
																						#key : '',
																						#body : '\t| client anUrl aProfileName |
\taProfileName := \'dominemosLasTIC\'.
\tanUrl := \'https://twitter.com/\', aProfileName.
\tclient := ZnClient new.
\tclient get: anUrl.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1522,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Encontrar algo dentro del html',
																						#key : '',
																						#body : '\t| client anUrl aProfileName |
\taProfileName := \'dominemosLasTIC\'.
\tanUrl := \'https://twitter.com/\', aProfileName.
\tclient := ZnClient new.
\tclient get: anUrl.',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1522,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					}
																				],
																				#parent : @1506,
																				#level : 3,
																				#links : OrderedCollection [ ]
																			}
																		],
																		#parent : @1503,
																		#level : 2,
																		#links : OrderedCollection [ ]
																	},
																	GrafoscopioNode {
																		#header : 'Contratos públicos',
																		#key : '',
																		#body : '',
																		#tags : OrderedCollection [
																			'text'
																		],
																		#children : OrderedCollection [
																			GrafoscopioNode {
																				#header : 'Visualización Guía: Treemapping',
																				#key : '',
																				#body : 'Para mirar cómo se han realizado los gastos presupuestales, usaremos como visualización guía una que es producida por
la técnica de *treemapping* y que permite explorar cómo una jerarquía está compuesta por partes disyuntas que la conforman
(como en el caso de la división de presupuestos).
Para mayor información sobre dicha técnica véase la 
[página de la wikipedia sobre treemapping](https://en.wikipedia.org/wiki/Treemapping)',
																				#tags : OrderedCollection [
																					'text'
																				],
																				#children : OrderedCollection [
																					GrafoscopioNode {
																						#header : 'Ejemplo 1',
																						#key : '',
																						#body : '\t| b |
\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color veryLightGray.
\t
\tb from: (1 to: 17) using: [#()].
\tb weight: #yourself.
\tb build.
\t^ b view',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1536,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Ejemplo 2',
																						#key : '',
																						#body : 'RTTreeMapExample new exampleNumber',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1536,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Integrando datos a la visualización',
																						#key : '',
																						#body : '| aFile aCharacter table b |

aFile := (FileLocator documents / \'DataWeek\' / \'query-subtotales-por-segmentos.csv\') asFileReference.
aCharacter := $,.
table := RTTabTable new input: aFile contents usingDelimiter: aCharacter.
table valuesOfColumn: 2.

\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color veryLightGray.
\tb from: (2 to: table numberOfRows) using: [#()].
\tb weight: [:n | (table valuesOfColumn: 2) at: n ].
\tb build.
\tb view.
table values',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1536,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Probando OpenSpending',
																						#key : '',
																						#body : '| contratos archivo |

archivo := (FileLocator documents / \'DataWeek\' / \'query-subtotales-por-segmentos.csv\') asFileReference.
contratos := OpenSpending new.
contratos loadDataFromCSV: archivo usingDelimiter: $,.
contratos',
																						#tags : 'código',
																						#children : OrderedCollection [ ],
																						#parent : @1536,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					},
																					GrafoscopioNode {
																						#header : 'Treemap con etiquetas',
																						#key : '',
																						#body : '',
																						#tags : OrderedCollection [
																							'text'
																						],
																						#children : OrderedCollection [
																							GrafoscopioNode {
																								#header : 'Primera versión',
																								#key : '',
																								#body : '| b labels popup |
\tlabels := RTLabel elementsOn: #(\'uno\' \'dos\' \'tres\' \'cuatro\' \'cinco\').
\tpopup := RTPopup new.
\tpopup text: [:object | labels at: object  ].
\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color random.
\tb from: (1 to: 5) using: [#()].
\tb weight: [:n | n].
\tb build.
\tb view elements @ RTLabelled.
\t^ b view.',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1551,
																								#level : 5,
																								#links : OrderedCollection [ ]
																							},
																							GrafoscopioNode {
																								#header : 'Entendiendo popups dinámicos',
																								#key : '',
																								#body : '',
																								#tags : 'código',
																								#children : OrderedCollection [ ],
																								#parent : @1551,
																								#level : 5,
																								#links : OrderedCollection [ ]
																							}
																						],
																						#parent : @1536,
																						#level : 4,
																						#links : OrderedCollection [ ]
																					}
																				],
																				#parent : @1533,
																				#level : 3,
																				#links : OrderedCollection [ ]
																			}
																		],
																		#parent : @1503,
																		#level : 2,
																		#links : OrderedCollection [ ]
																	}
																],
																#parent : @1500,
																#level : 2,
																#links : OrderedCollection [ ]
															}
														],
														#parent : @1243,
														#level : 1,
														#links : OrderedCollection [ ]
													}
												],
												#level : 0,
												#nodesInPreorder : OrderedCollection [
													@1243,
													@1246,
													@1250,
													@1254,
													@1124,
													@1128,
													@1132,
													@1136,
													@1140,
													@1143,
													@1146,
													@1149,
													@1152,
													@1156,
													@1160,
													@1164,
													@1169,
													@1172,
													@1176,
													@1180,
													@1183,
													@1186,
													@1189,
													@1192,
													@1195,
													@1199,
													@1200,
													@1201,
													@1123,
													@1120,
													@1202,
													@1206,
													@1214,
													@1218,
													@1222,
													@1226,
													@1230,
													@1234,
													@1239,
													@1258,
													@1261,
													@1264,
													@1267,
													@1270,
													@1273,
													@1276,
													@1279,
													@1282,
													@1286,
													@1289,
													@1292,
													@1295,
													@1298,
													@1301,
													@1304,
													@1307,
													@1310,
													@1312,
													@1316,
													@1320,
													@1323,
													@1326,
													@1329,
													@1333,
													@1336,
													@1339,
													@1342,
													@1345,
													@1349,
													@1352,
													@1360,
													@1363,
													@1366,
													@1369,
													@1372,
													@1375,
													@1380,
													@1384,
													@1388,
													@1391,
													@1422,
													@1425,
													@1430,
													@1432,
													@1435,
													@1438,
													@1441,
													@1450,
													@1453,
													@1456,
													@1459,
													@1462,
													@1465,
													@1468,
													@1471,
													@1474,
													@1478,
													@1481,
													@1484,
													@1488,
													@1491,
													@1494,
													@1500,
													@1503,
													@1506,
													@1509,
													@1512,
													@1515,
													@1518,
													@1522,
													@1525,
													@1528,
													@1533,
													@1536,
													@1539,
													@1542,
													@1545,
													@1548,
													@1551,
													@1554,
													@1557
												]
											},
											#level : 1,
											#links : OrderedCollection [ ]
										},
										#level : 2,
										#links : OrderedCollection [
											''
										]
									},
									#level : 3,
									#links : OrderedCollection [
										''
									]
								}
							],
							#parent : @639,
							#level : 2,
							#nodesInPreorder : OrderedCollection [
								@1117,
								@1120
							],
							#links : @1567
						},
						GrafoscopioNode {
							#header : 'Colections',
							#key : '',
							#body : '"El mensaje do: es enviado a una colección de objetos (Array, Set, OrderedCollection),
evaluando el bloque para cada elemento.

Acá queremos imprimir todos los números sobre el Transcript (una consola)"

| miColeccion |

#(11 38 3 -2 10) do: [:each |
     Transcript show: each*2; cr].

"Some other really nice iterators"

miColeccion := #(11 38 3 -2 10) collect: [:each | each abs].

#(11 38 3 -2 10) collect: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each >= 10].  

#(11 38 3 -2 10) reject: [:each | each > 10]. 

#(11 38 3 -2 10) 
     do: [:each | Transcript show: each printString]
     separatedBy: [Transcript show: \'.\'].

#(11 38 3 -2 10) detect: [ :el | el = 0 ] 
\tifFound: [ Transcript show: \'Encontrado\' ]
 \tifNone: [  ^ nil ]

"Ahora ve a la siguiente lección"',
							#tags : @1203,
							#children : @1204,
							#parent : @639,
							#level : 2,
							#nodesInPreorder : OrderedCollection [
								@1570
							],
							#links : @1205
						},
						GrafoscopioNode {
							#header : 'Optional',
							#key : '',
							#body : 'Las siguientes lecciones son algo más avanzadas y referidas a elementos  de interfaces gráficas
(botones, morphs) y cambios en caliente en los métodos de Smalltalk.
Si bien son importantes, las exploraremos con detalle en otros lugares, así que puedes
pasar al cierre de este tutorial y luego ir  a otros nodos como los de
código elegante en Pharo y otros ejemplos minimalistas para terminar en los distintos
proyectos del nodo titulado "Visualización de datos".',
							#tags : @1212,
							#children : @1213,
							#parent : @639,
							#level : 2,
							#nodesInPreorder : OrderedCollection [
								@1572,
								@1214,
								@1218,
								@1222,
								@1226,
								@1230,
								@1234
							],
							#links : @1238
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				@642,
				@645,
				@1069,
				@1074,
				@1078,
				@1082,
				@1086,
				@1090,
				@1102,
				@1107,
				@1112,
				@1117,
				@1120,
				@1570,
				@1572,
				@1214,
				@1218,
				@1222,
				@1226,
				@1230,
				@1234,
				GrafoscopioNode {
					#header : 'Publishing and Sharing our work',
					#body : '',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Saving and sharing your code snippets and notebook via web',
							#body : 'Use "Export Playground" functionality for code nodes and share your previos excercises via the Etherpad with your
companions.

',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Fossil',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Installing',
											#body : '',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Windows',
													#body : 'To install Fossil on Windows follow these steps:

  - Go to the download page at http://fossil-scm.org/index.html/uv/download.html .
  - Choose the binary for Windows.
  - Extract those zip in the C:/Windows folder.
  - That\'s it.
',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @1584,
													#level : 5,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : @1581,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Using',
											#body : 'Follow the following steps to share your notebooks using Fossil',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Clone a repository the Data Week repository at: <http://mutabit.com/repos.fossil/dataweek/>',
													#body : 'Clone the Data Week repository at: <http://mutabit.com/repos.fossil/dataweek/>

Lets start creating a folder for our repository, this could have any name. In our case we\'ll call it `DataWeek`:
    
    mkdir -p ~/Documents/DataWeek
    cd ~/Documentos/DataWeek
    fossil clone http://mutabit.com/repos.fossil/dataweek/ dataweek.fossil

The general syntax for cloning a repository is:
    
    fossil clone <repo-remoto> <nombre-local>
    
Una vez se halla terminado el clonado del repositorio, saldrá algo como esto:
        
     Round-trips: 3   Artifacts sent: 0  received: 378
    Clone done, sent: 835  received: 15013550  ip: 45.55.37.99
    Rebuilding repository meta-data...
     100.0% complete...
    Extra delta compression... 
    Vacuuming the database... 
    project-id: aa9f6e73b4f326e190f15c4a830c0909619bfa42
    server-id:  e166198b6fb3e438428986e46077a10f4efae1b9
    admin-user: apple (password is "9fa088")
',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @1592,
													#level : 4,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Open the repository',
													#body : 'Go to the folder where you cloned the repository and open it:

    cd ~/Documents/DataWeek
    fossil open dataweek.fossil 
    
Una vez abierto, veremos una salida como la que está en: 

Artefactos/DataSelfies/data-selfies.ston
Artefactos/SoftwarePublicoColombia/anotaciones.png
Artefactos/SoftwarePublicoColombia/carta-lider-iniciativa.md
Artefactos/SoftwarePublicoColombia/carta-lider-iniciativa.pdf

<More files listed>

project-name: Dataweek
repository:   /home/offray/Documentos/Critinfo/dataweek.fossil
local-root:   /home/offray/Documentos/Critinfo/
config-db:    /home/offray/.fossil
project-code: aa9f6e73b4f326e190f15c4a830c0909619bfa42
checkout:     113749bfda422450b7a2bdb68b8a28b17a690142 2017-10-29 22:46:31 UTC
parent:       bddea106fa30df41ee415b9d350a56277995eb5e 2017-10-26 23:04:08 UTC
tags:         trunk
comment:      Notas para el taller de mañana. (user: offray)
check-ins:    99

que corresponde a los archivos y carpetas en dicho repositorio y que remotamente se pueden navegar desde:

Hemos accedido a una copia de [todos los archivos](http://mutabit.com/repos.fossil/dataweek/dir?ci=tip ), sino de [toda su historia](http://mutabit.com/repos.fossil/dataweek/timeline?n=500&y=all&t=&ms=exact )      

',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @1592,
													#level : 4,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Introduce variation ',
													#body : '  - Create a folder for you under `Participants/<you>`, where `<you>` is any kind of unique indenfier yourself.
    It could be `FirstNameLastName`, your social media handler, or others.
  - From Grafoscopio, save a modified version of this notebook to the previously created folder.

',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @1592,
													#level : 4,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Register and syncronize',
													#body : '- Creamos un usuario en dicho repositorio:

        http://mutabit.com/repos.fossil/dataweek/login
        
 Nos sincronizamos desde la consola de comandos:
        
           fossil sync http://<usuario>@mutabit.com/repos.fossil/dataweek/      
        
donde `<usuario>` es el nombre de usuario que registramos en el paso anterior.',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @1592,
													#level : 4,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Commit',
													#body : '  - Commit to the Fossil repository.
  - Browse the repository history, locate your commit and share your notebook with others.  ',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @1592,
													#level : 4,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Share your commit',
													#body : 'Browse the [repository history](http://mutabit.com/repos.fossil/dataweek/timeline ), locate your commit and share your notebook with others.',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @1592,
													#level : 4,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Rinse and repeat',
													#body : 'Go to the excercises in the previous section. Do the "Using block to modularize code" and
"Add voting results for all deparments" and commit your modifed notebook with these two
solutions added.',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [ ],
													#parent : @1592,
													#level : 4,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : @1581,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										}
									],
									#parent : @1578,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Using Code Browser + SmalltalkHub',
									#body : 'In the previous excercise, we learnt how to share notebooks with the world using Fossil code repositories.
Each notebook is a text file that can be shared & versioned in this way.
But at some point you will want to reify you code in a way that express your understangin about a problem
via models. 
When you do that (which is called modelling) in Pharo, you are creating what is called a Specific Domain
Language (or DSL) for that problem.
With the previous excercises, we are ready to create a DSL for the Peace Voting Results in Colombia, with
the help on Code Browser and then we are going to share such DSL using SmalltalkHub, wich is a facility
to share code among Pharo users.
This will be the objective of this section.',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [ ],
									#parent : @1578,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								}
							],
							#parent : @1575,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						}
					],
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				@1578,
				@1581,
				@1584,
				@1587,
				@1592,
				@1595,
				@1599,
				@1603,
				@1607,
				@1611,
				@1615,
				@1619,
				@1625,
				GrafoscopioNode {
					#header : 'Modelling data',
					#body : '',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Data adquiring & manipulation',
							#body : '',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Open Movie Data Base',
									#body : 'This first exercise will be related with Open Movie Data Base.',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [ ],
									#parent : @1634,
									#level : 3,
									#links : OrderedCollection [
										'',
										'http://www.omdbapi.com/'
									]
								},
								GrafoscopioNode {
									#header : 'Líderes amenazados en Colombia',
									#body : '| contents data totalHombres totalMujeres b labeledData lb |
"Let\'s get the data"
contents := \'https://tupale.co//milfs/api.php?id=410&tipo=simple\' asUrl retrieveContents.
data := NeoJSONReader fromString: contents.
totalHombres := (data select: [ :item | (item at: \'Sexo\') = \'Hombre\']) size.
totalMujeres := data size -  totalHombres.
labeledData := { \'Hombres\' -> totalHombres . \'Mujeres\' -> totalMujeres }.
"Here we build the Pie Graphics"
b := RTPieBuilder new.
b interaction popup.
b objects: labeledData.
b slice: #value.
b labeled.
b normalizer distinctColor.
"Legend"
lb := RTLegendBuilder new.
lb view: b view.
lb addText: \'Líderes amenazados en Colombia 2016\'.
lb build.
^ b',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : @1634,
									#level : 3,
									#links : OrderedCollection [
										'',
										'https://tupale.co//milfs/api.php?id=410&tipo=simple',
										'http://ws.stfx.eu/GR43R3BV92KC'
									]
								}
							],
							#parent : @1631,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				@1634,
				@1637,
				@1641,
				GrafoscopioNode {
					#header : 'What\'s next',
					#body : '',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [ ],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				}
			]
		},
		#level : 1,
		#links : OrderedCollection [
			''
		]
	},
	@8,
	@12,
	@20,
	@84,
	@105,
	@173,
	@639,
	@1575,
	@1631,
	@1647
]