SlideShare ist ein Scribd-Unternehmen logo
1 von 109
Downloaden Sie, um offline zu lesen
Plumbin' Pipelines
with Gulp.js
@Dynatrace
@Ruxit
@ddprrt
fettblog.eu
HTML
CSS
JavaScript
Sass CoffeeScript LESS
P o s t C S S H A M L J a d e
U g l i f y E S 6 R e a c t J S
B r o w s e r i f y A n g u l a r J S
E m b e r C S S M i n J S L i n t
ESHint ImageOptim Mocha
Jasmine TypeScript
1530 lines of code
original Ant tasks used:
concat — copy — delete — mkdir
Let's talk a
short bit about
the JS build tool
revolution
Grunt started a boom
Gruntfiles get long
Grunt tasks get slow
lots of reads
and writes
And then came Gulp
Disclaimer
I (occasionally) contribute
to Gulp
I'm writing a book on Gulp
http://bit.ly/gulp-tool-book

39% off with 39baumgar

coupon code!
I don't know Java anymore
Java is to JavaScript what

Alf is to Gandalf
Let's go!
The ecosystem
Runtime environment
JavaScript
Package System for Node
Host of all things Gulp plugins
CLI Gulpfile
PluginA
PluginA
CLI Gulpfile
PluginA
PluginA
starts
CLI Gulpfile
PluginA
PluginA
loadsstarts
CLI Gulpfile
PluginA
PluginA
loadsstarts
uses
npm install -g gulp-cli
npm init
npm install --save-dev gulp
touch gulpfile.js
npm install -g gulpjs/gulp-cli#4.0
npm init
npm install --save-dev gulpjs/gulp#4.0
touch gulpfile.js
The basics:
Streams
gulp.src(…) gulp.dest(…)
Reads files Writes files
gulp.src(…) gulp.dest(…)
gulp.src(…) .pipe(uglify()) gulp.dest(…)
gulp.src(…) .pipe(uglify()) gulp.dest(…).pipe(concat())
to the command line!
Gulp API
• gulp.task creates a new task

• It requires to return either a Stream, a Promise or an Observable

• gulp.src “globs” files and returns a stream of virtual file objects

• each file can be piped through a process (jshint, uglify, less, etc.)

• gulp.dest saves the file back to the file system
gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
defines a new task
gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
with a defined name
gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
we load a certain file
(or files)
Starting here, we have virtual
files in-memory instead of
real files we
gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
and pipe it through a
series of operations
gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
before we save it
again on the "real" file system
Tasks
scripts styles lint
scripts
styles
lintgulp.parallel
scripts
styles
lint
gulp.parallel
gulp.series
to the command line!
Gulp API
• The second parameter of gulp.task is always a function.

• gulp.series is a task function that runs tasks in sequential order.

• gulp.parallel is a task function that starts every task concurrently

• Both task functions accept task names and other functions as
parameters.

• They can be combined infinitly
gulp.task('default',
gulp.series('clean',
gulp.parallel('styles', 'scripts'),
‘server'
)
);
gulp.task('default',
gulp.series('clean',
gulp.parallel('styles', 'scripts'),
‘server'
)
);
runs in series
gulp.task('default',
gulp.series('clean',
gulp.parallel('styles', 'scripts'),
‘server'
)
);
runs in parallel
A development
environment
gulp.watch
scripts
*.js
Bowser-Sync!
r
to the command line!
Gulp API
• gulp.watch creates a file watcher and listens to changes

• changes include ‘change’, ‘add’, ‘unlink’ and others

• BrowserSync is a development tool that can be fully integrated in
Gulp.

• Watchers trigger a browserSync.reload call
function watcher(done) {
gulp.watch('styles/**/*.less', gulp.parallel(‘styles’));
done();
}
function watcher(done) {
gulp.watch('styles/**/*.less', gulp.parallel(‘styles’));
done();
}
watches this Glob pattern
function watcher(done) {
gulp.watch('styles/**/*.less', gulp.parallel(‘styles’));
done();
}
starts this task on
change, unlink, add
gulp.task('server', function(done) {
bSync({
server: {
baseDir: ['dist', 'app']
}
})
done();
});
gulp.task('server', function(done) {
bSync({
server: {
baseDir: ['dist', 'app']
}
})
done();
}); BrowserSync set up to start
a dev server, serving dist and
app statically
gulp.watch('dist/**/*', bSync.reload);
And a watcher that triggers a
reload
Incremental
builds
Some tasks take long
gulp.src(‘scripts/*.js’)
.pipe(uglify())
.pipe(gulp.dest())
.pipe(concat())
Some tasks take long
gulp.src(‘scripts/*.js’)
.pipe(uglify())
.pipe(gulp.dest())
.pipe(concat())
Some tasks take long
gulp.src(‘scripts/*.js’)
.pipe(uglify())
.pipe(gulp.dest())
.pipe(concat())
Too much is going on!
Each change: Uglify all
the files?
Some tasks take long
gulp.src(‘scripts/*.js’)
.pipe(uglify())
.pipe(gulp.dest())
.pipe(concat())
filter files
that have changed
filter files
that have changed
do performance
heavy operations
filter files
that have changed
do performance
heavy operations
remember the
old files
filter files
that have changed
do performance
heavy operations
remember the
old files
and continue
with the other ops
to the command line!
Gulp Plugins
• gulp-cached and gulp-remember can be used to create file caches

• The plugin filters non-changed files and ads them back to the
stream once we are done with performance-heavy tasks

• Additionally to that, we can use gulp.lastRun in Gulp 4 to filter files
during globbing

• gulp-newer allows us to do incremental copies/builds on a per-file
basis
gulp.task('scripts', function () {
return gulp.src('app/scripts/**/*.js')
.pipe(cached('ugly'))
.pipe(uglify())
.pipe(remember('ugly'))
.pipe(concat('main.min.js'))
.pipe(gulp.dest('dist/scripts'));
});
gulp.task('scripts', function () {
return gulp.src('app/scripts/**/*.js')
.pipe(cached('ugly'))
.pipe(uglify())
.pipe(remember('ugly'))
.pipe(concat('main.min.js'))
.pipe(gulp.dest('dist/scripts'));
});
we use the cache to
check if files have
changed
gulp.task('scripts', function () {
return gulp.src('app/scripts/**/*.js')
.pipe(cached('ugly'))
.pipe(uglify())
.pipe(remember('ugly'))
.pipe(concat('main.min.js'))
.pipe(gulp.dest('dist/scripts'));
});
once we are done,
we remember all
the other files
we stored in
the cache
Part II
A short
source map interlude
Browserify
(for Babel/React)
so similar … yet so
different?
Gulp
Streams
Browserify 

Streams
Why not both??
var b = browserify({
entries: ['_js/main.js']
});
var bundle = function() {
return b.bundle()
.pipe(source(‘main.js’))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('js'));
}
var b = browserify({
entries: ['_js/main.js']
});
var bundle = function() {
return b.bundle()
.pipe(source(‘main.js’))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('js'));
}
b.bundle emits a
stream.
But no vinyl file
objects
var b = browserify({
entries: ['_js/main.js']
});
var bundle = function() {
return b.bundle()
.pipe(source(‘main.js’))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('js'));
}
vinyl-source-stream
wraps the original
stream into
a vinyl file object
var b = browserify({
entries: ['_js/main.js']
});
var bundle = function() {
return b.bundle()
.pipe(source(‘main.js’))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('js'));
}
vinyl-buffer converts
the stream contents
to a buffer for
plugins who need
such
Stream arrays
and merge Streams
A static
site generator
What does it do?
• Generates static HTML sites

• From a templating engine

• Can parse Markdown

• Can parse HTML

• Can create permalinks

• For different types (posts, pages)
The stack
• We use kramdown to convert Markdown to HTML

• We use nujucks for our templating engine

• We rename posts to feature blog permalink

• We rename pages to resemble pretty URLs
In pipes
gulp.src(‘posts/*.md')
.pipe(kramdown())
.pipe(wrap())
.pipe(nunjucks())
.pipe(rename())
.pipe(gulp.dest())
In pipes
gulp.src(‘posts/*.md')
.pipe(kramdown())
.pipe(wrap())
.pipe(nunjucks())
.pipe(rename())
.pipe(gulp.dest())
gulp.src(‘posts/*.html')
.pipe(wrap())
.pipe(nunjucks())
.pipe(rename())
.pipe(gulp.dest())
In pipes
gulp.src(‘posts/*.md')
.pipe(kramdown())
.pipe(wrap())
.pipe(nunjucks())
.pipe(rename())
.pipe(gulp.dest())
gulp.src(‘posts/*.html')
.pipe(wrap())
.pipe(nunjucks())
.pipe(rename())
.pipe(gulp.dest())
the same!
In pipes
gulp.src(‘pages/*.md')
.pipe(kramdown())
.pipe(wrap())
.pipe(nunjucks())
.pipe(rename())
.pipe(gulp.dest())
gulp.src(‘pages/*.html')
.pipe(wrap())
.pipe(nunjucks())
.pipe(rename())
.pipe(gulp.dest())
In pipes
gulp.src(‘pages/*.md')
.pipe(kramdown())
.pipe(wrap())
.pipe(nunjucks())
.pipe(rename())
.pipe(gulp.dest())
gulp.src(‘pages/*.html')
.pipe(wrap())
.pipe(nunjucks())
.pipe(rename())
.pipe(gulp.dest())
the same!
What if we could
reuse parts of the
stream?
to the command line!
to the command line!
gulp.task('default', function(cb) {
var streams = elements.map(function(el) {
return merge(
gulp.src(el.dir + '/**.md').pipe(markdown()),
gulp.src(el.dir + '/**.html')
).pipe(rename(el.renamefn));
});
return merge(streams).pipe(data(options))
.pipe(wrap(layoutStr))
.pipe(swig())
.pipe(gulp.dest('build'));
});
gulp.task('default', function(cb) {
var streams = elements.map(function(el) {
return merge(
gulp.src(el.dir + '/**.md').pipe(markdown()),
gulp.src(el.dir + '/**.html')
).pipe(rename(el.renamefn));
});
return merge(streams).pipe(data(options))
.pipe(wrap(layoutStr))
.pipe(swig())
.pipe(gulp.dest('build'));
});
we combine
multiple sources
to one stream
gulp.task('default', function(cb) {
var streams = elements.map(function(el) {
return merge(
gulp.src(el.dir + '/**.md').pipe(markdown()),
gulp.src(el.dir + '/**.html')
).pipe(rename(el.renamefn));
});
return merge(streams).pipe(data(options))
.pipe(wrap(layoutStr))
.pipe(swig())
.pipe(gulp.dest('build'));
});
with Array.map
and merge we can
create stream
arrays
Material
Workshop files
https://github.com/frontend-tooling

https://github.com/frontend-tooling/sample-project-gulp

https://github.com/frontend-tooling/static-site-generator

http://fettblog.eu

http://speakerdeck.com/ddprrt
Reading Material
http://bit.ly/gulp-tool-book

39% off with 39baumgar

coupon code!
@ddprrt

Weitere ähnliche Inhalte

Was ist angesagt?

CoffeeScript presentation
CoffeeScript presentationCoffeeScript presentation
CoffeeScript presentation
John Lynch
 
How to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rbHow to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rb
Hiroshi SHIBATA
 
Performance Optimization of Rails Applications
Performance Optimization of Rails ApplicationsPerformance Optimization of Rails Applications
Performance Optimization of Rails Applications
Serge Smetana
 
PDXPortland - Dockerize Django
PDXPortland - Dockerize DjangoPDXPortland - Dockerize Django
PDXPortland - Dockerize Django
Hannes Hapke
 
Rails Application Optimization Techniques & Tools
Rails Application Optimization Techniques & ToolsRails Application Optimization Techniques & Tools
Rails Application Optimization Techniques & Tools
guest05c09d
 
An Introduction to Go
An Introduction to GoAn Introduction to Go
An Introduction to Go
Cloudflare
 

Was ist angesagt? (20)

Intro to-puppet
Intro to-puppetIntro to-puppet
Intro to-puppet
 
Puppet at GitHub / ChatOps
Puppet at GitHub / ChatOpsPuppet at GitHub / ChatOps
Puppet at GitHub / ChatOps
 
How to test code with mruby
How to test code with mrubyHow to test code with mruby
How to test code with mruby
 
CoffeeScript presentation
CoffeeScript presentationCoffeeScript presentation
CoffeeScript presentation
 
20141210 rakuten techtalk
20141210 rakuten techtalk20141210 rakuten techtalk
20141210 rakuten techtalk
 
How to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rbHow to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rb
 
ZSH and RVM
ZSH and RVMZSH and RVM
ZSH and RVM
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 
CPANTS: Kwalitative website and its tools
CPANTS: Kwalitative website and its toolsCPANTS: Kwalitative website and its tools
CPANTS: Kwalitative website and its tools
 
Ansible not only for Dummies
Ansible not only for DummiesAnsible not only for Dummies
Ansible not only for Dummies
 
Leave end-to-end testing to Capybara
Leave end-to-end testing to CapybaraLeave end-to-end testing to Capybara
Leave end-to-end testing to Capybara
 
Automated reproducible images on openstack using vagrant and packer
Automated reproducible images on openstack using vagrant and packerAutomated reproducible images on openstack using vagrant and packer
Automated reproducible images on openstack using vagrant and packer
 
Performance Optimization of Rails Applications
Performance Optimization of Rails ApplicationsPerformance Optimization of Rails Applications
Performance Optimization of Rails Applications
 
Smalltalk on rubinius
Smalltalk on rubiniusSmalltalk on rubinius
Smalltalk on rubinius
 
Concurrency in Python
Concurrency in PythonConcurrency in Python
Concurrency in Python
 
PDXPortland - Dockerize Django
PDXPortland - Dockerize DjangoPDXPortland - Dockerize Django
PDXPortland - Dockerize Django
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
Rails Application Optimization Techniques & Tools
Rails Application Optimization Techniques & ToolsRails Application Optimization Techniques & Tools
Rails Application Optimization Techniques & Tools
 
An Introduction to Go
An Introduction to GoAn Introduction to Go
An Introduction to Go
 
Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go
 

Ähnlich wie Plumbin Pipelines - A Gulp.js workshop

Angular workflow with gulp.js
Angular workflow with gulp.jsAngular workflow with gulp.js
Angular workflow with gulp.js
Cihad Horuzoğlu
 

Ähnlich wie Plumbin Pipelines - A Gulp.js workshop (20)

TDC2016SP - Esqueça Grunt ou Gulp. Webpack and NPM rule them all!
TDC2016SP -  Esqueça Grunt ou Gulp. Webpack and NPM rule them all!TDC2016SP -  Esqueça Grunt ou Gulp. Webpack and NPM rule them all!
TDC2016SP - Esqueça Grunt ou Gulp. Webpack and NPM rule them all!
 
Gulp and bower Implementation
Gulp and bower Implementation Gulp and bower Implementation
Gulp and bower Implementation
 
Getting started with gulpjs
Getting started with gulpjsGetting started with gulpjs
Getting started with gulpjs
 
Angular workflow with gulp.js
Angular workflow with gulp.jsAngular workflow with gulp.js
Angular workflow with gulp.js
 
Web development tools { starter pack }
Web development tools { starter pack }Web development tools { starter pack }
Web development tools { starter pack }
 
Automating your workflow with Gulp.js
Automating your workflow with Gulp.jsAutomating your workflow with Gulp.js
Automating your workflow with Gulp.js
 
Introduction to Gulp
Introduction to GulpIntroduction to Gulp
Introduction to Gulp
 
Gulp - The Streaming Build System
Gulp - The Streaming Build SystemGulp - The Streaming Build System
Gulp - The Streaming Build System
 
Automating WordPress Plugin Development with Gulp
Automating WordPress Plugin Development with GulpAutomating WordPress Plugin Development with Gulp
Automating WordPress Plugin Development with Gulp
 
Introduction to GulpJs
Introduction to GulpJsIntroduction to GulpJs
Introduction to GulpJs
 
GulpJs - An Introduction
GulpJs - An IntroductionGulpJs - An Introduction
GulpJs - An Introduction
 
Gulp: Your Build Process Will Thank You
Gulp: Your Build Process Will Thank YouGulp: Your Build Process Will Thank You
Gulp: Your Build Process Will Thank You
 
Automating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAutomating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with Gulp
 
Frontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeFrontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the like
 
Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!
 
gulp
gulpgulp
gulp
 
Command Line Applications with Ruby
Command Line Applications with RubyCommand Line Applications with Ruby
Command Line Applications with Ruby
 
Laziness with Gulp
Laziness with GulpLaziness with Gulp
Laziness with Gulp
 
Automating Your Workflow with Gulp.js - php[world] 2016
Automating Your Workflow with Gulp.js - php[world] 2016Automating Your Workflow with Gulp.js - php[world] 2016
Automating Your Workflow with Gulp.js - php[world] 2016
 
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
 

Mehr von Stefan Baumgartner

Mehr von Stefan Baumgartner (12)

WASM! WASI! WAGI! WAT?
WASM! WASI! WAGI! WAT?WASM! WASI! WAGI! WAT?
WASM! WASI! WAGI! WAT?
 
Serverless Rust
Serverless RustServerless Rust
Serverless Rust
 
What TypeScript taught me about JavaScript
What TypeScript taught me about JavaScriptWhat TypeScript taught me about JavaScript
What TypeScript taught me about JavaScript
 
Real-world component libraries at scale
Real-world component libraries at scaleReal-world component libraries at scale
Real-world component libraries at scale
 
Jamstack on Azure
Jamstack on AzureJamstack on Azure
Jamstack on Azure
 
TypeScript's Type System
TypeScript's Type SystemTypeScript's Type System
TypeScript's Type System
 
The hero's journey
The hero's journeyThe hero's journey
The hero's journey
 
Sketchmine: Design Systems Tooling
Sketchmine: Design Systems ToolingSketchmine: Design Systems Tooling
Sketchmine: Design Systems Tooling
 
Automating UI development
Automating UI developmentAutomating UI development
Automating UI development
 
A hero's journey in JavaScript frameworks
A hero's journey in JavaScript frameworksA hero's journey in JavaScript frameworks
A hero's journey in JavaScript frameworks
 
[German] Ab mit dem Kopf!
[German] Ab mit dem Kopf![German] Ab mit dem Kopf!
[German] Ab mit dem Kopf!
 
Speed Index, explained!
Speed Index, explained!Speed Index, explained!
Speed Index, explained!
 

Kürzlich hochgeladen

%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 

Kürzlich hochgeladen (20)

%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 

Plumbin Pipelines - A Gulp.js workshop