window.c Đóng và self.c Đóng không đóng cửa sổ trong Chrome


174

Vấn đề là khi tôi gọi window.close()hoặc self.close()nó không đóng cửa sổ. Bây giờ dường như có một niềm tin rằng trong Chrome bạn không thể đóng bằng tập lệnh bất kỳ cửa sổ nào không phải là tập lệnh được tạo. Đó là sai một cách rõ ràng nhưng bất kể nó được cho là vẫn làm điều đó, ngay cả khi nó yêu cầu bật lên một cảnh báo để xác nhận. Những điều này không xảy ra.

Vì vậy, có ai có phương pháp đóng cửa sổ thực sự, có chức năng và đã được chứng minh bằng cách sử dụng một cái gì đó giống như javascript:window.close()hoặc javascript:self.close()thực sự làm những gì được mong đợi và điều gì đó xảy ra tốt trong mọi trình duyệt KHÔNG dựa trên Chrome không? Mọi đề xuất sẽ được đánh giá rất cao và tôi đang tìm giải pháp cụ thể cho Javascript, không có gì do JQuery hoặc bên thứ ba triển khai.

Cập nhật: Mặc dù phần lớn những gì đã được đề xuất có những hạn chế nghiêm trọng và các vấn đề về khả năng sử dụng, đề xuất mới nhất (cụ thể cho TamperMonkey) sử dụng // @grant window.closetrong tiêu đề tập lệnh thường sẽ thực hiện thủ thuật ngay cả trên các tab mà thông thường không thể xử lý phương thức đóng. Mặc dù không hoàn toàn lý tưởng và không khái quát cho mọi trường hợp, nhưng đó là một giải pháp tốt trong trường hợp của tôi.


window.close()làm việc cho tôi trong chrome.
mash

3
@ G hèårđïåñ: Umm, không, không. Nó không có gì để làm với ngôn ngữ. Đây là một chức năng được thực hiện bởi các trình duyệt. Nếu bạn có thể viết một ví dụ tối thiểu cho thấy cách thức hoạt window.closeđộng không như ý muốn, tôi nghĩ rằng điều đó có thể hữu ích hơn là nói, "nó không hoạt động".
Máy xay sinh tố

3
Tôi đã cho bạn HAI ví dụ. Đánh vần nó cho bạn,<a href="javascript:window.close">CLOSE</a>
G TiếtårĐïåñ

3
Người giám hộ đó là javascript không đúng. Hãy thử window.close () và nó hoạt động. window.c Đóng chỉ là một tên biến và sẽ không gọi hàm (ít nhất là không khi tôi kiểm tra nó trong chrome 37). Khi tôi thay đổi ví dụ của bạn thành window.c Đóng () nó hoạt động trong chrome 37.
George

3
Gượngårđïåñ Những gì @George nói KHÔNG phải là tranh luận (trừ khi tôi hoàn toàn hiểu sai ý nghĩa của từ này). Anh ấy đúng khi tuyên bố rằng bạn có lỗi cú pháp trong javascript trong các ví dụ của bạn và nếu bạn có cùng một lỗi trong mã ứng dụng, thì đây có thể là nguyên nhân của vấn đề của bạn. Tuy nhiên, nếu đây chỉ là những lỗi chính tả trong ví dụ của bạn, thì bạn nên sửa những lỗi chính tả đó để có câu trả lời tốt hơn.
Superole 6/2/2015

Câu trả lời:


187

Javascript thông thường không thể đóng cửa sổ willy-nilly. Đây là một tính năng bảo mật, được giới thiệu cách đây một thời gian, để ngăn chặn các khai thác độc hại và phiền toái khác nhau.

Từ thông số kỹ thuật mới nhất chowindow.close() :

Các close()phương pháp trên Window đối tượng nên, nếu tất cả các điều kiện sau đây được đáp ứng, gần bối cảnh duyệt Một :

  • Bối cảnh duyệt tương ứng A có thể đóng tập lệnh .
  • Bối cảnh duyệt của kịch bản đương nhiệm là quen thuộc với bối cảnh duyệt Một .
  • Bối cảnh truy cập của kịch bản đương nhiệm được phép để điều hướng các bối cảnh duyệt Một .

Một bối cảnh duyệt có thể đóng được tập lệnh nếu đó là bối cảnh duyệt phụ được tạo bởi tập lệnh (trái ngược với hành động của người dùng) hoặc nếu đó là bối cảnh duyệt có lịch sử phiên chỉ chứa một Tài liệu.

Điều này có nghĩa, với một ngoại lệ nhỏ, javascript không được phép đóng một cửa sổ không được mở bởi cùng một javascript đó.

Chrome cho phép ngoại lệ đó - điều này không áp dụng cho mô tả người dùng - tuy nhiên Firefox thì không. Việc triển khai Firefox không thay đổi :

Phương thức này chỉ được phép gọi cho các cửa sổ đã được mở bởi một tập lệnh bằng window.openphương thức này.


Nếu bạn cố gắng sử dụng window.closetừ Greasemonkey / Tampermonkey / userscript, bạn sẽ nhận được:
Firefox: Thông báo lỗi, " Scripts may not close windows that were not opened by script."
Chrome: chỉ âm thầm thất bại.



Giải pháp lâu dài:

Cách tốt nhất để giải quyết vấn đề này là tạo tiện ích mở rộng Chrome và / hoặc tiện ích bổ sung Firefox thay thế. Chúng có thể đóng cửa sổ hiện tại một cách đáng tin cậy.

Tuy nhiên, vì các rủi ro bảo mật, được đặt ra window.close, ít hơn nhiều đối với tập lệnh Greasemonkey / Tampermonkey; Greasemonkey và Tampermonkey có thể cung cấp hợp lý chức năng này trong API của họ (về cơ bản là đóng gói công cụ mở rộng cho bạn).
Xem xét thực hiện một yêu cầu tính năng.



Cách giải quyết khó khăn:

Chrome hiện dễ bị khai thác "tự chuyển hướng". Vì vậy, mã như thế này được sử dụng để làm việc nói chung:

open(location, '_self').close();

Đây là hành vi lỗi, IMO và hiện tại (tính đến khoảng tháng 4 năm 2015) hầu hết bị chặn. Nó vẫn sẽ hoạt động từ mã được tiêm chỉ khi tab được mở mới và không có trang nào trong lịch sử duyệt web. Vì vậy, nó chỉ hữu ích trong một tình huống rất nhỏ.

Tuy nhiên, một biến thể vẫn hoạt động trên Chrome (v43 & v44) cộng với Tampermonkey (v3.11 trở lên) . Sử dụng một cách rõ ràng @grantvà đơn giản window.close(). VÍ DỤ:

// ==UserScript==
// @name        window.close demo
// @include     http://YOUR_SERVER.COM/YOUR_PATH/*
// @grant       GM_addStyle
// ==/UserScript==

setTimeout (window.close, 5000);

Cảm ơn zanetu đã cập nhật. Lưu ý rằng điều này sẽ không hoạt động nếu chỉ có một tab mở. Nó chỉ đóng các tab bổ sung.


Firefox an toàn trước sự khai thác đó. Vì vậy, cách javascript duy nhất là làm tê liệt các cài đặt bảo mật, mỗi lần một trình duyệt.

Bạn có thể mở lên about:configvà thiết lập
allow_scripts_to_close_windowsđể true.

Nếu kịch bản của bạn là dành cho sử dụng cá nhân, hãy tiếp tục và làm điều đó. Nếu bạn yêu cầu bất kỳ ai khác bật cài đặt đó, họ sẽ thông minh và chính đáng, từ chối với định kiến.

Hiện tại không có cài đặt tương đương cho Chrome.


3
Này bạn của tôi, rất vui khi cuối cùng được nghe từ bạn. Chỉ cần lưu ý, trên Fx bạn có thể bỏ qua giới hạn đó bằng cách lật dom.allow_scripts_to_close_windows;falsesang truenhưng tôi đoán không có gì trong Chrome mà không hack nguồn / xây dựng lại, đó là cách tôi đã khắc phục được. Tôi biết và đã nói chuyện với nhà phát triển TM và trong bản alpha / beta gần đây, chúng tôi đã đặt nó làm tùy chọn tương thích (cài đặt tập lệnh) để chạy theo kiểu trung gian, hoạt động. Tôi đoán ngắn gọn về những vụ hack chúng tôi không có giải pháp sạch sẽ, thương hại.
Gốtårđïåñ

3
Nếu bất cứ ai gặp rắc rối với window.c Đóng hoặc sự khác biệt về hành vi giữa các trình duyệt, hãy đọc câu trả lời này thật cẩn thận - nó thực sự có tất cả thông tin đúng.
Bron Davies

Có cách nào để kiểm tra xem cửa sổ đã được mở bởi script hay chưa? (Tôi cần hiển thị / ẩn nút quay lại, tôi không muốn sử dụng hack) Cảm ơn EDIT: window.opener === null
Cétia

Kể từ Chrome 36.0.1985.125 WEDNESDAY, ngày 16 tháng 7 năm 2014, các cách giải quyết khác có thể không hoạt động, chi tiết trong câu trả lời của tôi.
swcool

2
window.close()sẽ hoạt động trong Tampermonkey nếu bạn đặt @grantthành một giá trị khác none. Xem chủ đề này .
zanetu

32

Chrome Đã sửa lỗi bảo mật trên phiên bản 36.0.1985.125

Chrome 36.0.1985.125 WEDNESDAY, 16 THÁNG 7 NĂM 2014 Ghi chú phát hành

Từ quan sát của tôi, bản cập nhật này đã khắc phục vấn đề sử dụng window.close()để đóng cửa sổ bật lên. Bạn sẽ thấy điều này trong bảng điều khiển khi nó thất bại, "Tập lệnh có thể chỉ đóng các cửa sổ được mở bởi nó." Điều đó có nghĩa là cách giải quyết khó khăn (câu trả lời của Brock Adams) có thể không hoạt động trong phiên bản mới nhất.

Vì vậy, trong các bản dựng được phát hành trước đó của Chrome, khối mã bên dưới có thể hoạt động nhưng không phải với bản cập nhật này.

window.open('', '_self', '');
window.close();

Đối với bản cập nhật này, bạn phải cập nhật mã của mình cho phù hợp để đóng cửa sổ bật lên. Một trong những giải pháp là lấy id cửa sổ bật lên và sử dụng

chrome.windows.remove(integer windowId, function callback)

phương pháp để loại bỏ nó. API cửa sổ mở rộng Chrome có thể được tìm thấy tại chrome.windows .

Trên thực tế, tiện ích mở rộng chrome MarkView của tôi đã gặp phải vấn đề này và tôi đã phải cập nhật mã của mình để làm cho nó hoạt động cho Bản cập nhật Chrome này. Nhân tiện, MarkView là công cụ để đọc và ghi tập tin Markdown tuyệt vời, nó cung cấp các tính năng bao gồm Outline nội dung, Bảng có thể sắp xếp và tô sáng cú pháp khối mã với số dòng.

Tôi cũng đã tạo bài đăng này , bất kỳ ý kiến ​​đều được chào đón.


2
Cách hack chính xác là open(location, '_self').close();- lưu ý việc sử dụng giá trị trả về từ open(). Điều này vẫn hoạt động trên Chrome36.0.1985.125 m
Brock Adams

Trong trường hợp của tôi, tôi chỉ cần kiểm tra lại với open(location, '_self').close();, tôi đã gặp lỗi "Không được phép" về vấn đề này. Lỗi này khác với 'window.close () (warning on this"Scripts may close only the windows that were opened by it."). It looked like open (location,' _elf '). Close (); `di chuyển về phía trước một chút, nhưng nó không thể hoàn thành trong trường hợp của tôi. Cảm ơn @ brock-adams cho ý kiến.
swcool

Tôi có bản in và khi tôi chrome.windows.removenói nó không thể tìm thấy biểu tượng chrome. Làm thế nào tôi có thể giải quyết điều này? Tôi có cần thêm một số loại tài liệu tham khảo?
DevT

@devt chrome.windows.remove là API tiện ích mở rộng của Chrome, javascript của bạn sẽ được chương trình tiện ích chrome của bạn nhận ra. Bạn có thể dùng thử bên trong background.js, trong phần mở rộng chrome của bạn, bạn cần phải có: "nền": {"scripts": ["background.js"], ...},
swcool

Tôi đã gỡ bỏ chức năng đăng nhập MarkView để người dùng truy cập tự do. Vì vậy, ví dụ tôi đã đề cập ở trên hiện không có sẵn.
swcool

21

Trong tampermonkey bây giờ bạn có thể sử dụng

// @grant        window.close

Và sau đó chỉ cần gọi

window.close();

Tôi đã xác nhận rằng điều này hoạt động trong nhiều trường hợp nhưng đôi khi vẫn cứng đầu nhưng tốt hơn là không có gì, cảm ơn bạn. Tôi sẽ thêm nó vào bài viết.
Gốtårđïåñ

2
Cũng như một ghi chú: Không hoạt động với tôi trong Greasemonkey 3.10
mt025

17

Tôi đang sử dụng phương thức được đăng bởi Brock Adams và nó thậm chí còn hoạt động trong Firefox, nếu người dùng bắt đầu.

open(location, '_self').close();

Tôi đang gọi nó từ một lần nhấn nút để nó được người dùng khởi tạo và nó vẫn hoạt động tốt khi sử dụng Chrome 35-40, Internet Explorer 11, Safari 7-8 và CSONG Firefox 29-35. Tôi đã thử nghiệm bằng phiên bản 8.1 của Windows và Mac OS X 10.6, 10.9 & 10.10 nếu khác.


Mã cửa sổ tự đóng (trên trang tự đóng)

Mã hoàn chỉnh sẽ được sử dụng trên cửa sổ do người dùng mở có thể tự đóng:

window_to_close.htmlm

JavaScript:

function quitBox(cmd)
{   
    if (cmd=='quit')
    {
        open(location, '_self').close();
    }   
    return false;   
}

HTML:

<input type="button" name="Quit" id="Quit" value="Quit" onclick="return quitBox('quit');" />

Hãy thử trang thử nghiệm này: (Hiện đã được thử nghiệm trong Chrome 40 và Firefox 35)

http://browserstranguity.bitbucket.io/window_close_tester.htmlm


Mã cửa sổ mở (trên một trang mở ra trang trên)

Để thực hiện công việc này, khả năng tương thích trình duyệt chéo áp đặt bảo mật yêu cầu cửa sổ phải đóng phải được mở bởi người dùng nhấp vào nút trong cùng một tên miền.

Ví dụ: cửa sổ sử dụng phương thức trên để tự đóng, có thể được mở từ một trang bằng mã này (mã được cung cấp từ trang ví dụ của tôi được liên kết ở trên):

window_close_tester.htm

JavaScript:

function open_a_window() 
{
    window.open("window_to_close.htm"); 

    return false;
}

HTML:

<input type="button" onclick="return open_a_window();" value="Open New Window/Tab" />

Quên về các ngoại lệ do người dùng bắt đầu; nắm bắt tốt. Tôi nghĩ rằng hầu hết người dùng muốn hoạt động hoàn toàn tự động mặc dù. Họ đã có một cơ chế đóng tiện dụng, do người dùng khởi xướng - chữ X nhỏ ở phía trên bên phải. (^
Brock Adams

1
Bằng cách nào đó, điều này không làm việc cho tôi. Cả trên firefox 30 cũng như trên Chrome 37. Tất cả những gì nó làm là khiến trang trở nên trống rỗng (hành vi thực sự kỳ lạ). Mã của tôi là <button onclick="open(location,'_self').close()" >Close Window</button>. Tôi đang làm một cái gì đó rõ ràng sai? Dường như với tôi rằng đây cũng là người dùng bắt đầu. Lưu ý rằng tôi nhận được kết quả tương tự nếu tôi sử dụng một <button>hoặc một <input type="button">.
LordOfThePigs

Đã thêm một trang thử nghiệm ở trên trong câu trả lời cho bạn.
Jeff Clayton

@YumYumYum cảm ơn vì bài đăng, bitbucket.org đã thay đổi liên kết đến bitbucket.io gần đây - đã sửa trong câu trả lời ngay bây giờ
Jeff Clayton

Nó hoạt động với tôi (có một nút trên trang để đóng cửa sổ). Những gì không hoạt động là: window.open('', '_self', ''); window.close(); nhưng nó đã làm việc với open(location, '_self').close();
kstallonen

10

Nhiều người vẫn đang cố gắng tìm cách đóng trình duyệt Chrome bằng javascript. Phương pháp sau chỉ hoạt động khi bạn sử dụng Chrome làm trình khởi chạy APP - kiosk chẳng hạn!

Tôi đã thử nghiệm như sau:

Tôi đang sử dụng tiện ích mở rộng sau: Đóng Kiosk

Tôi đang làm theo hướng dẫn sử dụng và có vẻ như nó hoạt động tốt (đảm bảo bạn xóa bộ nhớ cache trong khi thực hiện các bài kiểm tra). Các javascript tôi sử dụng là (đính kèm với nhấp vào sự kiện):

window.location.href = '/closekiosk';

Tôi hy vọng điều đó sẽ giúp được ai đó, vì đó là giải pháp làm việc duy nhất tôi tìm thấy.

Lưu ý: Có vẻ như tiện ích mở rộng chạy ở chế độ nền và thêm biểu tượng khay Chrome. Nó có tùy chọn sau được chọn: "Để Chrome chạy ở chế độ nền" (hoặc văn bản tương tự). Bạn có thể cần phải chơi với nó, cho đến khi nó làm việc cho bạn. Tôi đã bỏ chọn nó và bây giờ nó hoạt động tốt!


9

Mặc dù nghĩ rằng đó là "sai một cách rõ ràng", nhưng những gì bạn nói "dường như là một niềm tin" thực sự chính xác. Tài liệu Mozilla cho window.c Đóng nói

Phương thức này chỉ được phép gọi cho các cửa sổ đã được mở bởi một tập lệnh bằng phương thức window.open. Nếu cửa sổ không được mở bởi tập lệnh, lỗi sau sẽ xuất hiện trong Bảng điều khiển JavaScript: Tập lệnh có thể không đóng cửa sổ không được mở bởi tập lệnh

Bạn nói rằng đó là "đáng lẽ vẫn phải làm" nhưng tôi không nghĩ rằng bạn sẽ tìm thấy bất kỳ tài liệu tham khảo nào hỗ trợ điều đó, có lẽ bạn đã đánh giá sai điều gì đó?


9

Tôi tìm thấy một cách mới phù hợp với tôi

var win = window.open("about:blank", "_self");
win.close();

1
đây là năm 2017 và tôi vẫn nhận được lỗi "Tập lệnh có thể không đóng các cửa sổ không được mở bởi tập lệnh."
Rotimi

Hack đẹp cho nút xác nhận của IE 11.
Gopal00005

Hoạt động trên Chrome và Firefox
Vineeth Pradhan

1
Lỗ này có vẻ đã được lấp đầy. Tôi không biết từ khi nào nhưng tôi đang sử dụng bản dựng mới nhất 84.x. Các trang trống tải nhưng đóng không kích hoạt.
Scott Christensen

4

Mã dưới đây làm việc cho tôi -

window.open('location', '_self', '');
window.close();

Đã thử nghiệm trên Chrome 43.0.2357.81


Bạn có thể thêm phiên bản Chrome của mình không?
Stephan

Phiên bản chrome của tôi là 43.0.2357.81.
DfrDkn

7
Đối với tôi chỉ cần thay thế cửa sổ hiện tại, với một cửa sổ tại / location.
alianos-

@ alianos- đối với tôi cũng vậy.
RicardoGonzales

1
Không hoạt động trong chrome mới nhất - Phiên bản 61.0.3163.100 (Bản dựng chính thức) (64-bit)
Subhajit

1

Điều này có thể cũ, nhưng hãy trả lời nó.

Tôi sử dụng top.close () để đóng một tab. window.close () hoặc mở khác ... đóng không hoạt động với tôi.


11
Điều này cũng bị "Scripts may not close windows that were not opened by script."vấn đề được đề cập trong các câu trả lời khác.
kad81

1
xin vui lòng đưa ra giải pháp cho câu trả lời của bạn. xin vui lòng không thảo luận vấn đề chỉ trên câu trả lời của bạn.
Bimal Das

0

Trong trường hợp của tôi, trang cần đóng, nhưng có thể đã được mở bởi một liên kết và do đó window.closesẽ thất bại.

Giải pháp tôi chọn là phát hành window.close, theo sau window.setTimeoutlà chuyển hướng đến một trang khác.

Bằng cách đó, nếu window.closethành công, việc thực thi trên trang đó dừng lại, nhưng nếu thất bại, trong một giây, nó sẽ chuyển hướng đến một trang khác.

window.close();
window.setTimeout(function(){location.href = '/some-page.php';},1000);

0

Câu trả lời này từ Brock có được nó làm việc cho tôi. javascript không được phép đóng một cửa sổ không được mở bởi cùng một javascript đó.

Tôi chỉ có thể đóng cửa sổ con nếu tôi sẽ đóng nó từ javascript cha. Vì vậy, trong cha mẹ tôi, tôi có thể làm một cái gì đó như thế này.

var myChildWindow;

function openWindow(){
myChildWindow = window.open("","myChildWindow","width=400,height=400");
}

function closeWindow() {
myChildWindow.close();
}

-1

Bạn cũng có thể thử sử dụng mã của tôi dưới đây. Điều này cũng sẽ giúp bạn chuyển hướng cửa sổ cha mẹ của bạn:

Cha mẹ:

<script language="javascript">

function open_a_window() 
{
    var w = 200;
        var h = 200;
        var left = Number((screen.width/2)-(w/2));
        var tops = Number((screen.height/2)-(h/2));

        window.open("window_to_close.html", '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+tops+', left='+left);

   return false;
}

// opener:
window.onmessage = function (e) {
  if (e.data === 'location') {
    window.location.replace('https://www.google.com');
  }
};

</script>

<input type="button" onclick="return open_a_window();" value="Open New Window/Tab" />

Popup:

<!DOCTYPE html>
<html>
<body onload="quitBox('quit');">

<h1>The window closer:</h1>

<input type="button" onclick="return quitBox('quit');" value="Close This Window/Tab" /> 


<script language="javascript">

function quitBox(cmd) 
{      
    if (cmd=='quit')    
    {   
       window.opener.postMessage('location', '*');
       window.open(location, '_self').close();    
    }     
    return false;   
}

</script>

</body>
</html>


-2

Chỉ khi bạn mở một cửa sổ mới bằng window.open () thì cửa sổ mới có thể đóng bằng mã như tôi đã đề cập ở trên. Điều này hoạt động hoàn hảo đối với tôi :) Lưu ý: Không bao giờ sử dụng href để mở trang trong tab mới. Window.close () không hoạt động với "href". Sử dụng window.open () thay thế.


1
Nó chỉ là thay thế cửa sổ hiện tại. Không còn nữa.
RicardoGonzales

-3

Tôi muốn chia sẻ "giải pháp" của mình với vấn đề này. Có vẻ như hầu hết chúng ta đang cố gắng đóng cửa sổ trình duyệt trong phiên trình duyệt tiêu chuẩn, nơi người dùng đang truy cập trang web này hoặc trang web khác, sau khi họ truy cập các trang web khác và trước khi họ truy cập thêm.

Tuy nhiên, tình huống của tôi là tôi đang xây dựng một ứng dụng web cho một thiết bị về cơ bản sẽ là điều duy nhất mà thiết bị làm. Bạn khởi động nó, nó khởi chạy Chrome và điều hướng đến ứng dụng của chúng tôi. Nó thậm chí không được kết nối với internet, bất kỳ máy chủ nào mà nó nói đến đều nằm trên các container Docker cục bộ của chúng tôi. Người dùng cần một cách để đóng ứng dụng (còn gọi là đóng Chrome) để họ có thể truy cập thiết bị đầu cuối để thực hiện cập nhật hệ thống.

Vì vậy, nó khởi động, khởi chạy Chrome ở chế độ kiosk, theo đúng địa chỉ. Điều này xảy ra để dễ dàng đáp ứng tùy chọn thứ hai trong thông số kỹ thuật:

Ngữ cảnh duyệt có thể đóng tập lệnh nếu đó là bối cảnh duyệt phụ được tạo bởi tập lệnh (trái ngược với hành động của người dùng) hoặc nếu đó là bối cảnh duyệt cấp cao nhất có lịch sử phiên chỉ chứa một Tài liệu.

Vì vậy, chỉ cần gọi window.close()từ ứng dụng kiosk của tôi chỉ hoạt động !


-5

Hãy thử một cái gì đó như thế này onclick = "return self.close ()"

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.