প্রোটো স্পেস হানাদার (আপনি কি এটি ব্লিট করতে পারেন?)


18

প্রোটো স্পেস হানাদাররা

এটি একটি গ্রাফিকাল আউটপুট চ্যালেঞ্জ যেখানে ভাষায় প্রতি সংক্ষিপ্ততম কোড দেওয়া কাজটি।

কার্য

আপনার কোডটি ব্যবহারকারীকে নিম্নলিখিত এলিয়েনটিকে স্ক্রিন / উইন্ডোর আশেপাশে সরাতে দেওয়া উচিত।

এখানে চিত্র বর্ণনা লিখুন

আপনার কোডটি কেবল একটি স্থানীয় ফাইল থেকে লোড করতে পারে। এটিকে অন্য একটি আদর্শ চিত্রের ফর্ম্যাটে রূপান্তর করতে বা এমনকি ছবিতে ছোট পিক্সেল ত্রুটিগুলি যা মন্তব্যগুলিতে উল্লেখ করা হয়েছে তা নির্ধারণ করতে দ্বিধা বোধ করবেন না।

পটভূমিটি সাদা হওয়া উচিত এবং উইন্ডো / স্ক্রিনটি কমপক্ষে 400 পিক্সেল দ্বারা 400 পিক্সেল হওয়া উচিত। যদি আপনার ভাষা যদি উইন্ডো / স্ক্রিনগুলি এত বড় সমর্থন করে না তবে এটি বৃহত্তম আকার ব্যবহার করে যতক্ষণ না এটি 200 বাই 200 এর চেয়ে কম নয় support

স্ক্রিনের আশেপাশে এলিয়েনটিকে সরাতে কোডের একটি মানক কীবোর্ডের তীর কীগুলি ব্যবহার করে উপরে / নিচে / বাম / ডান সমর্থন করা উচিত।

আপনার কোডটি একটি পূর্ণ প্রোগ্রাম হওয়া উচিত

বিধিনিষেধ / সীমাবদ্ধতা

এলিয়েনের সীমানায় থামানো উচিত। এটি একটি অভিন্ন হারে সরানো উচিত সহজে কোনো দৃশ্যমান ঝিকিমিকি বা তোতলামি সঙ্গে এবং অন্তত 24fps এ দেখানো হবে। স্ক্রিন / উইন্ডোর একপাশ থেকে অন্য দিকে যেতে 2 থেকে 5 সেকেন্ডের মধ্যে সময় লাগবে।

ভাষা ও গ্রন্থাগার

আপনি পছন্দ করেন এমন কোনও ভাষা বা গ্রন্থাগার ব্যবহার করতে পারেন (এটি এই চ্যালেঞ্জের জন্য তৈরি করা হয়নি)। তবে আমি চাইলে আপনার কোডটি পরীক্ষা করতে সক্ষম হতে চাই তাই আপনি যদি উবুন্টুতে এটি কীভাবে চালাতে চান তার জন্য পরিষ্কার নির্দেশনা সরবরাহ করতে পারেন যা খুব প্রশংসিত হবে।

তালিকা

এই পোস্টের নীচে স্ট্যাক স্নিপেট উত্তরগুলি থেকে ক্যাটালগ তৈরি করে a) ভাষার প্রতি সংক্ষিপ্ত সমাধানের তালিকা হিসাবে এবং খ) সামগ্রিক লিডারবোর্ড হিসাবে।

আপনার উত্তরটি প্রদর্শিত হয়েছে তা নিশ্চিত করার জন্য, দয়া করে নীচের মার্কডাউন টেম্পলেটটি ব্যবহার করে আপনার উত্তরটি শিরোনাম দিয়ে শুরু করুন:

## Language Name, N bytes

Nআপনার জমা দেওয়ার আকারটি কোথায় ? আপনি যদি নিজের স্কোরটি উন্নত করেন তবে আপনি পুরানো স্কোরগুলি শিরোনামে রেখে দিতে পারেন । এই ক্ষেত্রে:

## Ruby, <s>104</s> <s>101</s> 96 bytes

যদি আপনি নিজের শিরোনামে একাধিক সংখ্যা অন্তর্ভুক্ত করতে চান (যেমন আপনার স্কোর দুটি ফাইলের সমষ্টি বা আপনি পৃথকভাবে দোভাষী পতাকা দণ্ডের তালিকা করতে চান), নিশ্চিত করুন যে আসল স্কোরটি শিরোনামের শেষ সংখ্যা:

## Perl, 43 + 2 (-p flag) = 45 bytes

আপনি ভাষাটির নামটিকে একটি লিঙ্কও তৈরি করতে পারেন যা স্নিপেটে প্রদর্শিত হবে:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


2
আমরা কি ভিনগ্রহকে তৈরি করতে পারি? যদি তা হয়, তবে ছবি থেকে পিক্সেল ত্রুটিগুলি (আমার অনুমান?) অন্তর্ভুক্ত করতে হবে?
mınxomaτ

@ mınxomaτ এটি লিনাক্সের মধ্যে সীমাবদ্ধ নয়! "সম্ভব হলে" নোট করুন।

@ নিমি ধন্যবাদ যোগ করা হয়েছে যে আপনি এটি একটি স্থানীয় ফাইল থেকে লোড করতে পারেন।

@ mınxomaτ আপনি নিজে এটি তৈরি করতে পারেন বা একটি স্থানীয় ফাইল থেকে এটিকে লোড করতে পারেন। আমি পিক্সেল ত্রুটিগুলি লক্ষ্য করিনি তবে আমি ধরে নিয়েছি যে এটি লোড করা কোনও ক্ষেত্রেই কম কোড হবে।

আপনি কি "সীমান্তে থামুন" সংজ্ঞা দিতে পারেন? পুরো এলিয়েন কি সর্বদা দৃশ্যমান হওয়া দরকার, বা এটি সীমানার বাইরে আংশিকভাবে থামতে পারে?
টিমোথিমহ

উত্তর:


12

স্ক্র্যাচ , 221 217 বাইট

চিত্রটি এটি কার্য করতে দেখতে ক্লিক করুন। আন্দোলনটি কী-স্ট্রোক দ্বারা নির্ধারিত হয় , তাই আপনার কী পুনরাবৃত্তি সেট করা তত দ্রুততর মসৃণ হবে।

ইমেজ প্রকল্পের মধ্যে অন্তর্ভুক্ত করা হয়েছে, কিন্তু ভূত বাইট সাধারণত golfed থেকে গণনা করা হয় পাঠগত উপস্থাপনা , প্রতি এই মেটা পোস্টে । এটি গ্রহণযোগ্য কিনা (বা চলাচল যথেষ্ট মসৃণ কিনা) তা নিয়ে যদি মতানৈক্য হয় তবে আমাকে জানান এবং আমি এটিকে ঘিরে কাজ করার চেষ্টা করব।


এই উত্তরটি অনেক মজাদার!

আপনি এই প্রোগ্রামটির আকারটি কীভাবে পরিমাপ করলেন?

@ ল্যাম্বিক দ্বিতীয় অনুচ্ছেদ দেখুন।
টিমোথিমহ

1
217 বাইটে উত্পন্ন: scratchblocks.github.io/...
ev3commander

1
@ মরিস হ্যাঁ, এটি "যদি প্রান্তে, বাউন্স" কমান্ডের যত্ন নেয়। আপনি ছবিতে ক্লিক করে ডেমো খেলতে পারেন!
টিমোথিমহ

7

প্রসেসিং 2, 219 199 241 220 219 বাইট

int a,x=0,y=0;void setup(){size(500,500);}void draw(){background(-1);image(loadImage(".png"),x,y);if(keyPressed){a=keyCode;if(a==38)y--;if(a==37)x--;if(a==40)y++;if(a==39)x++;}x=constrain(x,0,436);y=constrain(y,0,454);}

চিত্রটি .png.pde হিসাবে একই ডিরেক্টরিতে সংরক্ষণ করা প্রয়োজন


6

পাইথন 2, 262 253 246 240 বাইট

from pygame import*
init()
key.set_repeat(1)
p=[0,0]
d=display
c=d.set_mode((400,)*2)
while c.fill((255,)*3):
 e=event.get(2);c.blit(image.load("I"),p);d.flip()
 if e:x=e[0].key+1;q=x&2;b=q/2;p[b]=max(0,min(336+b*16,p[b]+(1-q)*(1-(2*x&2))))

কি দারুন. হ্যাকারি অনেক কি।

মডিউল 'pygame' এ পাওয়া ব্যবহার http://pygame.org

ব্যাখ্যা

key.set_repeat(1) - প্রতি মিলি সেকেন্ডে ইভেন্ট সিস্টেমের মাধ্যমে পুনরাবৃত্তি কী ইভেন্টগুলি প্রেরণ করুন

c=d.set_mode((400,)*2) - 400x400 প্রদর্শন পৃষ্ঠটি তৈরি করুন

while c.fill((255,)*3):- কার্যকরভাবে while 1:কিন্তু পাশাপাশি পর্দা সাফ করে

e=event.get(2);c.blit(image.load("I"),p);d.flip()- কেবল কীবোর্ড ইভেন্টগুলি সংগ্রহ করুন, বলা একটি পিএনজি ফাইলে সংরক্ষিত চিত্রটি লোড করুন Iএবং এটিকে আঁকুন। স্ক্রিন আপডেট করুন

if e:x=e[0].key+1;q=x&2;b=q/2;p[b]=max(0,min(336+b*16,p[b]+(1-q)*(1-(2*x&2)))) - যদি কোনও ঘটনা ঘটে থাকে তবে কোন তীর কীটি টিপানো হয়েছিল (আপনি যদি অন্য কীগুলি টিপ করেন তবে কি অদ্ভুত জিনিসগুলি রয়েছে) কাজ করুন এবং তারপরে আপনি কোন কীটি চাপলেন তার উপর নির্ভর করে পৃষ্ঠের অবস্থান পরিবর্তন করুন।


আমি আপনার সমাধানটি সত্যিই পছন্দ করি।

@ ল্যাম্বিক তাই একটি একক বাইট ফাইলের নাম অনুমোদিত? (মানে এক্সটেনশন ছাড়াই?) যদি তা হয় তবে আমি ফাইলের নামগুলি বাইট গণনা থেকে সম্পূর্ণ বাদ দিতে পরামর্শ দিই।
mınxomaτ

@ mınxomaτ আমি একক বাইট ফাইলের নাম অনুমোদিত কিন্তু আমি নতুন স্কোরিং স্কিম আবিষ্কার করতে চাই না।

@ ল্যাম্বিক প্রসেসিং একক-বাইট ফাইলের নামগুলি পরিচালনা করতে পারে না ... সুতরাং এটি অন্যায্য।
TheDoctor

2
@ দ্য ডক্টর এটি ঠিক এতে: বিভিন্ন ভাষা আলাদা! আমি প্রস্তাব দিয়েছি যে আমরা স্টিডিনের কাছ থেকে ইনপুট নেওয়া চ্যালেঞ্জগুলিও বর্জন করি, আপনি জানেন, কারণ পাইথনে এটি করতে
এতগুলি

5

হাস্কেল, 410 বাইট

import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game
main=do b<-loadBMP"b";play(InWindow""(400,400)(0,0))white 200((0,0),id)(b#)e(%)
e(EventKey(SpecialKey k)Down _ _)(c,_)|k==KeyUp=(c,fmap(+1))|k==KeyDown=(c,fmap(+(-1)))|k==KeyLeft=(c,((+(-1))?))|k==KeyRight=(c,((+1)?))
e(EventKey _ Up _ _)(c,_)=(c,id)
e _ w=w
_%(c,f)=(s?(s<$>f c),f)
s=min 200.max(-200)
b#((x,y),_)=Translate x y b
f?(a,b)=(f a,b)

নামের একটি ফাইলের মধ্যে এলিয়েনের ছবি আশা করা bযায়.bmp বিন্যাস।

আমি গ্লস লাইব্রেরিতে নতুন, তাই সম্ভবত এটি অনুকূল নয়। ট্র্যাকিং KeyUp/ এর পরিবর্তে কোনও কী চাপানো হয়েছে কিনা তা আমি জানতে পারি কিনা তা কি কেউ জানেন?KeyDown ইভেন্টগুলির ?

এটি কীভাবে কাজ করে: এর সর্বশেষ চারটি পরামিতি playহ'ল বিশ্ব রাষ্ট্র (এর সাথে সূচনা করা ((0,0),id), একটি রাজ্য থেকে চিত্র আঁকার ফাংশন #), ইভেন্ট হ্যান্ডলার ( e) এবং সময়ের সাথে সাথে রাষ্ট্র পরিবর্তন করে এমন একটি ফাংশন %

রাজ্যটি এক্স-কোঅর্ডিনেটের একটি জুড়ি এবং যখনই %ডাকা হয় তখন কীভাবে এগুলি পরিবর্তন করা যায় তা একটি ফাংশন ।

#বিটম্যাপ ( b) বর্তমান স্থানাঙ্কে সরানো হয় এবং এটি আঁকুন।

eপারেন জন্য দেখায় KeyDownরাজ্যের বা কার্সার কী ও সেট উপযুক্ত ফাংশন ঘটনা KeyUpযে কোনো একটি কি পরিচয় ফাংশন রাজ্যের ফাংশন পুনরায় সেট করতে।

% রাজ্য থেকে বর্তমান স্থানাঙ্কে ফাংশন প্রয়োগ করে এবং সীমানা পরীক্ষা করে।


আমি সর্বদা আশ্চর্য হয়েছি আপনি এমনকি হাস্কেলের মধ্যে এই ধরণের কাজ করতে পারেন। ধন্যবাদ!

4

এলম, 240 বাইট

import Graphics.Element as G
import Keyboard as K
import Time
import Signal exposing(..)
c=min 800>>max 64
i(x,y)=G.container x y G.middle(G.image 64 48"http://i.stack.imgur.com/CUweU.png")
main=i<~foldp(\{x,y}(v,w)->(c v+x,c w-y))(99,99)(sampleOn(Time.fps 200)K.arrows)

এখানে চেষ্টা করুন । বাইট গণনাটি ইউআরএল প্রতিস্থাপনের পরে .png


আমাকে এখন এলম শিখতে হবে। ধন্যবাদ.

3

অটোআইটি , 269 267 বাইট

#include<Misc.au3>
GUICreate(0,-1,-1,-1,-1,-1,34078728)
$0=GUICtrlCreatePic("b.bmp",0,0,64,48)
GUISetState()
Dim $1,$2
$3=_IsPressed
Do
$1+=$3("27")-$3("25")
$2+=$3("28")-$3("26")
$1=($1>336)?336:($1<0)?0:$1
$2=($2>352)?352:($2<0)?0:$2
GUICtrlSetPos($0,$1,$2)
Until 0

স্ক্রিপ্ট ডিরেক্টরিতে ছবিটি b.bmp হিসাবে সংরক্ষণ করা প্রয়োজন। আপনি যদি সত্যিকারের স্বচ্ছতার সাথে কোনও ছবি ব্যবহার করতে চান তবে আপনাকে এটি পিএনজি থেকে 32 বিট বিটম্যাপে রূপান্তর করতে হবে (ওটি: একটি সত্যিকারের অপ্রকাশিত বিন্যাস)।

ব্যাখ্যা

Misc.au3অ্যাক্সেস পেতে আমাদের আমদানি করতে হবে _IsPressed। একটি ফাংশন যা একটি মূল কোড গ্রহণ করে এবং ফেরত দেয় TrueবাFalse কী টিপে গেলে।

আমাদের 400px বর্গক্ষেত্রের উইন্ডোটি তৈরি করতে যেভাবে চ্যালেঞ্জটির চিত্রটি বেশ দুর্দান্ত। ডিফল্ট (হিসাবে চিহ্নিত -1বা হিসাবে Default) আকারের প্যারামিটারগুলি 400x400। বর্ধিত জানালা শৈলী সেট করা হয় 34078728। এটি উইন্ডোটিকে ডাবল-বাফার করে নীচে থেকে উপরে টেনে তুলতে বাধ্য করে। চ্যালেঞ্জের প্রয়োজনীয়তা অনুযায়ী ঝাঁকুনি দূর করতে এটি প্রয়োজনীয়। উইন্ডোজ 10-এ, শৈলীর এই অস্বাভাবিক (এবং কিছুটা অপ্রকাশিত) সংমিশ্রণ উইন্ডো শিরোনাম বারটিকে ভেঙে দেয় (সমস্ত হোভারিং এফেক্টগুলি অক্ষম করা হয়)।

$1এবং $2ঘোষণা করা হয় এবং এক্স রাখা হবে এবং y ছবি নিয়ন্ত্রণ দ্বারা লোড অফসেট $0। কোডটি উল্লেখযোগ্যভাবে সংক্ষিপ্ত করতে $3ফাংশনের পয়েন্টার হয়ে ওঠে _IsPressed

যেহেতু প্রোগ্রামটি থেকে বেরিয়ে আসতে সক্ষম হওয়ার প্রয়োজন নেই, তাই এই স্ক্রিপ্টটি অসীম লুপে চলে ( Until 0)।

$1+=$3("27")-$3("25")অটোআইটিতে ভেরিয়েন্ট ডেটাটাইপকে _IsPressedগালিচালিত করে বুলিয়ান মান থেকে পূর্ণসংখ্যায় ফেরত যা এক্স অফসেট থেকে যোগ বা সাব'ড করা যায়। ওয়াই এর জন্য একই। $1=($1>336)?336:($1<0)?0:$1সীমান্তে এলিয়েনকে থামাতে সীমানা পরীক্ষা করতে সি-জাতীয় ভাষা থেকে জানা টের্নারি অপারেটর ব্যবহার করে।

GuiCtrlSetPos চিত্র নিয়ন্ত্রণ নিয়ন্ত্রণকে নতুন স্থানাঙ্কে নিয়ে যায়।

এখানে স্বচ্ছ এলিয়েন সহ একটি স্ক্রিনশট রয়েছে (আপনি এমনকি তির্যকভাবে স্থানান্তর করতে পারেন):

স্ক্রিনশট


আপনার পটভূমি সাদা না!
সার্জিওল

2

লুয়া + LÖVE, 291 টি অক্ষর

x=0
y=0
l=love
g=l.graphics
l.window.setMode(400,400)
i=g.newImage("i")
function l.update()d=l.keyboard.isDown
if d("left")and x>0 then x=x-1 end
if d("right")and x<336 then x=x+1 end
if d("up")and y>0 then y=y-1 end
if d("down")and y<352 then y=y+1 end
end
function l.draw()g.draw(i,x,y)end

এটি একটি অবিস্মরণীয় 400 x 400 উইন্ডো ব্যবহার করে। সামঞ্জস্য করার ক্ষেত্রে আমার কোনও সাফল্য ছিল নাlove.keyboard.setKeyRepeat()কী পড়ার গতি বাড়ানোর করার ক্ষেত্রে , তাই আমি প্রতিটি কীটির স্থিতি পোলিং করে প্রস্তাবিত উপায়ে করেছি।

যেহেতু লুয়ার সাথে আমার সম্পর্কটি forসর্বোত্তম নয়, এই সময়টি প্রতিটি কী-র শর্তের ডাম্প হার্ডকোডিংয়ের চেয়ে লুপিংকে আরও ছোট করতে সক্ষম হয়েছিল।


2

স্পেসবিএএস - 285 255 বাইট

1 GRAPHIC NEW v LOAD "inv8.bmp" TRANSPARENT 15
2 PALETTE COPY v,0,1 TO 5: GRAPHIC REMAP v
3 LET x,y=100
4 CLS : WINDOW PUT GRAPHIC v,0,x,y
5 LET x=x+KEYST(39)-KEYST(37),y=y+KEYST(40)-KEYST(38)
6 LET x=CLAMP(x,1 TO 400),y=CLAMP(y,1 TO 400)
7 WAIT SCREEN 
8 GO TO 4

চিত্রটি লোড করুন - রঙ 15 উজ্জ্বল সাদা, যাতে এটি স্বচ্ছ হয়ে যায়।

আসল চিত্র এবং ডিফল্ট স্পেসবিএএস প্যালেটটি ব্যবহার করে এটি কিছুটা বিজোড় হয়ে উঠেছে, সুতরাং লাইন 2 ইনপুট চিত্রটি মেলানোর জন্য তাদের চারপাশে স্যুইচ করে। চিত্রের নীচে দেখায় যে এটি লাইন 2 এবং তার পরে কেমন দেখাচ্ছে।

এখানে চিত্র বর্ণনা লিখুন

ক্ল্যাম্প কমান্ড গ্রাফিককে উভয় দিকের মধ্যে 1 এবং 400 এর মধ্যে সীমাবদ্ধ করে, যদি বেশ কয়েকটি আইএফ ... তারপরে বিবৃতিতে সংরক্ষণ করে।

লাইন 9 কেবল জিনিসগুলি ধরার জন্য অপেক্ষা করে এবং ঝাঁকুনি প্রতিরোধ করে।

এটি কোন কী টিপিত হয় তার বুলিয়ান চেকের ভিত্তিতে একবারে একটি পিক্সেল স্থানান্তরিত করে, তাই পাশ থেকে পাশ যেতে 5 সেকেন্ডের চেয়ে কিছুটা বেশি সময় লাগে।


2

জুতো সহ রুবি, 252 243 টি অক্ষর

Shoes.app{background white
i=image'i'
m=[0,0]
a=[:width,:height]
animate(99){i.left+=m[0]<=>i.left
i.top+=m[1]<=>i.top}
keypress{|k|d,v={?u=>[1,-1],?d=>[1,1],?l=>[0,-1],?r=>[0,1]}[k[0]];m[d]=[[m[d]+v*4,self.send(p=a[d])-i.send(p)].min,0].max}}

এটি ডিফল্ট x০০ x ৫০০ থেকে শুরু করে একটি আকার পরিবর্তনযোগ্য উইন্ডো ব্যবহার করে the

প্রয়োজনীয়তাগুলি পূরণ করার কৌশলটি হ'ল আক্রমণকারীর অবস্থান 4 এর ইনক্রিমেন্টে পরিবর্তিত হয় তবে প্রকৃত চলাচল প্রতি সেকেন্ডে 99 ফ্রেমে 1 বর্ধিত হয় made


2

টিসিএল / টাকা , 242 বাইট

grid [canvas .c -w 400 -he 403 -bg #FFF -highlightt 0]
.c cr i 30 24 -i [image c photo -fi .png] -t p
lmap {k b x y} "Up 1]>25 0 -5 Right 0]<368 5 0 Down 1]<376 0 5 Left 0]>30 -5 0" {bind . <$k> "if \[lindex \[.c coo p] $b {.c move p $x $y}"}

এটি যে কোনও লিনাক্সে চালাতে: আপনার অবশ্যই টিসিএল এবং টাকা ইনস্টলড থাকতে হবে; তারপরে কোনও ফাইলটিতে কোডটি অনুলিপি করুন, আসুন বলি invaders.tcl; আপনার .pngএকই ফোল্ডারের মতো চিত্রটি সংরক্ষণ করাও দরকার । স্ক্রিপ্টটি চালাতে wish invaders.tcl একটি শেল টাইপ করুন । পিএস: কোডটি পরিবর্তে একটি ইন্টারেক্টিভ শেলটিতে পেস্ট করা থাকলে এটি আরও গল্ফ হতে পারে, কারণ এটি ডিফল্ট সংক্ষেপিত কমান্ড দ্বারা সমর্থন করে।
sergiol

1

জাভাস্ক্রিপ্ট (কাগজ.জেএস ব্যবহার করে), 215 বাইট

v=new Raster("http://i.stack.imgur.com/CUweU.png",99,99);p=new Size(4,0)
onFrame=e=>{if(!v.isInside(view.bounds)){p=-p};v.position+=p}
onKeyDown=e=>{p=new Size([[0,-4],[0,4],[-4,0],[4,0]]["udlr".indexOf(e.key[0])])}

কাগজ.জেএস একটি জেএস গ্রাফিক্স ফ্রেমওয়ার্ক, যার অর্থ এটি চিত্রের ম্যানিপুলেশন সম্পর্কিত অনেক দরকারী বৈশিষ্ট্যযুক্ত। চালানোর জন্য, উপরেরটি এখানে বাম দিকের অংশে অনুলিপি করুন , তারপরে, এলিয়েনকে প্রায় ঘুরিয়ে আনতে, ফোকাস দেওয়ার জন্য ডান বিভাগে একবার ক্লিক করুন। যদি আপনার ব্রাউজারটি এটি পরিচালনা করতে পারে তবে এটি 60fps এ চালানো উচিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.