Codebase list pysmb / 58d3de4b-c4ff-4a2a-b125-a6d48468e345/upstream/1.2.8
Import upstream version 1.2.8 Kali Janitor 1 year, 5 months ago
191 changed file(s) with 35855 addition(s) and 19320 deletion(s). Raw diff Collapse all Expand all
0 pysmb-1.2.8, 12 Jun 2022
1 ========================
2
3 - Fix issue with listPath based on recommendation in #195
4 - Fix embedded MD4 algorithm
5 - Add SMB UTF-16 surrogate exception workaround policy
6
7 pysmb-1.2.7, 30 May 2021
8 ========================
9
10 - Fix compatibility issues on file retrievals with Likewise servers (#177)
11 - Improve SMBConnection's connect() method to remove the need to provide sock_family
12 parameter for IPv6 addresses in Python 3.x (#180)
13
14 pysmb-1.2.6, 9 Dec 2020
15 =======================
16 - Fix bug in SMB1 store file implmentation which generates SMB_COM_WRITE_ANDX
17 packets larger than the allowed max buffer size (#175)
18
19 pysmb-1.2.5, 18 Oct 2020
20 =======================
21 - Fix bug in filename encoding which leads to failure for file retrieval and upload operations (#170 #171).
22 - Improve resetFileAttributes() method in SMBConnection class to allow the
23 new attribute to be specified in the reset operation (#172).
24
25 pysmb-1.2.4, 6 Oct 2020
26 =======================
27 - Remove dependency on pycrypto as it is no longer under active maintenance
28
29 pysmb-1.2.3, 6 Oct 2020
30 =======================
31 - Fix bug in session key generation during session negotiation (#166)
32 - Fix bug in SMB message signing which leads to operation failures with Samba services.
33
34 pysmb-1.2.2, 5 Sep 2020
35 =======================
36 - Improve SMB URL handlers to support specifying server's machine name and IP
37 address. (#162)
38 - Improvements to documentation on SMB URLs (#160)
39
40 pysmb-1.2.1, 17 May 2020
41 ========================
42 - Fix bug in deleteFiles() method which can fail for certain search patterns.
43
44 pysmb-1.2.0, 17 May 2020
45 =========================
46 - Add new parameter, delete_matching_folders, to deleteFiles() method to
47 support deletion of child folders that match the search pattern.
48
49 pysmb-1.1.29, 16 May 2020
50 =========================
51 - Fix unhandled exception for short NBNS queries #149
52 - Fix wildcard file deletion with servers on SMB2 protocol #33
53
54 pysmb-1.1.28, 23 Nov 2019
55 ========================
56 - SharedFile instances returned from the listPath() method now has a new
57 file_id attribute which represents the file reference number given by the SMB server.
58
59 pysmb-1.1.27, 9 Jan 2019
60 ========================
61 - Remove support for SMB-2.1 dialect as it seems to have issues with Windows 2008 R2
62
63 pysmb-1.1.26, 5 Jan 2019
64 ========================
65 - Prevents OperationError from being raised when listPath() operation does not
66 return any matching file results.
67 - SMBConnection is now a context manager #122.
68
69 pysmb-1.1.25, 28 July 2018
70 ========================
71 - Fix buggy support for search parameter in listPath() method. Add
72 SMB_FILE_ATTRIBUTE_INCL_NORMAL bit constant to include 'normal' files with
73 other file types in the returned result. From now on, pysmb defines a 'normal' file
74 as a file entry that is not read-only, not hidden, not system, not archive and
75 not a directory; it ignores other attributes like compression, indexed, sparse,
76 temporary and encryption. listPath() method will now include 'normal' files
77 using the default search parameter.
78 - Add isNormal property to SharedFile class to support test if the file is a
79 'normal' file (according to pysmb definition of 'normal' file).
80
81 pysmb-1.1.24, 19 July 2018
82 ========================
83 - Improve listPath implementation for SMB1
84 - Support for STATUS_PENDING responses across all SMB2 operations.
85
86 pysmb-1.1.23, 5 May 2018
87 ========================
88 - Fix bug in listShares() method which fails when the remote server has many shares.
89 - Improve echo() method to test and fail if the provided data to echo is not a bytes object.
90 - Fix bug in listPath() method where the path to query is not properly terminated.
91
92 pysmb-1.1.22, 17 Sep 2017
93 ========================
94 - Fix bug in getAttributes() method which should return only the filename
95 instead of the entire path for the filename property for the return result.
96
97 pysmb-1.1.21, 9 Sep 2017
98 ========================
99 - Fix bug where timestamp values for SMB1 getAttributes() response are not
100 converted properly from FILETIME to epoch time values.
101
102 pysmb-1.1.20, 13 Aug 2017
103 =========================
104 - Add getSecurity() method to support security descriptors query via SMB2
105 - Improve retrieveFile() and retrieveFileFromOffset() methods to allow file
106 retrievals over SMB2 even when the file is being locked on the server.
107 - Silently discards NMB SESSION_KEEPALIVE packets instead of raising warnings.
108 - SMB sessionID will be sent in ECHO requests to conform to SMB2 specs.
109 - Fix type errors for MD4 functions in python3.
110
0111 pysmb-1.1.19, 13 Nov 2016
1 ========================
112 =========================
2113 - Ignore STATUS_PENDING during delete and file store operations
3114
4115 pysmb-1.1.18, 9 Apr 2016
00
1 Copyright (C) 2001-2015 Michael Teo <miketeo (a) miketeo.net>
1 Copyright (C) 2001-2020 Michael Teo <miketeo (a) miketeo.net>
22
33 This software is provided 'as-is', without any express or implied warranty.
44 In no event will the author be held liable for any damages arising from the
0 include LICENSE
1 include CHANGELOG
2 recursive-include python2 *
3 recursive-exclude python2 *.pyc
4 recursive-exclude python2 *~
5 recursive-include python3 *
6 recursive-exclude python3 *.pyc
7 recursive-exclude python3 *~
8 recursive-include sphinx *
9 recursive-include docs *
10 recursive-exclude docs *.zip
0 Metadata-Version: 1.1
0 Metadata-Version: 2.1
11 Name: pysmb
2 Version: 1.1.19
2 Version: 1.2.8
33 Summary: pysmb is an experimental SMB/CIFS library written in Python to support file sharing between Windows and Linux machines
44 Home-page: https://miketeo.net/projects/pysmb
55 Author: Michael Teo
66 Author-email: [email protected]
77 License: zlib/libpng
8 Description: pysmb is an experimental SMB/CIFS library written in Python. It implements the client-side SMB/CIFS protocol which allows your Python application to access and transfer files to/from SMB/CIFS shared folders like your Windows file sharing and Samba folders.
98 Keywords: windows samba cifs sharing ftp smb linux
10 Platform: UNKNOWN
119 Classifier: Development Status :: 5 - Production/Stable
1210 Classifier: Environment :: Win32 (MS Windows)
1311 Classifier: Environment :: Console
2321 Classifier: Topic :: Communications :: File Sharing
2422 Classifier: Topic :: Software Development :: Libraries :: Python Modules
2523 Classifier: Topic :: System :: Networking
24 License-File: LICENSE
25
26 pysmb is an experimental SMB/CIFS library written in Python. It implements the client-side SMB/CIFS protocol which allows your Python application to access and transfer files to/from SMB/CIFS shared folders like your Windows file sharing and Samba folders.
00 # Sphinx build info version 1
11 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
2 config: 8ec856095809db2990831edf01ebc5a4
2 config: 821c76a70446b97774adb84bc93f0dbf
33 tags: 645f666f9bcd5a90fca523b33c5a78b7
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
20
1 <!DOCTYPE html>
32
4 <html xmlns="http://www.w3.org/1999/xhtml">
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>Overview: module code &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../_static/jquery.js"></script>
23 <script type="text/javascript" src="../_static/underscore.js"></script>
24 <script type="text/javascript" src="../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../index.html" />
26 </head>
27 <body role="document">
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>Overview: module code &#8212; pysmb 1.2.8 documentation</title>
8 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
9 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
10 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
11 <script src="../_static/jquery.js"></script>
12 <script src="../_static/underscore.js"></script>
13 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
14 <script src="../_static/doctools.js"></script>
15 <link rel="index" title="Index" href="../genindex.html" />
16 <link rel="search" title="Search" href="../search.html" />
17 </head><body>
2818 <div class="related" role="navigation" aria-label="related navigation">
2919 <h3>Navigation</h3>
3020 <ul>
3121 <li class="right" style="margin-right: 10px">
3222 <a href="../genindex.html" title="General Index"
3323 accesskey="I">index</a></li>
34 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
24 <li class="right" >
25 <a href="../py-modindex.html" title="Python Module Index"
26 >modules</a> |</li>
27 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
28 <li class="nav-item nav-item-this"><a href="">Overview: module code</a></li>
3529 </ul>
36 </div>
37 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
38 <div class="sphinxsidebarwrapper">
39 <div id="searchbox" style="display: none" role="search">
40 <h3>Quick search</h3>
41 <form class="search" action="../search.html" method="get">
42 <input type="text" name="q" />
43 <input type="submit" value="Go" />
44 <input type="hidden" name="check_keywords" value="yes" />
45 <input type="hidden" name="area" value="default" />
46 </form>
47 <p class="searchtip" style="font-size: 90%">
48 Enter search terms or a module, class or function name.
49 </p>
50 </div>
51 <script type="text/javascript">$('#searchbox').show(0);</script>
52 </div>
53 </div>
30 </div>
5431
5532 <div class="document">
5633 <div class="documentwrapper">
5936
6037 <h1>All modules for which code is available</h1>
6138 <ul><li><a href="nmb/NetBIOS.html">nmb.NetBIOS</a></li>
62 <li><a href="nmb/NetBIOSProtocol.html">nmb.NetBIOSProtocol</a></li>
6339 <li><a href="smb/SMBConnection.html">smb.SMBConnection</a></li>
64 <li><a href="smb/SMBProtocol.html">smb.SMBProtocol</a></li>
6540 <li><a href="smb/base.html">smb.base</a></li>
41 <li><a href="smb/security_descriptors.html">smb.security_descriptors</a></li>
6642 <li><a href="smb/smb_structs.html">smb.smb_structs</a></li>
6743 </ul>
6844
45 <div class="clearer"></div>
6946 </div>
47 </div>
48 </div>
49 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
50 <div class="sphinxsidebarwrapper">
51 <div id="searchbox" style="display: none" role="search">
52 <h3 id="searchlabel">Quick search</h3>
53 <div class="searchformwrapper">
54 <form class="search" action="../search.html" method="get">
55 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
56 <input type="submit" value="Go" />
57 </form>
58 </div>
59 </div>
60 <script>document.getElementById('searchbox').style.display = "block"</script>
7061 </div>
7162 </div>
7263 <div class="clearer"></div>
7768 <li class="right" style="margin-right: 10px">
7869 <a href="../genindex.html" title="General Index"
7970 >index</a></li>
80 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
71 <li class="right" >
72 <a href="../py-modindex.html" title="Python Module Index"
73 >modules</a> |</li>
74 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
75 <li class="nav-item nav-item-this"><a href="">Overview: module code</a></li>
8176 </ul>
8277 </div>
8378 <div class="footer" role="contentinfo">
84 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
85 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
79 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
80 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
8681 </div>
8782 </body>
8883 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html>
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>nmb.NetBIOS &mdash; pysmb 1.1.18 documentation</title>
9
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>nmb.NetBIOS &#8212; pysmb 1.2.7 documentation</title>
8 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
109 <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../../_static/jquery.js"></script>
23 <script type="text/javascript" src="../../_static/underscore.js"></script>
24 <script type="text/javascript" src="../../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../../index.html" />
26 <link rel="up" title="Module code" href="../index.html" />
27 </head>
28 <body role="document">
10 <script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
11 <script src="../../_static/jquery.js"></script>
12 <script src="../../_static/underscore.js"></script>
13 <script src="../../_static/doctools.js"></script>
14 <link rel="index" title="Index" href="../../genindex.html" />
15 <link rel="search" title="Search" href="../../search.html" />
16 </head><body>
2917 <div class="related" role="navigation" aria-label="related navigation">
3018 <h3>Navigation</h3>
3119 <ul>
3220 <li class="right" style="margin-right: 10px">
3321 <a href="../../genindex.html" title="General Index"
3422 accesskey="I">index</a></li>
35 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
23 <li class="right" >
24 <a href="../../py-modindex.html" title="Python Module Index"
25 >modules</a> |</li>
26 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.7 documentation</a> &#187;</li>
27 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &#187;</li>
28 <li class="nav-item nav-item-this"><a href="">nmb.NetBIOS</a></li>
3729 </ul>
38 </div>
39 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
40 <div class="sphinxsidebarwrapper">
41 <div id="searchbox" style="display: none" role="search">
42 <h3>Quick search</h3>
43 <form class="search" action="../../search.html" method="get">
44 <input type="text" name="q" />
45 <input type="submit" value="Go" />
46 <input type="hidden" name="check_keywords" value="yes" />
47 <input type="hidden" name="area" value="default" />
48 </form>
49 <p class="searchtip" style="font-size: 90%">
50 Enter search terms or a module, class or function name.
51 </p>
52 </div>
53 <script type="text/javascript">$('#searchbox').show(0);</script>
54 </div>
55 </div>
30 </div>
5631
5732 <div class="document">
5833 <div class="documentwrapper">
6035 <div class="body" role="main">
6136
6237 <h1>Source code for nmb.NetBIOS</h1><div class="highlight"><pre>
63
38 <span></span>
6439 <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">random</span><span class="o">,</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">time</span><span class="o">,</span> <span class="nn">select</span>
65 <span class="kn">from</span> <span class="nn">base</span> <span class="kn">import</span> <span class="n">NBNS</span><span class="p">,</span> <span class="n">NotConnectedError</span>
66 <span class="kn">from</span> <span class="nn">nmb_constants</span> <span class="kn">import</span> <span class="n">TYPE_CLIENT</span><span class="p">,</span> <span class="n">TYPE_SERVER</span><span class="p">,</span> <span class="n">TYPE_WORKSTATION</span>
40 <span class="kn">from</span> <span class="nn">.base</span> <span class="kn">import</span> <span class="n">NBNS</span><span class="p">,</span> <span class="n">NotConnectedError</span>
41 <span class="kn">from</span> <span class="nn">.nmb_constants</span> <span class="kn">import</span> <span class="n">TYPE_CLIENT</span><span class="p">,</span> <span class="n">TYPE_SERVER</span><span class="p">,</span> <span class="n">TYPE_WORKSTATION</span>
6742
6843 <div class="viewcode-block" id="NetBIOS"><a class="viewcode-back" href="../../api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS">[docs]</a><span class="k">class</span> <span class="nc">NetBIOS</span><span class="p">(</span><span class="n">NBNS</span><span class="p">):</span>
6944
7045 <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s1">&#39;NMB.NetBIOS&#39;</span><span class="p">)</span>
7146
72 <div class="viewcode-block" id="NetBIOS.__init__"><a class="viewcode-back" href="../../api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.__init__">[docs]</a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">broadcast</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">listen_port</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
47 <div class="viewcode-block" id="NetBIOS.__init__"><a class="viewcode-back" href="../../api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">broadcast</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">listen_port</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
7348 <span class="sd">&quot;&quot;&quot;</span>
7449 <span class="sd"> Instantiate a NetBIOS instance, and creates a IPv4 UDP socket to listen/send NBNS packets.</span>
7550
9267 <span class="sd"> :return: None</span>
9368 <span class="sd"> &quot;&quot;&quot;</span>
9469 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
95 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="bp">None</span></div>
70 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="kc">None</span></div>
9671
9772 <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">):</span>
9873 <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">,</span> <span class="s1">&#39;Socket is already closed&#39;</span>
136111 <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">,</span> <span class="s1">&#39;Socket is already closed&#39;</span>
137112
138113 <span class="n">trn_id</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mh">0xFFFF</span><span class="p">)</span>
139 <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">prepareNetNameQuery</span><span class="p">(</span><span class="n">trn_id</span><span class="p">,</span> <span class="bp">False</span><span class="p">)</span>
114 <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">prepareNetNameQuery</span><span class="p">(</span><span class="n">trn_id</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
140115 <span class="bp">self</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">)</span>
141116 <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pollForQueryPacket</span><span class="p">(</span><span class="n">trn_id</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
142117 <span class="k">if</span> <span class="n">ret</span><span class="p">:</span>
143 <span class="k">return</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="n">s</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">TYPE_SERVER</span><span class="p">,</span> <span class="n">ret</span><span class="p">))</span>
118 <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="n">s</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">TYPE_SERVER</span><span class="p">,</span> <span class="n">ret</span><span class="p">)))</span>
144119 <span class="k">else</span><span class="p">:</span>
145 <span class="k">return</span> <span class="bp">None</span></div>
120 <span class="k">return</span> <span class="kc">None</span></div>
146121
147122 <span class="c1">#</span>
148123 <span class="c1"># Protected Methods</span>
149124 <span class="c1">#</span>
150125
151126 <span class="k">def</span> <span class="nf">_pollForNetBIOSPacket</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">wait_trn_id</span><span class="p">,</span> <span class="n">timeout</span><span class="p">):</span>
152 <span class="n">end_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">timeout</span>
153 <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
127 <span class="n">end_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">timeout</span>
128 <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
154129 <span class="k">try</span><span class="p">:</span>
155 <span class="n">_timeout</span> <span class="o">=</span> <span class="n">end_time</span> <span class="o">-</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
130 <span class="n">_timeout</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">-</span><span class="n">end_time</span>
156131 <span class="k">if</span> <span class="n">_timeout</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
157 <span class="k">return</span> <span class="bp">None</span>
132 <span class="k">return</span> <span class="kc">None</span>
158133
159134 <span class="n">ready</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">([</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="n">_timeout</span><span class="p">)</span>
160135 <span class="k">if</span> <span class="ow">not</span> <span class="n">ready</span><span class="p">:</span>
161 <span class="k">return</span> <span class="bp">None</span>
136 <span class="k">return</span> <span class="kc">None</span>
162137
163138 <span class="n">data</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">recvfrom</span><span class="p">(</span><span class="mh">0xFFFF</span><span class="p">)</span>
164139 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
168143
169144 <span class="k">if</span> <span class="n">trn_id</span> <span class="o">==</span> <span class="n">wait_trn_id</span><span class="p">:</span>
170145 <span class="k">return</span> <span class="n">ret</span>
171 <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
172 <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span> <span class="ow">is</span> <span class="n">types</span><span class="o">.</span><span class="n">TupleType</span><span class="p">:</span>
146 <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
147 <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">tuple</span><span class="p">:</span>
173148 <span class="k">if</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EINTR</span> <span class="ow">and</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EAGAIN</span><span class="p">:</span>
174149 <span class="k">raise</span> <span class="n">ex</span>
175150 <span class="k">else</span><span class="p">:</span>
179154 <span class="c1"># Contributed by Jason Anderson</span>
180155 <span class="c1">#</span>
181156 <span class="k">def</span> <span class="nf">_pollForQueryPacket</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">wait_trn_id</span><span class="p">,</span> <span class="n">timeout</span><span class="p">):</span>
182 <span class="n">end_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">timeout</span>
183 <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
157 <span class="n">end_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">timeout</span>
158 <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
184159 <span class="k">try</span><span class="p">:</span>
185 <span class="n">_timeout</span> <span class="o">=</span> <span class="n">end_time</span> <span class="o">-</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
160 <span class="n">_timeout</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">-</span><span class="n">end_time</span>
186161 <span class="k">if</span> <span class="n">_timeout</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
187 <span class="k">return</span> <span class="bp">None</span>
162 <span class="k">return</span> <span class="kc">None</span>
188163
189164 <span class="n">ready</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">([</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="n">_timeout</span><span class="p">)</span>
190165 <span class="k">if</span> <span class="ow">not</span> <span class="n">ready</span><span class="p">:</span>
191 <span class="k">return</span> <span class="bp">None</span>
166 <span class="k">return</span> <span class="kc">None</span>
192167
193168 <span class="n">data</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">recvfrom</span><span class="p">(</span><span class="mh">0xFFFF</span><span class="p">)</span>
194169 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
198173
199174 <span class="k">if</span> <span class="n">trn_id</span> <span class="o">==</span> <span class="n">wait_trn_id</span><span class="p">:</span>
200175 <span class="k">return</span> <span class="n">ret</span>
201 <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
202 <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span> <span class="ow">is</span> <span class="n">types</span><span class="o">.</span><span class="n">TupleType</span><span class="p">:</span>
176 <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
177 <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">tuple</span><span class="p">:</span>
203178 <span class="k">if</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EINTR</span> <span class="ow">and</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EAGAIN</span><span class="p">:</span>
204179 <span class="k">raise</span> <span class="n">ex</span>
205180 <span class="k">else</span><span class="p">:</span>
206181 <span class="k">raise</span> <span class="n">ex</span></div>
207182 </pre></div>
208183
184 <div class="clearer"></div>
209185 </div>
186 </div>
187 </div>
188 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
189 <div class="sphinxsidebarwrapper">
190 <div id="searchbox" style="display: none" role="search">
191 <h3 id="searchlabel">Quick search</h3>
192 <div class="searchformwrapper">
193 <form class="search" action="../../search.html" method="get">
194 <input type="text" name="q" aria-labelledby="searchlabel" />
195 <input type="submit" value="Go" />
196 </form>
197 </div>
198 </div>
199 <script>$('#searchbox').show(0);</script>
210200 </div>
211201 </div>
212202 <div class="clearer"></div>
217207 <li class="right" style="margin-right: 10px">
218208 <a href="../../genindex.html" title="General Index"
219209 >index</a></li>
220 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
221 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &raquo;</li>
210 <li class="right" >
211 <a href="../../py-modindex.html" title="Python Module Index"
212 >modules</a> |</li>
213 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.7 documentation</a> &#187;</li>
214 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &#187;</li>
215 <li class="nav-item nav-item-this"><a href="">nmb.NetBIOS</a></li>
222216 </ul>
223217 </div>
224218 <div class="footer" role="contentinfo">
225 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
226 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
219 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
220 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.4.3.
227221 </div>
228222 </body>
229223 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html>
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>nmb.NetBIOSProtocol &mdash; pysmb 1.1.18 documentation</title>
9
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>nmb.NetBIOSProtocol &#8212; pysmb 1.2.7 documentation</title>
8 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
109 <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../../_static/jquery.js"></script>
23 <script type="text/javascript" src="../../_static/underscore.js"></script>
24 <script type="text/javascript" src="../../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../../index.html" />
26 <link rel="up" title="Module code" href="../index.html" />
27 </head>
28 <body role="document">
10 <script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
11 <script src="../../_static/jquery.js"></script>
12 <script src="../../_static/underscore.js"></script>
13 <script src="../../_static/doctools.js"></script>
14 <link rel="index" title="Index" href="../../genindex.html" />
15 <link rel="search" title="Search" href="../../search.html" />
16 </head><body>
2917 <div class="related" role="navigation" aria-label="related navigation">
3018 <h3>Navigation</h3>
3119 <ul>
3220 <li class="right" style="margin-right: 10px">
3321 <a href="../../genindex.html" title="General Index"
3422 accesskey="I">index</a></li>
35 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
23 <li class="right" >
24 <a href="../../py-modindex.html" title="Python Module Index"
25 >modules</a> |</li>
26 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.7 documentation</a> &#187;</li>
27 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &#187;</li>
28 <li class="nav-item nav-item-this"><a href="">nmb.NetBIOSProtocol</a></li>
3729 </ul>
38 </div>
39 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
40 <div class="sphinxsidebarwrapper">
41 <div id="searchbox" style="display: none" role="search">
42 <h3>Quick search</h3>
43 <form class="search" action="../../search.html" method="get">
44 <input type="text" name="q" />
45 <input type="submit" value="Go" />
46 <input type="hidden" name="check_keywords" value="yes" />
47 <input type="hidden" name="area" value="default" />
48 </form>
49 <p class="searchtip" style="font-size: 90%">
50 Enter search terms or a module, class or function name.
51 </p>
52 </div>
53 <script type="text/javascript">$('#searchbox').show(0);</script>
54 </div>
55 </div>
30 </div>
5631
5732 <div class="document">
5833 <div class="documentwrapper">
6035 <div class="body" role="main">
6136
6237 <h1>Source code for nmb.NetBIOSProtocol</h1><div class="highlight"><pre>
63
38 <span></span>
6439 <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">random</span><span class="o">,</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">time</span>
6540 <span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span><span class="p">,</span> <span class="n">defer</span>
6641 <span class="kn">from</span> <span class="nn">twisted.internet.protocol</span> <span class="kn">import</span> <span class="n">DatagramProtocol</span>
67 <span class="kn">from</span> <span class="nn">nmb_constants</span> <span class="kn">import</span> <span class="n">TYPE_SERVER</span>
68 <span class="kn">from</span> <span class="nn">base</span> <span class="kn">import</span> <span class="n">NBNS</span>
69
70 <span class="n">IP_QUERY</span><span class="p">,</span> <span class="n">NAME_QUERY</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
42 <span class="kn">from</span> <span class="nn">.base</span> <span class="kn">import</span> <span class="n">NBNS</span>
7143
7244 <div class="viewcode-block" id="NetBIOSTimeout"><a class="viewcode-back" href="../../api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NetBIOSTimeout">[docs]</a><span class="k">class</span> <span class="nc">NetBIOSTimeout</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
7345 <span class="sd">&quot;&quot;&quot;Raised in NBNSProtocol via Deferred.errback method when queryName method has timeout waiting for reply&quot;&quot;&quot;</span>
7749
7850 <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s1">&#39;NMB.NBNSProtocol&#39;</span><span class="p">)</span>
7951
80 <div class="viewcode-block" id="NBNSProtocol.__init__"><a class="viewcode-back" href="../../api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.__init__">[docs]</a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">broadcast</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">listen_port</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
52 <div class="viewcode-block" id="NBNSProtocol.__init__"><a class="viewcode-back" href="../../api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">broadcast</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">listen_port</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
8153 <span class="sd">&quot;&quot;&quot;</span>
8254 <span class="sd"> Instantiate a NBNSProtocol instance.</span>
8355
9365 <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">getHandle</span><span class="p">()</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_BROADCAST</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
9466 <span class="n">reactor</span><span class="o">.</span><span class="n">callLater</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleanupPendingTrns</span><span class="p">)</span></div>
9567
96 <span class="k">def</span> <span class="nf">datagramReceived</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">from_info</span><span class="p">):</span>
68 <div class="viewcode-block" id="NBNSProtocol.datagramReceived"><a class="viewcode-back" href="../../api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.datagramReceived">[docs]</a> <span class="k">def</span> <span class="nf">datagramReceived</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">from_info</span><span class="p">):</span>
9769 <span class="n">host</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">from_info</span>
9870 <span class="n">trn_id</span><span class="p">,</span> <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">decodePacket</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
9971
10375 <span class="k">if</span> <span class="n">ip</span> <span class="ow">is</span> <span class="n">NAME_QUERY</span><span class="p">:</span>
10476 <span class="c1"># decode as query packet</span>
10577 <span class="n">trn_id</span><span class="p">,</span> <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">decodeIPQueryPacket</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
106 <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">ret</span><span class="p">)</span>
78 <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">ret</span><span class="p">)</span></div>
10779
10880 <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">):</span>
10981 <span class="c1"># We don&#39;t use the transport.write method directly as it keeps raising DeprecationWarning for ip=&#39;&lt;broadcast&gt;&#39;</span>
12193 <span class="sd"> On timeout, the errback function will be called with a Failure instance wrapping around a NetBIOSTimeout exception</span>
12294 <span class="sd"> &quot;&quot;&quot;</span>
12395 <span class="n">trn_id</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mh">0xFFFF</span><span class="p">)</span>
124 <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
125 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">trn_id</span><span class="p">):</span>
96 <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
97 <span class="k">if</span> <span class="n">trn_id</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="p">:</span>
12698 <span class="k">break</span>
12799 <span class="k">else</span><span class="p">:</span>
128100 <span class="n">trn_id</span> <span class="o">=</span> <span class="p">(</span><span class="n">trn_id</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xFFFF</span>
153125 <span class="sd"> On timeout, the errback function will be called with a Failure instance wrapping around a NetBIOSTimeout exception</span>
154126 <span class="sd"> &quot;&quot;&quot;</span>
155127 <span class="n">trn_id</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mh">0xFFFF</span><span class="p">)</span>
156 <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
157 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">trn_id</span><span class="p">):</span>
128 <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
129 <span class="k">if</span> <span class="n">trn_id</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="p">:</span>
158130 <span class="k">break</span>
159131 <span class="k">else</span><span class="p">:</span>
160132 <span class="n">trn_id</span> <span class="o">=</span> <span class="p">(</span><span class="n">trn_id</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xFFFF</span>
167139 <span class="n">d2</span><span class="o">.</span><span class="n">addErrback</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">)</span>
168140
169141 <span class="k">def</span> <span class="nf">stripCode</span><span class="p">(</span><span class="n">ret</span><span class="p">):</span>
170 <span class="k">if</span> <span class="n">ret</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="c1"># got valid response. Somehow the callback is also called when there is an error.</span>
142 <span class="k">if</span> <span class="n">ret</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># got valid response. Somehow the callback is also called when there is an error.</span>
171143 <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="n">s</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">TYPE_SERVER</span><span class="p">,</span> <span class="n">ret</span><span class="p">)))</span>
172144
173145 <span class="n">d2</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="n">stripCode</span><span class="p">)</span>
174146 <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="p">[</span><span class="n">trn_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">+</span><span class="n">timeout</span><span class="p">,</span> <span class="n">NAME_QUERY</span><span class="p">,</span> <span class="n">d2</span> <span class="p">)</span>
175147 <span class="k">return</span> <span class="n">d</span></div>
176148
177 <span class="k">def</span> <span class="nf">stopProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
178 <span class="n">DatagramProtocol</span><span class="o">.</span><span class="n">stopProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
149 <div class="viewcode-block" id="NBNSProtocol.stopProtocol"><a class="viewcode-back" href="../../api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.stopProtocol">[docs]</a> <span class="k">def</span> <span class="nf">stopProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
150 <span class="n">DatagramProtocol</span><span class="o">.</span><span class="n">stopProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
179151
180152 <span class="k">def</span> <span class="nf">cleanupPendingTrns</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
181153 <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
182154
183155 <span class="c1"># reply should have been received in the past</span>
184 <span class="n">expired</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="p">(</span><span class="n">trn_id</span><span class="p">,</span> <span class="p">(</span><span class="n">expiry_time</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">d</span><span class="p">)):</span> <span class="n">expiry_time</span> <span class="o">&lt;</span> <span class="n">now</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="o">.</span><span class="n">iteritems</span><span class="p">())</span>
156 <span class="c1"># info is tuple of ( expiry_time, name, d )</span>
157 <span class="n">expired</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">trn_id</span><span class="p">,</span> <span class="n">info</span><span class="p">:</span> <span class="n">info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">now</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="o">.</span><span class="n">iteritems</span><span class="p">())</span>
185158
186159 <span class="c1"># remove expired items from dict + call errback</span>
187160 <span class="k">def</span> <span class="nf">expire_item</span><span class="p">(</span><span class="n">item</span><span class="p">):</span>
198171 <span class="n">reactor</span><span class="o">.</span><span class="n">callLater</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleanupPendingTrns</span><span class="p">)</span></div>
199172 </pre></div>
200173
174 <div class="clearer"></div>
201175 </div>
176 </div>
177 </div>
178 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
179 <div class="sphinxsidebarwrapper">
180 <div id="searchbox" style="display: none" role="search">
181 <h3 id="searchlabel">Quick search</h3>
182 <div class="searchformwrapper">
183 <form class="search" action="../../search.html" method="get">
184 <input type="text" name="q" aria-labelledby="searchlabel" />
185 <input type="submit" value="Go" />
186 </form>
187 </div>
188 </div>
189 <script>$('#searchbox').show(0);</script>
202190 </div>
203191 </div>
204192 <div class="clearer"></div>
209197 <li class="right" style="margin-right: 10px">
210198 <a href="../../genindex.html" title="General Index"
211199 >index</a></li>
212 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
213 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &raquo;</li>
200 <li class="right" >
201 <a href="../../py-modindex.html" title="Python Module Index"
202 >modules</a> |</li>
203 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.7 documentation</a> &#187;</li>
204 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &#187;</li>
205 <li class="nav-item nav-item-this"><a href="">nmb.NetBIOSProtocol</a></li>
214206 </ul>
215207 </div>
216208 <div class="footer" role="contentinfo">
217 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
218 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
209 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
210 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.4.3.
219211 </div>
220212 </body>
221213 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>smb.SMBConnection &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../../_static/jquery.js"></script>
23 <script type="text/javascript" src="../../_static/underscore.js"></script>
24 <script type="text/javascript" src="../../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../../index.html" />
26 <link rel="up" title="Module code" href="../index.html" />
27 </head>
28 <body role="document">
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>smb.SMBConnection &#8212; pysmb 1.2.8 documentation</title>
8 <link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
9 <link rel="stylesheet" type="text/css" href="../../_static/sphinxdoc.css" />
10 <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
11 <script src="../../_static/jquery.js"></script>
12 <script src="../../_static/underscore.js"></script>
13 <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
14 <script src="../../_static/doctools.js"></script>
15 <link rel="index" title="Index" href="../../genindex.html" />
16 <link rel="search" title="Search" href="../../search.html" />
17 </head><body>
2918 <div class="related" role="navigation" aria-label="related navigation">
3019 <h3>Navigation</h3>
3120 <ul>
3221 <li class="right" style="margin-right: 10px">
3322 <a href="../../genindex.html" title="General Index"
3423 accesskey="I">index</a></li>
35 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
24 <li class="right" >
25 <a href="../../py-modindex.html" title="Python Module Index"
26 >modules</a> |</li>
27 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
28 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &#187;</li>
29 <li class="nav-item nav-item-this"><a href="">smb.SMBConnection</a></li>
3730 </ul>
38 </div>
39 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
40 <div class="sphinxsidebarwrapper">
41 <div id="searchbox" style="display: none" role="search">
42 <h3>Quick search</h3>
43 <form class="search" action="../../search.html" method="get">
44 <input type="text" name="q" />
45 <input type="submit" value="Go" />
46 <input type="hidden" name="check_keywords" value="yes" />
47 <input type="hidden" name="area" value="default" />
48 </form>
49 <p class="searchtip" style="font-size: 90%">
50 Enter search terms or a module, class or function name.
51 </p>
52 </div>
53 <script type="text/javascript">$('#searchbox').show(0);</script>
54 </div>
55 </div>
31 </div>
5632
5733 <div class="document">
5834 <div class="documentwrapper">
6036 <div class="body" role="main">
6137
6238 <h1>Source code for smb.SMBConnection</h1><div class="highlight"><pre>
63
64 <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">select</span><span class="o">,</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">struct</span><span class="o">,</span> <span class="nn">errno</span>
65 <span class="kn">from</span> <span class="nn">smb_constants</span> <span class="kn">import</span> <span class="o">*</span>
66 <span class="kn">from</span> <span class="nn">smb_structs</span> <span class="kn">import</span> <span class="o">*</span>
67 <span class="kn">from</span> <span class="nn">base</span> <span class="kn">import</span> <span class="n">SMB</span><span class="p">,</span> <span class="n">NotConnectedError</span><span class="p">,</span> <span class="n">NotReadyError</span><span class="p">,</span> <span class="n">SMBTimeout</span>
39 <span></span>
40 <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">select</span><span class="o">,</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">types</span><span class="o">,</span> <span class="nn">struct</span><span class="o">,</span> <span class="nn">errno</span>
41 <span class="kn">from</span> <span class="nn">.smb_constants</span> <span class="kn">import</span> <span class="o">*</span>
42 <span class="kn">from</span> <span class="nn">.smb_structs</span> <span class="kn">import</span> <span class="o">*</span>
43 <span class="kn">from</span> <span class="nn">.base</span> <span class="kn">import</span> <span class="n">SMB</span><span class="p">,</span> <span class="n">NotConnectedError</span><span class="p">,</span> <span class="n">NotReadyError</span><span class="p">,</span> <span class="n">SMBTimeout</span>
6844
6945
7046 <div class="viewcode-block" id="SMBConnection"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection">[docs]</a><span class="k">class</span> <span class="nc">SMBConnection</span><span class="p">(</span><span class="n">SMB</span><span class="p">):</span>
7854 <span class="c1">#: SMB messages will only be signed when remote server requires signing.</span>
7955 <span class="n">SIGN_WHEN_REQUIRED</span> <span class="o">=</span> <span class="mi">2</span>
8056
81 <div class="viewcode-block" id="SMBConnection.__init__"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.__init__">[docs]</a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">sign_options</span> <span class="o">=</span> <span class="n">SIGN_WHEN_REQUIRED</span><span class="p">,</span> <span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
57 <div class="viewcode-block" id="SMBConnection.__init__"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">sign_options</span> <span class="o">=</span> <span class="n">SIGN_WHEN_REQUIRED</span><span class="p">,</span> <span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="kc">False</span><span class="p">):</span>
8258 <span class="sd">&quot;&quot;&quot;</span>
8359 <span class="sd"> Create a new SMBConnection instance.</span>
8460
8561 <span class="sd"> *username* and *password* are the user credentials required to authenticate the underlying SMB connection with the remote server.</span>
62 <span class="sd"> *password* can be a string or a callable returning a string.</span>
8663 <span class="sd"> File operations can only be proceeded after the connection has been authenticated successfully.</span>
8764
8865 <span class="sd"> Note that you need to call *connect* method to actually establish the SMB connection to the remote server and perform authentication.</span>
9168 <span class="sd"> Some newer server installations might also support Direct hosting of SMB over TCP/IP; for these servers, the default TCP port is 445.</span>
9269
9370 <span class="sd"> :param string my_name: The local NetBIOS machine name that will identify where this connection is originating from.</span>
94 <span class="sd"> You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\/:*?&quot;;|+``</span>
71 <span class="sd"> You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\\/:*?&quot;;|+``</span>
9572 <span class="sd"> :param string remote_name: The NetBIOS machine name of the remote server.</span>
9673 <span class="sd"> On windows, you can find out the machine name by right-clicking on the &quot;My Computer&quot; and selecting &quot;Properties&quot;.</span>
9774 <span class="sd"> This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.</span>
10784 <span class="sd"> :param boolean is_direct_tcp: Controls whether the NetBIOS over TCP/IP (is_direct_tcp=False) or the newer Direct hosting of SMB over TCP/IP (is_direct_tcp=True) will be used for the communication.</span>
10885 <span class="sd"> The default parameter is False which will use NetBIOS over TCP/IP for wider compatibility (TCP port: 139).</span>
10986 <span class="sd"> &quot;&quot;&quot;</span>
110 <span class="n">SMB</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span><span class="p">,</span> <span class="n">use_ntlm_v2</span><span class="p">,</span> <span class="n">sign_options</span><span class="p">,</span> <span class="n">is_direct_tcp</span><span class="p">)</span>
111 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="bp">None</span>
112 <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="bp">None</span>
113 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
87 <span class="n">SMB</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span><span class="p">,</span> <span class="n">use_ntlm_v2</span><span class="p">,</span> <span class="n">sign_options</span><span class="p">,</span> <span class="n">is_direct_tcp</span><span class="p">)</span>
88 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="kc">None</span>
89 <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="kc">None</span>
90 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
11491 <span class="bp">self</span><span class="o">.</span><span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="n">is_direct_tcp</span></div>
11592
11693 <span class="c1">#</span>
11895 <span class="c1">#</span>
11996
12097 <span class="k">def</span> <span class="nf">onAuthOK</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
121 <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="bp">True</span>
98 <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="kc">True</span>
12299
123100 <span class="k">def</span> <span class="nf">onAuthFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
124 <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="bp">False</span>
101 <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="kc">False</span>
125102
126103 <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
127104 <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span>
134111 <span class="n">total_sent</span> <span class="o">=</span> <span class="n">total_sent</span> <span class="o">+</span> <span class="n">sent</span>
135112
136113 <span class="c1">#</span>
114 <span class="c1"># Support for &quot;with&quot; context</span>
115 <span class="c1">#</span>
116 <span class="k">def</span> <span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
117 <span class="k">return</span> <span class="bp">self</span>
118
119 <span class="k">def</span> <span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
120 <span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
121
122 <span class="c1">#</span>
137123 <span class="c1"># Misc Properties</span>
138124 <span class="c1">#</span>
139125
147133 <span class="c1"># Public Methods</span>
148134 <span class="c1">#</span>
149135
150 <div class="viewcode-block" id="SMBConnection.connect"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.connect">[docs]</a> <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="mi">139</span><span class="p">,</span> <span class="n">sock_family</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">60</span><span class="p">):</span>
136 <div class="viewcode-block" id="SMBConnection.connect"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.connect">[docs]</a> <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="mi">139</span><span class="p">,</span> <span class="n">sock_family</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">60</span><span class="p">):</span>
151137 <span class="sd">&quot;&quot;&quot;</span>
152138 <span class="sd"> Establish the SMB connection to the remote SMB/CIFS server.</span>
153139
154140 <span class="sd"> You must call this method before attempting any of the file operations with the remote server.</span>
155141 <span class="sd"> This method will block until the SMB connection has attempted at least one authentication.</span>
156142
143 <span class="sd"> :param port: Defaults to 139. If you are using direct TCP mode (is_direct_tcp=true when creating this SMBConnection instance), use 445.</span>
144 <span class="sd"> :param sock_family: In Python 3.x, use *None* as we can infer the socket family from the provided *ip*. In Python 2.x, it must be either *socket.AF_INET* or *socket.AF_INET6*.</span>
157145 <span class="sd"> :return: A boolean value indicating the result of the authentication atttempt: True if authentication is successful; False, if otherwise.</span>
158146 <span class="sd"> &quot;&quot;&quot;</span>
159147 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span>
160148 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
161149
162 <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="bp">None</span>
163 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">sock_family</span><span class="p">)</span>
164 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">settimeout</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
165 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span> <span class="p">))</span>
166
167 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
150 <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="kc">None</span>
151 <span class="k">if</span> <span class="n">sock_family</span><span class="p">:</span>
152 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">sock_family</span><span class="p">)</span>
153 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">settimeout</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
154 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span> <span class="p">))</span>
155 <span class="k">else</span><span class="p">:</span>
156 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">create_connection</span><span class="p">((</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span> <span class="p">))</span>
157
158 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
168159 <span class="k">try</span><span class="p">:</span>
169160 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_direct_tcp</span><span class="p">:</span>
170161 <span class="bp">self</span><span class="o">.</span><span class="n">requestNMBSession</span><span class="p">()</span>
171162 <span class="k">else</span><span class="p">:</span>
172163 <span class="bp">self</span><span class="o">.</span><span class="n">onNMBSessionOK</span><span class="p">()</span>
173 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
174 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
175 <span class="k">finally</span><span class="p">:</span>
176 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
164 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
165 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
166 <span class="k">finally</span><span class="p">:</span>
167 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
177168
178169 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span></div>
179170
183174 <span class="sd"> &quot;&quot;&quot;</span>
184175 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span>
185176 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
186 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="bp">None</span></div>
177 <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="kc">None</span></div>
187178
188179 <div class="viewcode-block" id="SMBConnection.listShares"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listShares">[docs]</a> <span class="k">def</span> <span class="nf">listShares</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
189180 <span class="sd">&quot;&quot;&quot;</span>
197188 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
198189
199190 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">entries</span><span class="p">):</span>
200 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
191 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
201192 <span class="n">results</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">entries</span><span class="p">)</span>
202193
203194 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
204 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
205 <span class="k">raise</span> <span class="n">failure</span>
206
207 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
195 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
196 <span class="k">raise</span> <span class="n">failure</span>
197
198 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
208199 <span class="k">try</span><span class="p">:</span>
209200 <span class="bp">self</span><span class="o">.</span><span class="n">_listShares</span><span class="p">(</span><span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
210201 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
211202 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
212203 <span class="k">finally</span><span class="p">:</span>
213 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
204 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
214205
215206 <span class="k">return</span> <span class="n">results</span></div>
216207
217208 <div class="viewcode-block" id="SMBConnection.listPath"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listPath">[docs]</a> <span class="k">def</span> <span class="nf">listPath</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span>
218 <span class="n">search</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_READONLY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_DIRECTORY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_ARCHIVE</span><span class="p">,</span>
209 <span class="n">search</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_READONLY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_DIRECTORY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_ARCHIVE</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_INCL_NORMAL</span><span class="p">,</span>
219210 <span class="n">pattern</span> <span class="o">=</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
220211 <span class="sd">&quot;&quot;&quot;</span>
221212 <span class="sd"> Retrieve a directory listing of files/folders at *path*</span>
213
214 <span class="sd"> For simplicity, pysmb defines a &quot;normal&quot; file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.</span>
215 <span class="sd"> It ignores other attributes like compression, indexed, sparse, temporary and encryption.</span>
216
217 <span class="sd"> Note that the default search parameter will query for all read-only (SMB_FILE_ATTRIBUTE_READONLY), hidden (SMB_FILE_ATTRIBUTE_HIDDEN),</span>
218 <span class="sd"> system (SMB_FILE_ATTRIBUTE_SYSTEM), archive (SMB_FILE_ATTRIBUTE_ARCHIVE), normal (SMB_FILE_ATTRIBUTE_INCL_NORMAL) files</span>
219 <span class="sd"> and directories (SMB_FILE_ATTRIBUTE_DIRECTORY).</span>
220 <span class="sd"> If you do not need to include &quot;normal&quot; files in the result, define your own search parameter without the SMB_FILE_ATTRIBUTE_INCL_NORMAL constant.</span>
221 <span class="sd"> SMB_FILE_ATTRIBUTE_NORMAL should be used by itself and not be used with other bit constants.</span>
222222
223223 <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span>
224224 <span class="sd"> :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders.</span>
225225 <span class="sd"> :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py).</span>
226 <span class="sd"> The default *search* value will query for all read-only, hidden, system, archive files and directories.</span>
227226 <span class="sd"> :param string/unicode pattern: the filter to apply to the results before returning to the client.</span>
228227 <span class="sd"> :return: A list of :doc:`smb.base.SharedFile&lt;smb_SharedFile&gt;` instances.</span>
229228 <span class="sd"> &quot;&quot;&quot;</span>
233232 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
234233
235234 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">entries</span><span class="p">):</span>
236 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
235 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
237236 <span class="n">results</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">entries</span><span class="p">)</span>
238237
239238 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
240 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
241 <span class="k">raise</span> <span class="n">failure</span>
242
243 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
239 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
240 <span class="k">raise</span> <span class="n">failure</span>
241
242 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
244243 <span class="k">try</span><span class="p">:</span>
245244 <span class="bp">self</span><span class="o">.</span><span class="n">_listPath</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">search</span> <span class="o">=</span> <span class="n">search</span><span class="p">,</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
246245 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
247246 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
248247 <span class="k">finally</span><span class="p">:</span>
249 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
248 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
250249
251250 <span class="k">return</span> <span class="n">results</span></div>
252251
266265 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
267266
268267 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">entries</span><span class="p">):</span>
269 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
268 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
270269 <span class="n">results</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">entries</span><span class="p">)</span>
271270
272271 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
273 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
274 <span class="k">raise</span> <span class="n">failure</span>
275
276 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
272 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
273 <span class="k">raise</span> <span class="n">failure</span>
274
275 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
277276 <span class="k">try</span><span class="p">:</span>
278277 <span class="bp">self</span><span class="o">.</span><span class="n">_listSnapshots</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
279278 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
280279 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
281280 <span class="k">finally</span><span class="p">:</span>
282 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
281 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
283282
284283 <span class="k">return</span> <span class="n">results</span></div>
285284
297296 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
298297
299298 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">info</span><span class="p">):</span>
300 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
299 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
301300 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">info</span><span class="p">)</span>
302301
303302 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
304 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
305 <span class="k">raise</span> <span class="n">failure</span>
306
307 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
303 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
304 <span class="k">raise</span> <span class="n">failure</span>
305
306 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
308307 <span class="k">try</span><span class="p">:</span>
309308 <span class="bp">self</span><span class="o">.</span><span class="n">_getAttributes</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
310309 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
311310 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
312311 <span class="k">finally</span><span class="p">:</span>
313 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
312 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
314313
315314 <span class="k">return</span> <span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></div>
316315
317 <div class="viewcode-block" id="SMBConnection.retrieveFile"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFile">[docs]</a> <span class="k">def</span> <span class="nf">retrieveFile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
318 <span class="sd">&quot;&quot;&quot;</span>
319 <span class="sd"> Retrieve the contents of the file at *path* on the *service_name* and write these contents to the provided *file_obj*.</span>
320
321 <span class="sd"> Use *retrieveFileFromOffset()* method if you wish to specify the offset to read from the remote *path* and/or the number of bytes to write to the *file_obj*.</span>
316 <div class="viewcode-block" id="SMBConnection.getSecurity"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.getSecurity">[docs]</a> <span class="k">def</span> <span class="nf">getSecurity</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
317 <span class="sd">&quot;&quot;&quot;</span>
318 <span class="sd"> Retrieve the security descriptor of the file at *path* on the *service_name*.</span>
322319
323320 <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span>
324321 <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure&lt;smb_exceptions&gt;` will be raised.</span>
325 <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service.</span>
322 <span class="sd"> :return: A :class:`smb.security_descriptors.SecurityDescriptor` instance containing the security information of the file.</span>
323 <span class="sd"> &quot;&quot;&quot;</span>
324 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span>
325 <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s1">&#39;Not connected to server&#39;</span><span class="p">)</span>
326
327 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
328
329 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">info</span><span class="p">):</span>
330 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
331 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">info</span><span class="p">)</span>
332
333 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
334 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
335 <span class="k">raise</span> <span class="n">failure</span>
336
337 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
338 <span class="k">try</span><span class="p">:</span>
339 <span class="bp">self</span><span class="o">.</span><span class="n">_getSecurity</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
340 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
341 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
342 <span class="k">finally</span><span class="p">:</span>
343 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
344
345 <span class="k">return</span> <span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></div>
346
347 <div class="viewcode-block" id="SMBConnection.retrieveFile"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFile">[docs]</a> <span class="k">def</span> <span class="nf">retrieveFile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
348 <span class="sd">&quot;&quot;&quot;</span>
349 <span class="sd"> Retrieve the contents of the file at *path* on the *service_name* and write these contents to the provided *file_obj*.</span>
350
351 <span class="sd"> Use *retrieveFileFromOffset()* method if you wish to specify the offset to read from the remote *path* and/or the number of bytes to write to the *file_obj*.</span>
352
353 <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span>
354 <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure&lt;smb_exceptions&gt;` will be raised.</span>
355 <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service. In Python3, this file-like object must have a *write* method which accepts a bytes parameter.</span>
326356 <span class="sd"> :return: A 2-element tuple of ( file attributes of the file on server, number of bytes written to *file_obj* ).</span>
327357 <span class="sd"> The file attributes is an integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py)</span>
328358 <span class="sd"> &quot;&quot;&quot;</span>
329 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">retrieveFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="il">0L</span><span class="p">,</span> <span class="o">-</span><span class="il">1L</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span></div>
330
331 <div class="viewcode-block" id="SMBConnection.retrieveFileFromOffset"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFileFromOffset">[docs]</a> <span class="k">def</span> <span class="nf">retrieveFileFromOffset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="il">0L</span><span class="p">,</span> <span class="n">max_length</span> <span class="o">=</span> <span class="o">-</span><span class="il">1L</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
359 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">retrieveFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span></div>
360
361 <div class="viewcode-block" id="SMBConnection.retrieveFileFromOffset"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFileFromOffset">[docs]</a> <span class="k">def</span> <span class="nf">retrieveFileFromOffset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">max_length</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
332362 <span class="sd">&quot;&quot;&quot;</span>
333363 <span class="sd"> Retrieve the contents of the file at *path* on the *service_name* and write these contents to the provided *file_obj*.</span>
334364
335365 <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span>
336366 <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure&lt;smb_exceptions&gt;` will be raised.</span>
337 <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* up to *max_length* number of bytes.</span>
367 <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* up to *max_length* number of bytes. In Python3, this file-like object must have a *write* method which accepts a bytes parameter.</span>
338368 <span class="sd"> :param integer/long offset: the offset in the remote *path* where the first byte will be read and written to *file_obj*. Must be either zero or a positive integer/long value.</span>
339369 <span class="sd"> :param integer/long max_length: maximum number of bytes to read from the remote *path* and write to the *file_obj*. Specify a negative value to read from *offset* to the EOF.</span>
340370 <span class="sd"> If zero, the method returns immediately after the file is opened successfully for reading.</span>
347377 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
348378
349379 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span>
350 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
380 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
351381 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">r</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
352382
353383 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
354 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
355 <span class="k">raise</span> <span class="n">failure</span>
356
357 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
384 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
385 <span class="k">raise</span> <span class="n">failure</span>
386
387 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
358388 <span class="k">try</span><span class="p">:</span>
359389 <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">max_length</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
360390 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
361391 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
362392 <span class="k">finally</span><span class="p">:</span>
363 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
393 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
364394
365395 <span class="k">return</span> <span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></div>
366396
372402 <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span>
373403 <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file at *path* does not exist, it will be created. Otherwise, it will be overwritten.</span>
374404 <span class="sd"> If the *path* refers to a folder or the file cannot be opened for writing, an :doc:`OperationFailure&lt;smb_exceptions&gt;` will be raised.</span>
375 <span class="sd"> :param file_obj: A file-like object that has a *read* method. Data will read continuously from *file_obj* until EOF.</span>
405 <span class="sd"> :param file_obj: A file-like object that has a *read* method. Data will read continuously from *file_obj* until EOF. In Python3, this file-like object must have a *read* method which returns a bytes parameter.</span>
376406 <span class="sd"> :return: Number of bytes uploaded</span>
377407 <span class="sd"> &quot;&quot;&quot;</span>
378 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">storeFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="il">0L</span><span class="p">,</span> <span class="bp">True</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span></div>
379
380 <div class="viewcode-block" id="SMBConnection.storeFileFromOffset"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.storeFileFromOffset">[docs]</a> <span class="k">def</span> <span class="nf">storeFileFromOffset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="il">0L</span><span class="p">,</span> <span class="n">truncate</span> <span class="o">=</span> <span class="bp">False</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
408 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">storeFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="kc">True</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span></div>
409
410 <div class="viewcode-block" id="SMBConnection.storeFileFromOffset"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.storeFileFromOffset">[docs]</a> <span class="k">def</span> <span class="nf">storeFileFromOffset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">truncate</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
381411 <span class="sd">&quot;&quot;&quot;</span>
382412 <span class="sd"> Store the contents of the *file_obj* at *path* on the *service_name*.</span>
383413
395425 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
396426
397427 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span>
398 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
428 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
399429 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">r</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
400430
401431 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
402 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
403 <span class="k">raise</span> <span class="n">failure</span>
404
405 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
432 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
433 <span class="k">raise</span> <span class="n">failure</span>
434
435 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
406436 <span class="k">try</span><span class="p">:</span>
407437 <span class="bp">self</span><span class="o">.</span><span class="n">_storeFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">truncate</span> <span class="o">=</span> <span class="n">truncate</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
408438 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
409439 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
410440 <span class="k">finally</span><span class="p">:</span>
411 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
441 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
412442
413443 <span class="k">return</span> <span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></div>
414444
415 <div class="viewcode-block" id="SMBConnection.deleteFiles"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteFiles">[docs]</a> <span class="k">def</span> <span class="nf">deleteFiles</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
445 <div class="viewcode-block" id="SMBConnection.deleteFiles"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteFiles">[docs]</a> <span class="k">def</span> <span class="nf">deleteFiles</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
416446 <span class="sd">&quot;&quot;&quot;</span>
417447 <span class="sd"> Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.</span>
448
449 <span class="sd"> If delete_matching_folders is True, immediate sub-folders that match the path_file_pattern will be deleted recursively.</span>
418450
419451 <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span>
420452 <span class="sd"> :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.</span>
426458 <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s1">&#39;Not connected to server&#39;</span><span class="p">)</span>
427459
428460 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span>
429 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
430
431 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
432 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
433 <span class="k">raise</span> <span class="n">failure</span>
434
435 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
436 <span class="k">try</span><span class="p">:</span>
437 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteFiles</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
438 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
439 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
440 <span class="k">finally</span><span class="p">:</span>
441 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span></div>
442
443 <div class="viewcode-block" id="SMBConnection.resetFileAttributes"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.resetFileAttributes">[docs]</a> <span class="k">def</span> <span class="nf">resetFileAttributes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
461 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
462
463 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
464 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
465 <span class="k">raise</span> <span class="n">failure</span>
466
467 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
468 <span class="k">try</span><span class="p">:</span>
469 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteFiles</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
470 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
471 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
472 <span class="k">finally</span><span class="p">:</span>
473 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span></div>
474
475 <div class="viewcode-block" id="SMBConnection.resetFileAttributes"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.resetFileAttributes">[docs]</a> <span class="k">def</span> <span class="nf">resetFileAttributes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">file_attributes</span> <span class="o">=</span> <span class="n">ATTR_NORMAL</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
444476 <span class="sd">&quot;&quot;&quot;</span>
445477 <span class="sd"> Reset file attributes of one or more regular files or folders.</span>
446478 <span class="sd"> It supports the use of wildcards in file names, allowing for unlocking of multiple files/folders in a single request.</span>
447479 <span class="sd"> This function is very helpful when deleting files/folders that are read-only.</span>
448 <span class="sd"> Note: this function is currently only implemented for SMB2! Technically, it sets the FILE_ATTRIBUTE_NORMAL flag, therefore clearing all other flags. (See https://msdn.microsoft.com/en-us/library/cc232110.aspx for further information)</span>
480 <span class="sd"> By default, it sets the ATTR_NORMAL flag, therefore clearing all other flags.</span>
481 <span class="sd"> (See https://msdn.microsoft.com/en-us/library/cc232110.aspx for further information)</span>
482
483 <span class="sd"> Note: this function is currently only implemented for SMB2!</span>
449484
450485 <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span>
451486 <span class="sd"> :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.</span>
452487 <span class="sd"> Wildcards may be used in the filename component of the path.</span>
453488 <span class="sd"> If your path/filename contains non-English characters, you must pass in an unicode string.</span>
489 <span class="sd"> :param int file_attributes: The desired file attributes to set. Defaults to `ATTR_NORMAL`.</span>
454490 <span class="sd"> :return: None</span>
455491 <span class="sd"> &quot;&quot;&quot;</span>
456492 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span>
457493 <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s1">&#39;Not connected to server&#39;</span><span class="p">)</span>
458494
459495 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span>
460 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
461
462 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
463 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
464 <span class="k">raise</span> <span class="n">failure</span>
465
466 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
467 <span class="k">try</span><span class="p">:</span>
468 <span class="bp">self</span><span class="o">.</span><span class="n">_resetFileAttributes</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
469 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
470 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
471 <span class="k">finally</span><span class="p">:</span>
472 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span></div>
496 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
497
498 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
499 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
500 <span class="k">raise</span> <span class="n">failure</span>
501
502 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
503 <span class="k">try</span><span class="p">:</span>
504 <span class="bp">self</span><span class="o">.</span><span class="n">_resetFileAttributes</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
505 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
506 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
507 <span class="k">finally</span><span class="p">:</span>
508 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span></div>
473509
474510 <div class="viewcode-block" id="SMBConnection.createDirectory"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.createDirectory">[docs]</a> <span class="k">def</span> <span class="nf">createDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
475511 <span class="sd">&quot;&quot;&quot;</span>
484520 <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s1">&#39;Not connected to server&#39;</span><span class="p">)</span>
485521
486522 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span>
487 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
488
489 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
490 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
491 <span class="k">raise</span> <span class="n">failure</span>
492
493 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
523 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
524
525 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
526 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
527 <span class="k">raise</span> <span class="n">failure</span>
528
529 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
494530 <span class="k">try</span><span class="p">:</span>
495531 <span class="bp">self</span><span class="o">.</span><span class="n">_createDirectory</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
496532 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
497533 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
498534 <span class="k">finally</span><span class="p">:</span>
499 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span></div>
535 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span></div>
500536
501537 <div class="viewcode-block" id="SMBConnection.deleteDirectory"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteDirectory">[docs]</a> <span class="k">def</span> <span class="nf">deleteDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
502538 <span class="sd">&quot;&quot;&quot;</span>
511547 <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s1">&#39;Not connected to server&#39;</span><span class="p">)</span>
512548
513549 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span>
514 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
515
516 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
517 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
518 <span class="k">raise</span> <span class="n">failure</span>
519
520 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
550 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
551
552 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
553 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
554 <span class="k">raise</span> <span class="n">failure</span>
555
556 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
521557 <span class="k">try</span><span class="p">:</span>
522558 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteDirectory</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
523559 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
524560 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
525561 <span class="k">finally</span><span class="p">:</span>
526 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span></div>
562 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span></div>
527563
528564 <div class="viewcode-block" id="SMBConnection.rename"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.rename">[docs]</a> <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
529565 <span class="sd">&quot;&quot;&quot;</span>
539575 <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s1">&#39;Not connected to server&#39;</span><span class="p">)</span>
540576
541577 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span>
542 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
543
544 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
545 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
546 <span class="k">raise</span> <span class="n">failure</span>
547
548 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
578 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
579
580 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
581 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
582 <span class="k">raise</span> <span class="n">failure</span>
583
584 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
549585 <span class="k">try</span><span class="p">:</span>
550586 <span class="bp">self</span><span class="o">.</span><span class="n">_rename</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">)</span>
551587 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
552588 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
553589 <span class="k">finally</span><span class="p">:</span>
554 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span></div>
590 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span></div>
555591
556592 <div class="viewcode-block" id="SMBConnection.echo"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.echo">[docs]</a> <span class="k">def</span> <span class="nf">echo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">10</span><span class="p">):</span>
557593 <span class="sd">&quot;&quot;&quot;</span>
558594 <span class="sd"> Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*.</span>
559595
560 <span class="sd"> :param string data: Data to send to the remote server.</span>
596 <span class="sd"> :param bytes data: Data to send to the remote server. Must be a bytes object.</span>
561597 <span class="sd"> :return: The *data* parameter</span>
562598 <span class="sd"> &quot;&quot;&quot;</span>
563599 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span>
566602 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
567603
568604 <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span>
569 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
605 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
570606 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
571607
572608 <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span>
573 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
574 <span class="k">raise</span> <span class="n">failure</span>
575
576 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span>
609 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
610 <span class="k">raise</span> <span class="n">failure</span>
611
612 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">True</span>
577613 <span class="k">try</span><span class="p">:</span>
578614 <span class="bp">self</span><span class="o">.</span><span class="n">_echo</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">)</span>
579615 <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span>
580616 <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
581617 <span class="k">finally</span><span class="p">:</span>
582 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span>
618 <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="kc">False</span>
583619
584620 <span class="k">return</span> <span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></div>
585621
590626 <span class="k">def</span> <span class="nf">_pollForNetBIOSPacket</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span><span class="p">):</span>
591627 <span class="n">expiry_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">timeout</span>
592628 <span class="n">read_len</span> <span class="o">=</span> <span class="mi">4</span>
593 <span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
629 <span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
594630
595631 <span class="k">while</span> <span class="n">read_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
596632 <span class="k">try</span><span class="p">:</span>
607643
608644 <span class="n">data</span> <span class="o">=</span> <span class="n">data</span> <span class="o">+</span> <span class="n">d</span>
609645 <span class="n">read_len</span> <span class="o">-=</span> <span class="nb">len</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
610 <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
611 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ex</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">TupleType</span><span class="p">):</span>
646 <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
647 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ex</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
612648 <span class="k">if</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EINTR</span> <span class="ow">and</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EAGAIN</span><span class="p">:</span>
613649 <span class="k">raise</span> <span class="n">ex</span>
614650 <span class="k">else</span><span class="p">:</span>
615651 <span class="k">raise</span> <span class="n">ex</span>
616652
617 <span class="n">type_</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&gt;BBH&#39;</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
653 <span class="nb">type</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&gt;BBH&#39;</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
618654 <span class="k">if</span> <span class="n">flags</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">:</span>
619655 <span class="n">length</span> <span class="o">=</span> <span class="n">length</span> <span class="o">|</span> <span class="mh">0x10000</span>
620656
634670
635671 <span class="n">data</span> <span class="o">=</span> <span class="n">data</span> <span class="o">+</span> <span class="n">d</span>
636672 <span class="n">read_len</span> <span class="o">-=</span> <span class="nb">len</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
637 <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
638 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ex</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">TupleType</span><span class="p">):</span>
673 <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
674 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ex</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
639675 <span class="k">if</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EINTR</span> <span class="ow">and</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EAGAIN</span><span class="p">:</span>
640676 <span class="k">raise</span> <span class="n">ex</span>
641677 <span class="k">else</span><span class="p">:</span>
644680 <span class="bp">self</span><span class="o">.</span><span class="n">feedData</span><span class="p">(</span><span class="n">data</span><span class="p">)</span></div>
645681 </pre></div>
646682
683 <div class="clearer"></div>
647684 </div>
685 </div>
686 </div>
687 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
688 <div class="sphinxsidebarwrapper">
689 <div id="searchbox" style="display: none" role="search">
690 <h3 id="searchlabel">Quick search</h3>
691 <div class="searchformwrapper">
692 <form class="search" action="../../search.html" method="get">
693 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
694 <input type="submit" value="Go" />
695 </form>
696 </div>
697 </div>
698 <script>document.getElementById('searchbox').style.display = "block"</script>
648699 </div>
649700 </div>
650701 <div class="clearer"></div>
655706 <li class="right" style="margin-right: 10px">
656707 <a href="../../genindex.html" title="General Index"
657708 >index</a></li>
658 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
659 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &raquo;</li>
709 <li class="right" >
710 <a href="../../py-modindex.html" title="Python Module Index"
711 >modules</a> |</li>
712 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
713 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &#187;</li>
714 <li class="nav-item nav-item-this"><a href="">smb.SMBConnection</a></li>
660715 </ul>
661716 </div>
662717 <div class="footer" role="contentinfo">
663 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
664 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
718 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
719 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
665720 </div>
666721 </body>
667722 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html>
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>smb.SMBProtocol &mdash; pysmb 1.1.18 documentation</title>
9
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>smb.SMBProtocol &#8212; pysmb 1.2.7 documentation</title>
8 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
109 <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../../_static/jquery.js"></script>
23 <script type="text/javascript" src="../../_static/underscore.js"></script>
24 <script type="text/javascript" src="../../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../../index.html" />
26 <link rel="up" title="Module code" href="../index.html" />
27 </head>
28 <body role="document">
10 <script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
11 <script src="../../_static/jquery.js"></script>
12 <script src="../../_static/underscore.js"></script>
13 <script src="../../_static/doctools.js"></script>
14 <link rel="index" title="Index" href="../../genindex.html" />
15 <link rel="search" title="Search" href="../../search.html" />
16 </head><body>
2917 <div class="related" role="navigation" aria-label="related navigation">
3018 <h3>Navigation</h3>
3119 <ul>
3220 <li class="right" style="margin-right: 10px">
3321 <a href="../../genindex.html" title="General Index"
3422 accesskey="I">index</a></li>
35 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
23 <li class="right" >
24 <a href="../../py-modindex.html" title="Python Module Index"
25 >modules</a> |</li>
26 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.7 documentation</a> &#187;</li>
27 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &#187;</li>
28 <li class="nav-item nav-item-this"><a href="">smb.SMBProtocol</a></li>
3729 </ul>
38 </div>
39 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
40 <div class="sphinxsidebarwrapper">
41 <div id="searchbox" style="display: none" role="search">
42 <h3>Quick search</h3>
43 <form class="search" action="../../search.html" method="get">
44 <input type="text" name="q" />
45 <input type="submit" value="Go" />
46 <input type="hidden" name="check_keywords" value="yes" />
47 <input type="hidden" name="area" value="default" />
48 </form>
49 <p class="searchtip" style="font-size: 90%">
50 Enter search terms or a module, class or function name.
51 </p>
52 </div>
53 <script type="text/javascript">$('#searchbox').show(0);</script>
54 </div>
55 </div>
30 </div>
5631
5732 <div class="document">
5833 <div class="documentwrapper">
6035 <div class="body" role="main">
6136
6237 <h1>Source code for smb.SMBProtocol</h1><div class="highlight"><pre>
63
38 <span></span>
6439 <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">time</span>
6540 <span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span><span class="p">,</span> <span class="n">defer</span>
6641 <span class="kn">from</span> <span class="nn">twisted.internet.protocol</span> <span class="kn">import</span> <span class="n">ClientFactory</span><span class="p">,</span> <span class="n">Protocol</span>
67 <span class="kn">from</span> <span class="nn">smb_constants</span> <span class="kn">import</span> <span class="o">*</span>
68 <span class="kn">from</span> <span class="nn">smb_structs</span> <span class="kn">import</span> <span class="o">*</span>
69 <span class="kn">from</span> <span class="nn">base</span> <span class="kn">import</span> <span class="n">SMB</span><span class="p">,</span> <span class="n">NotConnectedError</span><span class="p">,</span> <span class="n">NotReadyError</span><span class="p">,</span> <span class="n">SMBTimeout</span>
42 <span class="kn">from</span> <span class="nn">.smb_constants</span> <span class="kn">import</span> <span class="o">*</span>
43 <span class="kn">from</span> <span class="nn">.smb_structs</span> <span class="kn">import</span> <span class="o">*</span>
44 <span class="kn">from</span> <span class="nn">.base</span> <span class="kn">import</span> <span class="n">SMB</span><span class="p">,</span> <span class="n">NotConnectedError</span><span class="p">,</span> <span class="n">NotReadyError</span><span class="p">,</span> <span class="n">SMBTimeout</span>
7045
7146
7247 <span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span> <span class="s1">&#39;SMBProtocolFactory&#39;</span><span class="p">,</span> <span class="s1">&#39;NotConnectedError&#39;</span><span class="p">,</span> <span class="s1">&#39;NotReadyError&#39;</span> <span class="p">]</span>
8762 <span class="k">else</span><span class="p">:</span>
8863 <span class="bp">self</span><span class="o">.</span><span class="n">onNMBSessionOK</span><span class="p">()</span>
8964
65
9066 <span class="k">def</span> <span class="nf">connectionLost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
9167 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">instance</span> <span class="o">==</span> <span class="bp">self</span><span class="p">:</span>
92 <span class="bp">self</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="bp">None</span>
68 <span class="bp">self</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="kc">None</span>
9369
9470 <span class="k">def</span> <span class="nf">dataReceived</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
9571 <span class="bp">self</span><span class="o">.</span><span class="n">feedData</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
12197 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">instance</span> <span class="o">==</span> <span class="bp">self</span><span class="p">:</span>
12298 <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
12399 <span class="n">to_remove</span> <span class="o">=</span> <span class="p">[]</span>
124 <span class="k">for</span> <span class="n">mid</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
100 <span class="k">for</span> <span class="n">mid</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
125101 <span class="k">if</span> <span class="n">r</span><span class="o">.</span><span class="n">expiry_time</span> <span class="o">&lt;</span> <span class="n">now</span><span class="p">:</span>
126102 <span class="k">try</span><span class="p">:</span>
127103 <span class="n">r</span><span class="o">.</span><span class="n">errback</span><span class="p">(</span><span class="n">SMBTimeout</span><span class="p">())</span>
146122 <span class="c1">#: SMB messages will only be signed when remote server requires signing.</span>
147123 <span class="n">SIGN_WHEN_REQUIRED</span> <span class="o">=</span> <span class="mi">2</span>
148124
149 <div class="viewcode-block" id="SMBProtocolFactory.__init__"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.__init__">[docs]</a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">sign_options</span> <span class="o">=</span> <span class="n">SIGN_WHEN_REQUIRED</span><span class="p">,</span> <span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
125 <div class="viewcode-block" id="SMBProtocolFactory.__init__"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">sign_options</span> <span class="o">=</span> <span class="n">SIGN_WHEN_REQUIRED</span><span class="p">,</span> <span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="kc">False</span><span class="p">):</span>
150126 <span class="sd">&quot;&quot;&quot;</span>
151127 <span class="sd"> Create a new SMBProtocolFactory instance. You will pass this instance to *reactor.connectTCP()* which will then instantiate the TCP connection to the remote SMB/CIFS server.</span>
152128 <span class="sd"> Note that the default TCP port for most SMB/CIFS servers using NetBIOS over TCP/IP is 139.</span>
156132 <span class="sd"> File operations can only be proceeded after the connection has been authenticated successfully.</span>
157133
158134 <span class="sd"> :param string my_name: The local NetBIOS machine name that will identify where this connection is originating from.</span>
159 <span class="sd"> You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\/:*?&quot;;|+``.</span>
135 <span class="sd"> You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\/:*?&quot;;|+``</span>
160136 <span class="sd"> :param string remote_name: The NetBIOS machine name of the remote server.</span>
161137 <span class="sd"> On windows, you can find out the machine name by right-clicking on the &quot;My Computer&quot; and selecting &quot;Properties&quot;.</span>
162138 <span class="sd"> This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.</span>
180156 <span class="bp">self</span><span class="o">.</span><span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="n">use_ntlm_v2</span>
181157 <span class="bp">self</span><span class="o">.</span><span class="n">sign_options</span> <span class="o">=</span> <span class="n">sign_options</span>
182158 <span class="bp">self</span><span class="o">.</span><span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="n">is_direct_tcp</span>
183 <span class="bp">self</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="bp">None</span> <span class="c1">#: The single SMBProtocol instance for each SMBProtocolFactory instance. Usually, you should not need to touch this attribute directly.</span></div>
159 <span class="bp">self</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1">#: The single SMBProtocol instance for each SMBProtocolFactory instance. Usually, you should not need to touch this attribute directly.</span></div>
184160
185161 <span class="c1">#</span>
186162 <span class="c1"># Public Property</span>
239215 <span class="k">return</span> <span class="n">d</span></div>
240216
241217 <div class="viewcode-block" id="SMBProtocolFactory.listPath"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.listPath">[docs]</a> <span class="k">def</span> <span class="nf">listPath</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span>
242 <span class="n">search</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_READONLY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_DIRECTORY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_ARCHIVE</span><span class="p">,</span>
218 <span class="n">search</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_READONLY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_DIRECTORY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_ARCHIVE</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_INCL_NORMAL</span><span class="p">,</span>
243219 <span class="n">pattern</span> <span class="o">=</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
244220 <span class="sd">&quot;&quot;&quot;</span>
245221 <span class="sd"> Retrieve a directory listing of files/folders at *path*</span>
222
223 <span class="sd"> For simplicity, pysmb defines a &quot;normal&quot; file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.</span>
224 <span class="sd"> It ignores other attributes like compression, indexed, sparse, temporary and encryption.</span>
225
226 <span class="sd"> Note that the default search parameter will query for all read-only (SMB_FILE_ATTRIBUTE_READONLY), hidden (SMB_FILE_ATTRIBUTE_HIDDEN),</span>
227 <span class="sd"> system (SMB_FILE_ATTRIBUTE_SYSTEM), archive (SMB_FILE_ATTRIBUTE_ARCHIVE), normal (SMB_FILE_ATTRIBUTE_INCL_NORMAL) files</span>
228 <span class="sd"> and directories (SMB_FILE_ATTRIBUTE_DIRECTORY).</span>
229 <span class="sd"> If you do not need to include &quot;normal&quot; files in the result, define your own search parameter without the SMB_FILE_ATTRIBUTE_INCL_NORMAL constant.</span>
230 <span class="sd"> SMB_FILE_ATTRIBUTE_NORMAL should be used by itself and not be used with other bit constants.</span>
246231
247232 <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span>
248233 <span class="sd"> :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders.</span>
249234 <span class="sd"> :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py).</span>
250 <span class="sd"> The default *search* value will query for all read-only, hidden, system, archive files and directories.</span>
251235 <span class="sd"> :param string/unicode pattern: the filter to apply to the results before returning to the client.</span>
252236 <span class="sd"> :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance&#39;s *errback* method.</span>
253237 <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of :doc:`smb.base.SharedFile&lt;smb_SharedFile&gt;` instances.</span>
304288
305289 <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span>
306290 <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure&lt;smb_exceptions&gt;` will be called in the returned *Deferred* errback.</span>
307 <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service.</span>
291 <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service. In Python3, this file-like object must have a *write* method which accepts a bytes parameter.</span>
308292 <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a 3-element tuple of ( *file_obj*, file attributes of the file on server, number of bytes written to *file_obj* ).</span>
309293 <span class="sd"> The file attributes is an integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py)</span>
310294 <span class="sd"> &quot;&quot;&quot;</span>
311 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">retrieveFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="il">0L</span><span class="p">,</span> <span class="o">-</span><span class="il">1L</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span></div>
312
313 <div class="viewcode-block" id="SMBProtocolFactory.retrieveFileFromOffset"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.retrieveFileFromOffset">[docs]</a> <span class="k">def</span> <span class="nf">retrieveFileFromOffset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="il">0L</span><span class="p">,</span> <span class="n">max_length</span> <span class="o">=</span> <span class="o">-</span><span class="il">1L</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
295 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">retrieveFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span></div>
296
297 <div class="viewcode-block" id="SMBProtocolFactory.retrieveFileFromOffset"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.retrieveFileFromOffset">[docs]</a> <span class="k">def</span> <span class="nf">retrieveFileFromOffset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">max_length</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
314298 <span class="sd">&quot;&quot;&quot;</span>
315299 <span class="sd"> Retrieve the contents of the file at *path* on the *service_name* and write these contents to the provided *file_obj*.</span>
316300
320304
321305 <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span>
322306 <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure&lt;smb_exceptions&gt;` will be called in the returned *Deferred* errback.</span>
323 <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service.</span>
307 <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service. In Python3, this file-like object must have a *write* method which accepts a bytes parameter.</span>
324308 <span class="sd"> :param integer/long offset: the offset in the remote *path* where the first byte will be read and written to *file_obj*. Must be either zero or a positive integer/long value.</span>
325309 <span class="sd"> :param integer/long max_length: maximum number of bytes to read from the remote *path* and write to the *file_obj*. Specify a negative value to read from *offset* to the EOF.</span>
326310 <span class="sd"> If zero, the *Deferred* callback is invoked immediately after the file is opened successfully for reading.</span>
346330 <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span>
347331 <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file at *path* does not exist, it will be created. Otherwise, it will be overwritten.</span>
348332 <span class="sd"> If the *path* refers to a folder or the file cannot be opened for writing, an :doc:`OperationFailure&lt;smb_exceptions&gt;` will be called in the returned *Deferred* errback.</span>
349 <span class="sd"> :param file_obj: A file-like object that has a *read* method. Data will read continuously from *file_obj* until EOF.</span>
333 <span class="sd"> :param file_obj: A file-like object that has a *read* method. Data will read continuously from *file_obj* until EOF. In Python3, this file-like object must have a *read* method which returns a bytes parameter.</span>
350334 <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a 2-element tuple of ( *file_obj*, number of bytes uploaded ).</span>
351335 <span class="sd"> &quot;&quot;&quot;</span>
352336 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span>
356340 <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_storeFile</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
357341 <span class="k">return</span> <span class="n">d</span></div>
358342
359 <div class="viewcode-block" id="SMBProtocolFactory.deleteFiles"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.deleteFiles">[docs]</a> <span class="k">def</span> <span class="nf">deleteFiles</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
343 <div class="viewcode-block" id="SMBProtocolFactory.deleteFiles"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.deleteFiles">[docs]</a> <span class="k">def</span> <span class="nf">deleteFiles</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
360344 <span class="sd">&quot;&quot;&quot;</span>
361345 <span class="sd"> Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.</span>
362346
347 <span class="sd"> If delete_matching_folders is True, immediate sub-folders that match the path_file_pattern will be deleted recursively.</span>
348 <span class="sd"> </span>
363349 <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span>
364350 <span class="sd"> :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.</span>
365351 <span class="sd"> Wildcards may be used in th filename component of the path.</span>
371357 <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s1">&#39;Not connected to server&#39;</span><span class="p">)</span>
372358
373359 <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span>
374 <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_deleteFiles</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
360 <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_deleteFiles</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
375361 <span class="k">return</span> <span class="n">d</span></div>
376362
377363 <div class="viewcode-block" id="SMBProtocolFactory.createDirectory"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.createDirectory">[docs]</a> <span class="k">def</span> <span class="nf">createDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
430416 <span class="sd">&quot;&quot;&quot;</span>
431417 <span class="sd"> Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*.</span>
432418
433 <span class="sd"> :param string data: Data to send to the remote server.</span>
419 <span class="sd"> :param bytes data: Data to send to the remote server. Must be a bytes object.</span>
434420 <span class="sd"> :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance&#39;s *errback* method.</span>
435421 <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *data* parameter.</span>
436422 <span class="sd"> &quot;&quot;&quot;</span>
457443 <span class="c1"># (Do not touch these unless you know what you are doing)</span>
458444 <span class="c1">#</span>
459445
460 <span class="k">def</span> <span class="nf">buildProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
446 <div class="viewcode-block" id="SMBProtocolFactory.buildProtocol"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.buildProtocol">[docs]</a> <span class="k">def</span> <span class="nf">buildProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
461447 <span class="n">p</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">my_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">use_ntlm_v2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sign_options</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_direct_tcp</span><span class="p">)</span>
462448 <span class="n">p</span><span class="o">.</span><span class="n">factory</span> <span class="o">=</span> <span class="bp">self</span>
463 <span class="k">return</span> <span class="n">p</span></div>
449 <span class="k">return</span> <span class="n">p</span></div></div>
464450 </pre></div>
465451
452 <div class="clearer"></div>
466453 </div>
454 </div>
455 </div>
456 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
457 <div class="sphinxsidebarwrapper">
458 <div id="searchbox" style="display: none" role="search">
459 <h3 id="searchlabel">Quick search</h3>
460 <div class="searchformwrapper">
461 <form class="search" action="../../search.html" method="get">
462 <input type="text" name="q" aria-labelledby="searchlabel" />
463 <input type="submit" value="Go" />
464 </form>
465 </div>
466 </div>
467 <script>$('#searchbox').show(0);</script>
467468 </div>
468469 </div>
469470 <div class="clearer"></div>
474475 <li class="right" style="margin-right: 10px">
475476 <a href="../../genindex.html" title="General Index"
476477 >index</a></li>
477 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
478 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &raquo;</li>
478 <li class="right" >
479 <a href="../../py-modindex.html" title="Python Module Index"
480 >modules</a> |</li>
481 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.7 documentation</a> &#187;</li>
482 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &#187;</li>
483 <li class="nav-item nav-item-this"><a href="">smb.SMBProtocol</a></li>
479484 </ul>
480485 </div>
481486 <div class="footer" role="contentinfo">
482 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
483 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
487 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
488 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.4.3.
484489 </div>
485490 </body>
486491 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>smb.base &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../../_static/jquery.js"></script>
23 <script type="text/javascript" src="../../_static/underscore.js"></script>
24 <script type="text/javascript" src="../../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../../index.html" />
26 <link rel="up" title="Module code" href="../index.html" />
27 </head>
28 <body role="document">
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>smb.base &#8212; pysmb 1.2.8 documentation</title>
8 <link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
9 <link rel="stylesheet" type="text/css" href="../../_static/sphinxdoc.css" />
10 <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
11 <script src="../../_static/jquery.js"></script>
12 <script src="../../_static/underscore.js"></script>
13 <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
14 <script src="../../_static/doctools.js"></script>
15 <link rel="index" title="Index" href="../../genindex.html" />
16 <link rel="search" title="Search" href="../../search.html" />
17 </head><body>
2918 <div class="related" role="navigation" aria-label="related navigation">
3019 <h3>Navigation</h3>
3120 <ul>
3221 <li class="right" style="margin-right: 10px">
3322 <a href="../../genindex.html" title="General Index"
3423 accesskey="I">index</a></li>
35 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
24 <li class="right" >
25 <a href="../../py-modindex.html" title="Python Module Index"
26 >modules</a> |</li>
27 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
28 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &#187;</li>
29 <li class="nav-item nav-item-this"><a href="">smb.base</a></li>
3730 </ul>
38 </div>
39 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
40 <div class="sphinxsidebarwrapper">
41 <div id="searchbox" style="display: none" role="search">
42 <h3>Quick search</h3>
43 <form class="search" action="../../search.html" method="get">
44 <input type="text" name="q" />
45 <input type="submit" value="Go" />
46 <input type="hidden" name="check_keywords" value="yes" />
47 <input type="hidden" name="area" value="default" />
48 </form>
49 <p class="searchtip" style="font-size: 90%">
50 Enter search terms or a module, class or function name.
51 </p>
52 </div>
53 <script type="text/javascript">$('#searchbox').show(0);</script>
54 </div>
55 </div>
31 </div>
5632
5733 <div class="document">
5834 <div class="documentwrapper">
6036 <div class="body" role="main">
6137
6238 <h1>Source code for smb.base</h1><div class="highlight"><pre>
63
39 <span></span>
6440 <span class="kn">import</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">binascii</span><span class="o">,</span> <span class="nn">time</span><span class="o">,</span> <span class="nn">hmac</span>
6541 <span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
66 <span class="kn">from</span> <span class="nn">smb_constants</span> <span class="kn">import</span> <span class="o">*</span>
67 <span class="kn">from</span> <span class="nn">smb2_constants</span> <span class="kn">import</span> <span class="o">*</span>
68 <span class="kn">from</span> <span class="nn">smb_structs</span> <span class="kn">import</span> <span class="o">*</span>
69 <span class="kn">from</span> <span class="nn">smb2_structs</span> <span class="kn">import</span> <span class="o">*</span>
42 <span class="kn">from</span> <span class="nn">.smb_constants</span> <span class="kn">import</span> <span class="o">*</span>
43 <span class="kn">from</span> <span class="nn">.smb2_constants</span> <span class="kn">import</span> <span class="o">*</span>
44 <span class="kn">from</span> <span class="nn">.smb_structs</span> <span class="kn">import</span> <span class="o">*</span>
45 <span class="kn">from</span> <span class="nn">.smb2_structs</span> <span class="kn">import</span> <span class="o">*</span>
46 <span class="kn">from</span> <span class="nn">.security_descriptors</span> <span class="kn">import</span> <span class="n">SecurityDescriptor</span>
7047 <span class="kn">from</span> <span class="nn">nmb.base</span> <span class="kn">import</span> <span class="n">NMBSession</span>
71 <span class="kn">from</span> <span class="nn">utils</span> <span class="kn">import</span> <span class="n">convertFILETIMEtoEpoch</span>
72 <span class="kn">import</span> <span class="nn">ntlm</span><span class="o">,</span> <span class="nn">securityblob</span>
48 <span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">convertFILETIMEtoEpoch</span>
49 <span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">ntlm</span><span class="p">,</span> <span class="n">securityblob</span>
50 <span class="kn">from</span> <span class="nn">.strategy</span> <span class="kn">import</span> <span class="n">DataFaultToleranceStrategy</span>
7351
7452 <span class="k">try</span><span class="p">:</span>
7553 <span class="kn">import</span> <span class="nn">hashlib</span>
7654 <span class="n">sha256</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span>
7755 <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
78 <span class="kn">from</span> <span class="nn">utils</span> <span class="kn">import</span> <span class="n">sha256</span>
56 <span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">sha256</span>
7957
8058
8159 <div class="viewcode-block" id="NotReadyError"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.base.NotReadyError">[docs]</a><span class="k">class</span> <span class="nc">NotReadyError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
8967 <div class="viewcode-block" id="SMBTimeout"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.base.SMBTimeout">[docs]</a><span class="k">class</span> <span class="nc">SMBTimeout</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
9068 <span class="sd">&quot;&quot;&quot;Raised when a timeout has occurred while waiting for a response or for a SMB/CIFS operation to complete.&quot;&quot;&quot;</span>
9169 <span class="k">pass</span></div>
92
93
94 <span class="k">def</span> <span class="nf">_convert_to_unicode</span><span class="p">(</span><span class="n">string</span><span class="p">):</span>
95 <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">):</span>
96 <span class="n">string</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
97 <span class="k">return</span> <span class="n">string</span>
9870
9971
10072 <span class="k">class</span> <span class="nc">SMB</span><span class="p">(</span><span class="n">NMBSession</span><span class="p">):</span>
11890 <span class="n">SIGN_WHEN_SUPPORTED</span> <span class="o">=</span> <span class="mi">1</span>
11991 <span class="n">SIGN_WHEN_REQUIRED</span> <span class="o">=</span> <span class="mi">2</span>
12092
121 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">sign_options</span> <span class="o">=</span> <span class="n">SIGN_WHEN_REQUIRED</span><span class="p">,</span> <span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
122 <span class="n">NMBSession</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="n">is_direct_tcp</span><span class="p">)</span>
123 <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">_convert_to_unicode</span><span class="p">(</span><span class="n">username</span><span class="p">)</span>
124 <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">_convert_to_unicode</span><span class="p">(</span><span class="n">password</span><span class="p">)</span>
125 <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="n">_convert_to_unicode</span><span class="p">(</span><span class="n">domain</span><span class="p">)</span>
93 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">sign_options</span> <span class="o">=</span> <span class="n">SIGN_WHEN_REQUIRED</span><span class="p">,</span> <span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="kc">False</span><span class="p">):</span>
94 <span class="n">NMBSession</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="n">is_direct_tcp</span><span class="p">)</span>
95 <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">username</span>
96 <span class="bp">self</span><span class="o">.</span><span class="n">_password</span> <span class="o">=</span> <span class="n">password</span>
97 <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="n">domain</span>
12698 <span class="bp">self</span><span class="o">.</span><span class="n">sign_options</span> <span class="o">=</span> <span class="n">sign_options</span>
12799 <span class="bp">self</span><span class="o">.</span><span class="n">is_direct_tcp</span> <span class="o">=</span> <span class="n">is_direct_tcp</span>
128100 <span class="bp">self</span><span class="o">.</span><span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="n">use_ntlm_v2</span> <span class="c1">#: Similar to LMAuthenticationPolicy and NTAuthenticationPolicy as described in [MS-CIFS] 3.2.1.1</span>
129101 <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">()</span>
130 <span class="bp">self</span><span class="o">.</span><span class="n">is_using_smb2</span> <span class="o">=</span> <span class="bp">False</span> <span class="c1">#: Are we communicating using SMB2 protocol? self.smb_message will be a SMB2Message instance if this flag is True</span>
102 <span class="bp">self</span><span class="o">.</span><span class="n">is_using_smb2</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1">#: Are we communicating using SMB2 protocol? self.smb_message will be a SMB2Message instance if this flag is True</span>
103 <span class="bp">self</span><span class="o">.</span><span class="n">async_requests</span> <span class="o">=</span> <span class="p">{</span> <span class="p">}</span> <span class="c1">#: AsyncID mapped to _PendingRequest instance</span>
131104 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span> <span class="o">=</span> <span class="p">{</span> <span class="p">}</span> <span class="c1">#: MID mapped to _PendingRequest instance</span>
132105 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span> <span class="o">=</span> <span class="p">{</span> <span class="p">}</span> <span class="c1">#: Share name mapped to TID</span>
133106 <span class="bp">self</span><span class="o">.</span><span class="n">next_rpc_call_id</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1">#: Next RPC callID value. Not used directly in SMB message. Usually encapsulated in sub-commands under SMB_COM_TRANSACTION or SMB_COM_TRANSACTION2 messages</span>
134107
135 <span class="bp">self</span><span class="o">.</span><span class="n">has_negotiated</span> <span class="o">=</span> <span class="bp">False</span>
136 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">False</span>
137 <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="o">=</span> <span class="bp">False</span> <span class="c1">#: True if the remote server accepts message signing. All outgoing messages will be signed. Simiar to IsSigningActive as described in [MS-CIFS] 3.2.1.2</span>
138 <span class="bp">self</span><span class="o">.</span><span class="n">signing_session_key</span> <span class="o">=</span> <span class="bp">None</span> <span class="c1">#: Session key for signing packets, if signing is active. Similar to SigningSessionKey as described in [MS-CIFS] 3.2.1.2</span>
139 <span class="bp">self</span><span class="o">.</span><span class="n">signing_challenge_response</span> <span class="o">=</span> <span class="bp">None</span> <span class="c1">#: Contains the challenge response for signing, if signing is active. Similar to SigningChallengeResponse as described in [MS-CIFS] 3.2.1.2</span>
108 <span class="bp">self</span><span class="o">.</span><span class="n">has_negotiated</span> <span class="o">=</span> <span class="kc">False</span>
109 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
110 <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1">#: True if the remote server accepts message signing. All outgoing messages will be signed. Simiar to IsSigningActive as described in [MS-CIFS] 3.2.1.2</span>
111 <span class="bp">self</span><span class="o">.</span><span class="n">signing_session_key</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1">#: Session key for signing packets, if signing is active. Similar to SigningSessionKey as described in [MS-CIFS] 3.2.1.2</span>
112 <span class="bp">self</span><span class="o">.</span><span class="n">signing_challenge_response</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1">#: Contains the challenge response for signing, if signing is active. Similar to SigningChallengeResponse as described in [MS-CIFS] 3.2.1.2</span>
140113 <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="mi">0</span>
141114 <span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="mi">0</span>
142115 <span class="bp">self</span><span class="o">.</span><span class="n">next_signing_id</span> <span class="o">=</span> <span class="mi">2</span> <span class="c1">#: Similar to ClientNextSendSequenceNumber as described in [MS-CIFS] 3.2.1.2</span>
148121
149122 <span class="c1"># SMB1 attributes</span>
150123 <span class="c1"># Most of the following attributes will be initialized upon receipt of SMB_COM_NEGOTIATE message from server (via self._updateServerInfo_SMB1 method)</span>
151 <span class="bp">self</span><span class="o">.</span><span class="n">use_plaintext_authentication</span> <span class="o">=</span> <span class="bp">False</span> <span class="c1">#: Similar to PlaintextAuthenticationPolicy in in [MS-CIFS] 3.2.1.1</span>
124 <span class="bp">self</span><span class="o">.</span><span class="n">use_plaintext_authentication</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1">#: Similar to PlaintextAuthenticationPolicy in in [MS-CIFS] 3.2.1.1</span>
152125 <span class="bp">self</span><span class="o">.</span><span class="n">max_raw_size</span> <span class="o">=</span> <span class="mi">0</span>
153126 <span class="bp">self</span><span class="o">.</span><span class="n">max_buffer_size</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1">#: Similar to MaxBufferSize as described in [MS-CIFS] 3.2.1.1</span>
154127 <span class="bp">self</span><span class="o">.</span><span class="n">max_mpx_count</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1">#: Similar to MaxMpxCount as described in [MS-CIFS] 3.2.1.1</span>
166139 <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">use_ntlm_v2</span> <span class="ow">and</span> <span class="s1">&#39;v2&#39;</span><span class="p">)</span> <span class="ow">or</span> <span class="s1">&#39;v1&#39;</span><span class="p">,</span>
167140 <span class="p">(</span><span class="n">SUPPORT_EXTENDED_SECURITY</span> <span class="ow">and</span> <span class="s1">&#39;with&#39;</span><span class="p">)</span> <span class="ow">or</span> <span class="s1">&#39;without&#39;</span><span class="p">)</span>
168141
142 <span class="nd">@property</span>
143 <span class="k">def</span> <span class="nf">password</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
144 <span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_password</span><span class="p">):</span>
145 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_password</span><span class="p">()</span>
146 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_password</span>
169147
170148 <span class="c1">#</span>
171149 <span class="c1"># NMBSession Methods</span>
178156 <span class="k">pass</span>
179157
180158 <span class="k">def</span> <span class="nf">onNMBSessionMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
181 <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
159 <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
182160 <span class="k">try</span><span class="p">:</span>
183161 <span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
184162 <span class="k">except</span> <span class="n">SMB2ProtocolHeaderError</span><span class="p">:</span>
185163 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Now switching over to SMB2 protocol communication&#39;</span><span class="p">)</span>
186 <span class="bp">self</span><span class="o">.</span><span class="n">is_using_smb2</span> <span class="o">=</span> <span class="bp">True</span>
164 <span class="bp">self</span><span class="o">.</span><span class="n">is_using_smb2</span> <span class="o">=</span> <span class="kc">True</span>
187165 <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># Must reset messageID counter, or else remote SMB2 server will disconnect</span>
188166 <span class="bp">self</span><span class="o">.</span><span class="n">_setupSMB2Methods</span><span class="p">()</span>
189167 <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_klassSMBMessage</span><span class="p">()</span>
235213 <span class="bp">self</span><span class="o">.</span><span class="n">_listShares</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_listShares_SMB1</span>
236214 <span class="bp">self</span><span class="o">.</span><span class="n">_listPath</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_listPath_SMB1</span>
237215 <span class="bp">self</span><span class="o">.</span><span class="n">_listSnapshots</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_listSnapshots_SMB1</span>
216 <span class="bp">self</span><span class="o">.</span><span class="n">_getSecurity</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getSecurity_SMB1</span>
238217 <span class="bp">self</span><span class="o">.</span><span class="n">_getAttributes</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getAttributes_SMB1</span>
239218 <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFile</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFile_SMB1</span>
240219 <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFileFromOffset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFileFromOffset_SMB1</span>
257236 <span class="bp">self</span><span class="o">.</span><span class="n">_listShares</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_listShares_SMB2</span>
258237 <span class="bp">self</span><span class="o">.</span><span class="n">_listPath</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_listPath_SMB2</span>
259238 <span class="bp">self</span><span class="o">.</span><span class="n">_listSnapshots</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_listSnapshots_SMB2</span>
239 <span class="bp">self</span><span class="o">.</span><span class="n">_getSecurity</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getSecurity_SMB2</span>
260240 <span class="bp">self</span><span class="o">.</span><span class="n">_getAttributes</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getAttributes_SMB2</span>
261241 <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFile</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFile_SMB2</span>
262242 <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFileFromOffset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFileFromOffset_SMB2</span>
281261 <span class="k">if</span> <span class="n">smb_message</span><span class="o">.</span><span class="n">mid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
282262 <span class="n">smb_message</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getNextMID_SMB2</span><span class="p">()</span>
283263
284 <span class="k">if</span> <span class="n">smb_message</span><span class="o">.</span><span class="n">command</span> <span class="o">!=</span> <span class="n">SMB2_COM_NEGOTIATE</span> <span class="ow">and</span> <span class="n">smb_message</span><span class="o">.</span><span class="n">command</span> <span class="o">!=</span> <span class="n">SMB2_COM_ECHO</span><span class="p">:</span>
264 <span class="k">if</span> <span class="n">smb_message</span><span class="o">.</span><span class="n">command</span> <span class="o">!=</span> <span class="n">SMB2_COM_NEGOTIATE</span><span class="p">:</span>
285265 <span class="n">smb_message</span><span class="o">.</span><span class="n">session_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session_id</span>
286266
287267 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span><span class="p">:</span>
303283 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">isReply</span><span class="p">:</span>
304284 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB2_COM_NEGOTIATE</span><span class="p">:</span>
305285 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
306 <span class="bp">self</span><span class="o">.</span><span class="n">has_negotiated</span> <span class="o">=</span> <span class="bp">True</span>
286 <span class="bp">self</span><span class="o">.</span><span class="n">has_negotiated</span> <span class="o">=</span> <span class="kc">True</span>
307287 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;SMB2 dialect negotiation successful&#39;</span><span class="p">)</span>
308288 <span class="bp">self</span><span class="o">.</span><span class="n">_updateServerInfo</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="p">)</span>
309289 <span class="bp">self</span><span class="o">.</span><span class="n">_handleNegotiateResponse</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
316296 <span class="k">try</span><span class="p">:</span>
317297 <span class="n">result</span> <span class="o">=</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">decodeAuthResponseSecurityBlob</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">security_blob</span><span class="p">)</span>
318298 <span class="k">if</span> <span class="n">result</span> <span class="o">==</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">RESULT_ACCEPT_COMPLETED</span><span class="p">:</span>
319 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">True</span>
299 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">True</span>
320300 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (on SMB2) successful!&#39;</span><span class="p">)</span>
301
302 <span class="c1"># [MS-SMB2]: 3.2.5.3.1</span>
303 <span class="c1"># If the security subsystem indicates that the session was established by an anonymous user,</span>
304 <span class="c1"># Session.SigningRequired MUST be set to FALSE.</span>
305 <span class="c1"># If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags field of the</span>
306 <span class="c1"># SMB2 SESSION_SETUP Response and if Session.SigningRequired is TRUE, this indicates a SESSION_SETUP</span>
307 <span class="c1"># failure and the connection MUST be terminated. If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags</span>
308 <span class="c1"># field of the SMB2 SESSION_SETUP Response and if RequireMessageSigning is FALSE, Session.SigningRequired</span>
309 <span class="c1"># MUST be set to FALSE.</span>
310 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">isGuestSession</span> <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">isAnonymousSession</span><span class="p">:</span>
311 <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="o">=</span> <span class="kc">False</span>
312 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Signing disabled because session is guest/anonymous&#39;</span><span class="p">)</span>
313
321314 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthOK</span><span class="p">()</span>
322315 <span class="k">else</span><span class="p">:</span>
323316 <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s1">&#39;SMB2_COM_SESSION_SETUP status is 0 but security blob negResult value is </span><span class="si">%d</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">result</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span>
324 <span class="k">except</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
317 <span class="k">except</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
325318 <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">),</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span>
326319 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc0000016</span><span class="p">:</span> <span class="c1"># STATUS_MORE_PROCESSING_REQUIRED</span>
327320 <span class="bp">self</span><span class="o">.</span><span class="n">session_id</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">session_id</span>
329322 <span class="n">result</span><span class="p">,</span> <span class="n">ntlm_token</span> <span class="o">=</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">decodeChallengeSecurityBlob</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">security_blob</span><span class="p">)</span>
330323 <span class="k">if</span> <span class="n">result</span> <span class="o">==</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">RESULT_ACCEPT_INCOMPLETE</span><span class="p">:</span>
331324 <span class="bp">self</span><span class="o">.</span><span class="n">_handleSessionChallenge</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">ntlm_token</span><span class="p">)</span>
332 <span class="k">except</span> <span class="p">(</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span><span class="p">,</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">UnsupportedSecurityProvider</span> <span class="p">),</span> <span class="n">ex</span><span class="p">:</span>
325 <span class="k">except</span> <span class="p">(</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span><span class="p">,</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">UnsupportedSecurityProvider</span> <span class="p">)</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
333326 <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">),</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span>
334 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc000006d</span><span class="p">:</span> <span class="c1"># STATUS_LOGON_FAILURE</span>
335 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">False</span>
327 <span class="k">elif</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc000006d</span> <span class="c1"># STATUS_LOGON_FAILURE</span>
328 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc0000064</span> <span class="c1"># STATUS_NO_SUCH_USER</span>
329 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc000006a</span><span class="p">):</span><span class="c1"># STATUS_WRONG_PASSWORD</span>
330 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
336331 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (on SMB2) failed. Please check username and password.&#39;</span><span class="p">)</span>
337332 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
333 <span class="k">elif</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc0000193</span> <span class="c1"># STATUS_ACCOUNT_EXPIRED</span>
334 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xC0000071</span><span class="p">):</span> <span class="c1"># STATUS_PASSWORD_EXPIRED</span>
335 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
336 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (on SMB2) failed. Account or password has expired.&#39;</span><span class="p">)</span>
337 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
338 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc0000234</span><span class="p">:</span> <span class="c1"># STATUS_ACCOUNT_LOCKED_OUT</span>
339 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
340 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (on SMB2) failed. Account has been locked due to too many invalid logon attempts.&#39;</span><span class="p">)</span>
341 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
342 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc0000072</span><span class="p">:</span> <span class="c1"># STATUS_ACCOUNT_DISABLED</span>
343 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
344 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (on SMB2) failed. Account has been disabled.&#39;</span><span class="p">)</span>
345 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
346 <span class="k">elif</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc000006f</span> <span class="c1"># STATUS_INVALID_LOGON_HOURS</span>
347 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc000015b</span> <span class="c1"># STATUS_LOGON_TYPE_NOT_GRANTED</span>
348 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc0000070</span><span class="p">):</span> <span class="c1"># STATUS_INVALID_WORKSTATION</span>
349 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
350 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (on SMB2) failed. Not allowed.&#39;</span><span class="p">)</span>
351 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
352 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc000018c</span><span class="p">:</span> <span class="c1"># STATUS_TRUSTED_DOMAIN_FAILURE</span>
353 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
354 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (on SMB2) failed. Domain not trusted.&#39;</span><span class="p">)</span>
355 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
356 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc000018d</span><span class="p">:</span> <span class="c1"># STATUS_TRUSTED_RELATIONSHIP_FAILURE</span>
357 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
358 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (on SMB2) failed. Workstation not trusted.&#39;</span><span class="p">)</span>
359 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
338360 <span class="k">else</span><span class="p">:</span>
339361 <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s1">&#39;Unknown status value (0x</span><span class="si">%08X</span><span class="s1">) in SMB_COM_SESSION_SETUP_ANDX (with extended security)&#39;</span> <span class="o">%</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="p">,</span>
340362 <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span>
341363
342 <span class="n">req</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
343 <span class="k">if</span> <span class="n">req</span><span class="p">:</span>
344 <span class="n">req</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">req</span><span class="o">.</span><span class="n">kwargs</span><span class="p">)</span>
345 <span class="k">return</span> <span class="bp">True</span>
364 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">isAsync</span><span class="p">:</span>
365 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0x00000103</span><span class="p">:</span> <span class="c1"># STATUS_PENDING</span>
366 <span class="n">req</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
367 <span class="k">if</span> <span class="n">req</span><span class="p">:</span>
368 <span class="bp">self</span><span class="o">.</span><span class="n">async_requests</span><span class="p">[</span><span class="n">message</span><span class="o">.</span><span class="n">async_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">req</span>
369 <span class="k">else</span><span class="p">:</span> <span class="c1"># All other status including SUCCESS</span>
370 <span class="n">req</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">async_requests</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">async_id</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
371 <span class="k">if</span> <span class="n">req</span><span class="p">:</span>
372 <span class="n">req</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">req</span><span class="o">.</span><span class="n">kwargs</span><span class="p">)</span>
373 <span class="k">return</span> <span class="kc">True</span>
374 <span class="k">else</span><span class="p">:</span>
375 <span class="n">req</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
376 <span class="k">if</span> <span class="n">req</span><span class="p">:</span>
377 <span class="n">req</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">req</span><span class="o">.</span><span class="n">kwargs</span><span class="p">)</span>
378 <span class="k">return</span> <span class="kc">True</span>
346379
347380
348381 <span class="k">def</span> <span class="nf">_updateServerInfo_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">payload</span><span class="p">):</span>
351384 <span class="bp">self</span><span class="o">.</span><span class="n">max_transact_size</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="n">max_transact_size</span>
352385 <span class="bp">self</span><span class="o">.</span><span class="n">max_read_size</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="n">max_read_size</span>
353386 <span class="bp">self</span><span class="o">.</span><span class="n">max_write_size</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="n">max_write_size</span>
354 <span class="bp">self</span><span class="o">.</span><span class="n">use_plaintext_authentication</span> <span class="o">=</span> <span class="bp">False</span> <span class="c1"># SMB2 never allows plaintext authentication</span>
387 <span class="bp">self</span><span class="o">.</span><span class="n">use_plaintext_authentication</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1"># SMB2 never allows plaintext authentication</span>
355388
356389
357390 <span class="k">def</span> <span class="nf">_handleNegotiateResponse_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
375408
376409 <span class="k">else</span><span class="p">:</span>
377410 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Performing NTLMv1 authentication (on SMB2) with server challenge &quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">server_challenge</span><span class="p">))</span>
378 <span class="n">nt_challenge_response</span><span class="p">,</span> <span class="n">lm_challenge_response</span><span class="p">,</span> <span class="n">session_key</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateChallengeResponseV1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">server_challenge</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>
379
380 <span class="n">ntlm_data</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateAuthenticateMessage</span><span class="p">(</span><span class="n">server_flags</span><span class="p">,</span>
381 <span class="n">nt_challenge_response</span><span class="p">,</span>
382 <span class="n">lm_challenge_response</span><span class="p">,</span>
383 <span class="n">session_key</span><span class="p">,</span>
384 <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span>
385 <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">)</span>
411 <span class="n">nt_challenge_response</span><span class="p">,</span> <span class="n">lm_challenge_response</span><span class="p">,</span> <span class="n">session_key</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateChallengeResponseV1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">server_challenge</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
412
413 <span class="n">ntlm_data</span><span class="p">,</span> <span class="n">session_signing_key</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateAuthenticateMessage</span><span class="p">(</span><span class="n">server_flags</span><span class="p">,</span>
414 <span class="n">nt_challenge_response</span><span class="p">,</span>
415 <span class="n">lm_challenge_response</span><span class="p">,</span>
416 <span class="n">session_key</span><span class="p">,</span>
417 <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span>
418 <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span>
419 <span class="bp">self</span><span class="o">.</span><span class="n">my_name</span><span class="p">)</span>
386420
387421 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">):</span>
388422 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s1">&#39;NT challenge response is &quot;</span><span class="si">%s</span><span class="s1">&quot; (</span><span class="si">%d</span><span class="s1"> bytes)&#39;</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">nt_challenge_response</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">nt_challenge_response</span><span class="p">))</span>
398432 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Server supports SMB signing&#39;</span><span class="p">)</span>
399433 <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sign_options</span> <span class="o">==</span> <span class="n">SMB</span><span class="o">.</span><span class="n">SIGN_WHEN_SUPPORTED</span><span class="p">)</span>
400434 <span class="k">else</span><span class="p">:</span>
401 <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="o">=</span> <span class="bp">False</span>
435 <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="o">=</span> <span class="kc">False</span>
402436
403437 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span><span class="p">:</span>
404438 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;SMB signing activated. All SMB messages will be signed.&quot;</span><span class="p">)</span>
405 <span class="bp">self</span><span class="o">.</span><span class="n">signing_session_key</span> <span class="o">=</span> <span class="p">(</span><span class="n">session_key</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="mi">16</span><span class="p">)[:</span><span class="mi">16</span><span class="p">]</span>
439 <span class="bp">self</span><span class="o">.</span><span class="n">signing_session_key</span> <span class="o">=</span> <span class="n">session_signing_key</span>
440 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">):</span>
441 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;SMB signing key is </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">signing_session_key</span><span class="p">))</span>
442
406443 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">capabilities</span> <span class="o">&amp;</span> <span class="n">CAP_EXTENDED_SECURITY</span><span class="p">:</span>
407 <span class="bp">self</span><span class="o">.</span><span class="n">signing_challenge_response</span> <span class="o">=</span> <span class="bp">None</span>
444 <span class="bp">self</span><span class="o">.</span><span class="n">signing_challenge_response</span> <span class="o">=</span> <span class="kc">None</span>
408445 <span class="k">else</span><span class="p">:</span>
409446 <span class="bp">self</span><span class="o">.</span><span class="n">signing_challenge_response</span> <span class="o">=</span> <span class="n">blob</span>
410447 <span class="k">else</span><span class="p">:</span>
431468
432469 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
433470 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
434 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectSrvSvcCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
471 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectSrvSvcCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">)</span>
435472 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
436473
437474 <span class="k">def</span> <span class="nf">connectSrvSvcCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
441478 <span class="c1"># The data_bytes are binding call to Server Service RPC using DCE v1.1 RPC over SMB. See [MS-SRVS] and [C706]</span>
442479 <span class="c1"># If you wish to understand the meanings of the byte stream, I would suggest you use a recent version of WireShark to packet capture the stream</span>
443480 <span class="n">data_bytes</span> <span class="o">=</span> \
444 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;05 00 0b 03 10 00 00 00 74 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
481 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;05 00 0b 03 10 00 00 00 74 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
445482 <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">call_id</span><span class="p">)</span> <span class="o">+</span> \
446 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
483 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
447484 <span class="s2">b8 10 b8 10 00 00 00 00 02 00 00 00 00 00 01 00</span>
448485 <span class="s2">c8 4f 32 4b 70 16 d3 01 12 78 5a 47 bf 6e e1 88</span>
449486 <span class="s2">03 00 00 00 04 5d 88 8a eb 1c c9 11 9f e8 08 00</span>
451488 <span class="s2">70 16 d3 01 12 78 5a 47 bf 6e e1 88 03 00 00 00</span>
452489 <span class="s2">2c 1c b7 6c 12 98 40 45 03 00 00 00 00 00 00 00</span>
453490 <span class="s2">01 00 00 00</span>
454 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
491 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
455492 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2WriteRequest</span><span class="p">(</span><span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
456 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">tid</span>
493 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">]</span>
457494 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
458 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">rpcBindCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
495 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">rpcBindCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
459496 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
460497 <span class="k">else</span><span class="p">:</span>
461498 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list shares: Unable to locate Server Service RPC endpoint&#39;</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span>
464501 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">trans_message</span><span class="p">)</span>
465502 <span class="k">if</span> <span class="n">trans_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
466503 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2ReadRequest</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">read_len</span> <span class="o">=</span> <span class="mi">1024</span><span class="p">,</span> <span class="n">read_offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">))</span>
467 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">trans_message</span><span class="o">.</span><span class="n">tid</span>
504 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">]</span>
468505 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
469 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">rpcReadCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
506 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">rpcReadCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
470507 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
471508 <span class="k">else</span><span class="p">:</span>
472 <span class="n">closeFid</span><span class="p">(</span><span class="n">trans_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">error</span> <span class="o">=</span> <span class="s1">&#39;Failed to list shares: Unable to read from Server Service RPC endpoint&#39;</span><span class="p">)</span>
509 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">error</span> <span class="o">=</span> <span class="s1">&#39;Failed to list shares: Unable to read from Server Service RPC endpoint&#39;</span><span class="p">)</span>
473510
474511 <span class="k">def</span> <span class="nf">rpcReadCB</span><span class="p">(</span><span class="n">read_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
475512 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">read_message</span><span class="p">)</span>
476513 <span class="k">if</span> <span class="n">read_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
477514 <span class="n">call_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getNextRPCCallID</span><span class="p">()</span>
478515
479 <span class="n">padding</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
516 <span class="n">padding</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
480517 <span class="n">remote_name</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\\\\</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span>
481518 <span class="n">server_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">remote_name</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
482519 <span class="n">server_bytes_len</span> <span class="o">=</span> <span class="n">server_len</span> <span class="o">*</span> <span class="mi">2</span>
483520 <span class="k">if</span> <span class="n">server_len</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
484 <span class="n">padding</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
521 <span class="n">padding</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
485522 <span class="n">server_bytes_len</span> <span class="o">+=</span> <span class="mi">2</span>
486523
487524 <span class="c1"># The data bytes are the RPC call to NetrShareEnum (Opnum 15) at Server Service RPC.</span>
488525 <span class="c1"># If you wish to understand the meanings of the byte stream, I would suggest you use a recent version of WireShark to packet capture the stream</span>
489526 <span class="n">data_bytes</span> <span class="o">=</span> \
490 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;05 00 00 03 10 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
527 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;05 00 00 03 10 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
491528 <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;HHI&#39;</span><span class="p">,</span> <span class="mi">72</span><span class="o">+</span><span class="n">server_bytes_len</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">call_id</span><span class="p">)</span> <span class="o">+</span> \
492 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;4c 00 00 00 00 00 0f 00 00 00 02 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
529 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;4c 00 00 00 00 00 0f 00 00 00 02 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
493530 <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;III&#39;</span><span class="p">,</span> <span class="n">server_len</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">server_len</span><span class="p">)</span> <span class="o">+</span> \
494531 <span class="p">(</span><span class="n">remote_name</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="n">padding</span> <span class="o">+</span> \
495 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
532 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
496533 <span class="s2">01 00 00 00 01 00 00 00 04 00 02 00 00 00 00 00</span>
497534 <span class="s2">00 00 00 00 ff ff ff ff 08 00 02 00 00 00 00 00</span>
498 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
535 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
499536 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2IoctlRequest</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="mh">0x0011C017</span><span class="p">,</span> <span class="n">flags</span> <span class="o">=</span> <span class="mh">0x01</span><span class="p">,</span> <span class="n">max_out_size</span> <span class="o">=</span> <span class="mi">8196</span><span class="p">,</span> <span class="n">in_data</span> <span class="o">=</span> <span class="n">data_bytes</span><span class="p">))</span>
500 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">read_message</span><span class="o">.</span><span class="n">tid</span>
537 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">]</span>
501538 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
502 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">listShareResultsCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
539 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">listShareResultsCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
503540 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
504541 <span class="k">else</span><span class="p">:</span>
505 <span class="n">closeFid</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">error</span> <span class="o">=</span> <span class="s1">&#39;Failed to list shares: Unable to bind to Server Service RPC endpoint&#39;</span><span class="p">)</span>
542 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">error</span> <span class="o">=</span> <span class="s1">&#39;Failed to list shares: Unable to bind to Server Service RPC endpoint&#39;</span><span class="p">)</span>
506543
507544 <span class="k">def</span> <span class="nf">listShareResultsCB</span><span class="p">(</span><span class="n">result_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
508545 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">result_message</span><span class="p">)</span>
510547 <span class="c1"># The payload.data_bytes will contain the results of the RPC call to NetrShareEnum (Opnum 15) at Server Service RPC.</span>
511548 <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">result_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">out_data</span>
512549
513 <span class="k">if</span> <span class="nb">ord</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span> <span class="o">&amp;</span> <span class="mh">0x02</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
514 <span class="n">sendReadRequest</span><span class="p">(</span><span class="n">result_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">data_bytes</span><span class="p">)</span>
515 <span class="k">else</span><span class="p">:</span>
516 <span class="n">decodeResults</span><span class="p">(</span><span class="n">result_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">data_bytes</span><span class="p">)</span>
517 <span class="k">elif</span> <span class="n">result_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0x0103</span><span class="p">:</span> <span class="c1"># STATUS_PENDING</span>
518 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">result_message</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">result_message</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">listShareResultsCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
519 <span class="k">else</span><span class="p">:</span>
520 <span class="n">closeFid</span><span class="p">(</span><span class="n">result_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
550 <span class="k">if</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mh">0x02</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
551 <span class="n">sendReadRequest</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">data_bytes</span><span class="p">)</span>
552 <span class="k">else</span><span class="p">:</span>
553 <span class="n">decodeResults</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">data_bytes</span><span class="p">)</span>
554 <span class="k">else</span><span class="p">:</span>
555 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
521556 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list shares: Unable to retrieve shared device list&#39;</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span>
522557
523558 <span class="k">def</span> <span class="nf">decodeResults</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">):</span>
525560 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> <span class="c1"># A list of SharedDevice instances</span>
526561 <span class="n">offset</span> <span class="o">=</span> <span class="mi">36</span> <span class="o">+</span> <span class="mi">12</span> <span class="c1"># You need to study the byte stream to understand the meaning of these constants</span>
527562 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">shares_count</span><span class="p">):</span>
528 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedDevice</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="mi">4</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">8</span><span class="p">])[</span><span class="mi">0</span><span class="p">],</span> <span class="bp">None</span><span class="p">,</span> <span class="bp">None</span><span class="p">))</span>
563 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedDevice</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="mi">4</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">8</span><span class="p">])[</span><span class="mi">0</span><span class="p">],</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">))</span>
529564 <span class="n">offset</span> <span class="o">+=</span> <span class="mi">12</span>
530565
531566 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">shares_count</span><span class="p">):</span>
532567 <span class="n">max_length</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;III&#39;</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">12</span><span class="p">])</span>
533568 <span class="n">offset</span> <span class="o">+=</span> <span class="mi">12</span>
534 <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">],</span> <span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
569 <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">])</span>
535570
536571 <span class="k">if</span> <span class="n">length</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
537572 <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="n">length</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span>
540575
541576 <span class="n">max_length</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;III&#39;</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">12</span><span class="p">])</span>
542577 <span class="n">offset</span> <span class="o">+=</span> <span class="mi">12</span>
543 <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">comments</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">],</span> <span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
578 <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">comments</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">])</span>
544579
545580 <span class="k">if</span> <span class="n">length</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
546581 <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="n">length</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span>
556591 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
557592 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
558593 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">readCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span>
559 <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">data_bytes</span><span class="p">)</span>
594 <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">data_bytes</span><span class="p">)</span>
560595
561596 <span class="k">def</span> <span class="nf">readCB</span><span class="p">(</span><span class="n">read_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
562597 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">read_message</span><span class="p">)</span>
563598 <span class="k">if</span> <span class="n">read_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
564 <span class="n">data_len</span> <span class="o">=</span> <span class="n">read_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_length</span>
565599 <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">read_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data</span>
566600
567 <span class="k">if</span> <span class="nb">ord</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span> <span class="o">&amp;</span> <span class="mh">0x02</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
568 <span class="n">sendReadRequest</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_bytes&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">24</span><span class="p">:</span><span class="n">data_len</span><span class="o">-</span><span class="mi">24</span><span class="p">])</span>
569 <span class="k">else</span><span class="p">:</span>
570 <span class="n">decodeResults</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_bytes&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">24</span><span class="p">:</span><span class="n">data_len</span><span class="o">-</span><span class="mi">24</span><span class="p">])</span>
571 <span class="k">else</span><span class="p">:</span>
572 <span class="n">closeFid</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
601 <span class="k">if</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mh">0x02</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
602 <span class="n">sendReadRequest</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_bytes&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">24</span><span class="p">:])</span>
603 <span class="k">else</span><span class="p">:</span>
604 <span class="n">decodeResults</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_bytes&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">24</span><span class="p">:])</span>
605 <span class="k">else</span><span class="p">:</span>
606 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
573607 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list shares: Unable to retrieve shared device list&#39;</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span>
574608
575 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">results</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
609 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">results</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
576610 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
577611 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
578612 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
580614 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
581615
582616 <span class="k">def</span> <span class="nf">closeCB</span><span class="p">(</span><span class="n">close_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
583 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
617 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
584618 <span class="n">callback</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">])</span>
585 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
619 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
586620 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">],</span> <span class="n">messages_history</span><span class="p">))</span>
587621
588 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
622 <span class="k">if</span> <span class="n">path</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
589623 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
590624 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
591625 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
594628 <span class="k">else</span><span class="p">:</span>
595629 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list shares: Unable to connect to IPC$&#39;</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span>
596630
597 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">path</span> <span class="p">)))</span>
631 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">path</span> <span class="p">)))</span>
598632 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
599633 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">)</span>
600634 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
615649 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
616650
617651 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
618 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
652 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
619653 <span class="s2">28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
620654 <span class="s2">44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
621655 <span class="s2">00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00</span>
622656 <span class="s2">00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
623657 <span class="s2">00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00</span>
624658 <span class="s2">51 46 69 64 00 00 00 00</span>
625 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
659 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
626660 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">path</span><span class="p">,</span>
627661 <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
628 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">FILE_READ_DATA</span> <span class="o">|</span> <span class="n">FILE_READ_EA</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span> <span class="o">|</span> <span class="n">SYNCHRONIZE</span><span class="p">,</span>
662 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">FILE_READ_DATA</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span> <span class="o">|</span> <span class="n">SYNCHRONIZE</span><span class="p">,</span>
629663 <span class="n">share_access</span> <span class="o">=</span> <span class="n">FILE_SHARE_READ</span> <span class="o">|</span> <span class="n">FILE_SHARE_WRITE</span> <span class="o">|</span> <span class="n">FILE_SHARE_DELETE</span><span class="p">,</span>
630664 <span class="n">oplock</span> <span class="o">=</span> <span class="n">SMB2_OPLOCK_LEVEL_NONE</span><span class="p">,</span>
631665 <span class="n">impersonation</span> <span class="o">=</span> <span class="n">SEC_IMPERSONATE</span><span class="p">,</span>
634668 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">create_context_data</span><span class="p">))</span>
635669 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
636670 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
637 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
671 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">)</span>
638672 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
639673
640674 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
641675 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span>
642676 <span class="k">if</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
643 <span class="n">sendQuery</span><span class="p">(</span><span class="n">create_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
677 <span class="n">sendQuery</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
678 <span class="k">elif</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xC0000034</span><span class="p">:</span> <span class="c1"># [MS-ERREF]: STATUS_OBJECT_NAME_INVALID</span>
679 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Path not found&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
644680 <span class="k">else</span><span class="p">:</span>
645681 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open directory&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
646682
647683 <span class="k">def</span> <span class="nf">sendQuery</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">data_buf</span><span class="p">):</span>
648684 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2QueryDirectoryRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span>
649 <span class="n">info_class</span> <span class="o">=</span> <span class="mh">0x03</span><span class="p">,</span> <span class="c1"># FileBothDirectoryInformation</span>
685 <span class="n">info_class</span> <span class="o">=</span> <span class="mh">0x25</span><span class="p">,</span> <span class="c1"># FileIdBothDirectoryInformation</span>
650686 <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
651687 <span class="n">output_buf_len</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_transact_size</span><span class="p">))</span>
652688 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
653689 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
654 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">queryCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">data_buf</span> <span class="o">=</span> <span class="n">data_buf</span><span class="p">)</span>
690 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">queryCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">data_buf</span> <span class="o">=</span> <span class="n">data_buf</span><span class="p">)</span>
655691 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
656692
657693 <span class="k">def</span> <span class="nf">queryCB</span><span class="p">(</span><span class="n">query_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
658694 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">query_message</span><span class="p">)</span>
659695 <span class="k">if</span> <span class="n">query_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
660696 <span class="n">data_buf</span> <span class="o">=</span> <span class="n">decodeQueryStruct</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_buf&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">query_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
661 <span class="n">sendQuery</span><span class="p">(</span><span class="n">query_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">data_buf</span><span class="p">)</span>
662 <span class="k">elif</span> <span class="n">query_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0x80000006</span><span class="n">L</span><span class="p">:</span> <span class="c1"># STATUS_NO_MORE_FILES</span>
663 <span class="n">closeFid</span><span class="p">(</span><span class="n">query_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">results</span> <span class="o">=</span> <span class="n">results</span><span class="p">)</span>
664 <span class="k">else</span><span class="p">:</span>
665 <span class="n">closeFid</span><span class="p">(</span><span class="n">query_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">error</span> <span class="o">=</span> <span class="n">query_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
697 <span class="n">sendQuery</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">data_buf</span><span class="p">)</span>
698 <span class="k">elif</span> <span class="n">query_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xC000000F</span><span class="p">:</span> <span class="c1"># [MS-ERREF]: STATUS_NO_SUCH_FILE</span>
699 <span class="c1"># If there are no matching files, we just treat as success instead of failing</span>
700 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">results</span> <span class="o">=</span> <span class="n">results</span><span class="p">)</span>
701 <span class="k">elif</span> <span class="n">query_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0x80000006</span><span class="p">:</span> <span class="c1"># STATUS_NO_MORE_FILES</span>
702 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">results</span> <span class="o">=</span> <span class="n">results</span><span class="p">)</span>
703 <span class="k">else</span><span class="p">:</span>
704 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">error</span> <span class="o">=</span> <span class="n">query_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
666705
667706 <span class="k">def</span> <span class="nf">decodeQueryStruct</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">):</span>
668 <span class="c1"># SMB_FIND_FILE_BOTH_DIRECTORY_INFO structure. See [MS-CIFS]: 2.2.8.1.7 and [MS-SMB]: 2.2.8.1.1</span>
669 <span class="n">info_format</span> <span class="o">=</span> <span class="s1">&#39;&lt;IIQQQQQQIIIBB24s&#39;</span>
707 <span class="c1"># FileIdBothDirectoryInformation structure. See [MS-SMB]: 2.2.8.1.3 and [MS-FSCC]: 2.4.17</span>
708 <span class="n">info_format</span> <span class="o">=</span> <span class="s1">&#39;&lt;IIQQQQQQIIIBB24sHQ&#39;</span>
670709 <span class="n">info_size</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">info_format</span><span class="p">)</span>
671710
672711 <span class="n">data_length</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">)</span>
678717 <span class="n">next_offset</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> \
679718 <span class="n">create_time</span><span class="p">,</span> <span class="n">last_access_time</span><span class="p">,</span> <span class="n">last_write_time</span><span class="p">,</span> <span class="n">last_attr_change_time</span><span class="p">,</span> \
680719 <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">filename_length</span><span class="p">,</span> <span class="n">ea_size</span><span class="p">,</span> \
681 <span class="n">short_name_length</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">short_name</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="n">info_format</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">info_size</span><span class="p">])</span>
720 <span class="n">short_name_length</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">short_name</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">file_id</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="n">info_format</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">info_size</span><span class="p">])</span>
682721
683722 <span class="n">offset2</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">+</span> <span class="n">info_size</span>
684723 <span class="k">if</span> <span class="n">offset2</span> <span class="o">+</span> <span class="n">filename_length</span> <span class="o">&gt;</span> <span class="n">data_length</span><span class="p">:</span>
685724 <span class="k">return</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:]</span>
686725
687 <span class="n">filename</span> <span class="o">=</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset2</span><span class="p">:</span><span class="n">offset2</span><span class="o">+</span><span class="n">filename_length</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
688 <span class="n">short_name</span> <span class="o">=</span> <span class="n">short_name</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
689 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedFile</span><span class="p">(</span><span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">create_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_access_time</span><span class="p">),</span>
690 <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_write_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_attr_change_time</span><span class="p">),</span>
691 <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">short_name</span><span class="p">,</span> <span class="n">filename</span><span class="p">))</span>
726 <span class="n">filename</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset2</span><span class="p">:</span><span class="n">offset2</span><span class="o">+</span><span class="n">filename_length</span><span class="p">])</span>
727 <span class="n">short_name</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">short_name</span><span class="p">[:</span><span class="n">short_name_length</span><span class="p">])</span>
728
729 <span class="n">accept_result</span> <span class="o">=</span> <span class="kc">False</span>
730 <span class="k">if</span> <span class="p">(</span><span class="n">file_attributes</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span> <span class="mh">0x00</span><span class="p">,</span> <span class="n">ATTR_NORMAL</span> <span class="p">):</span> <span class="c1"># Only the first 8-bits are compared. We ignore other bits like temp, compressed, encryption, sparse, indexed, etc</span>
731 <span class="n">accept_result</span> <span class="o">=</span> <span class="p">(</span><span class="n">search</span> <span class="o">==</span> <span class="n">SMB_FILE_ATTRIBUTE_NORMAL</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="n">search</span> <span class="o">&amp;</span> <span class="n">SMB_FILE_ATTRIBUTE_INCL_NORMAL</span><span class="p">)</span>
732 <span class="k">else</span><span class="p">:</span>
733 <span class="n">accept_result</span> <span class="o">=</span> <span class="p">(</span><span class="n">file_attributes</span> <span class="o">&amp;</span> <span class="n">search</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span>
734 <span class="k">if</span> <span class="n">accept_result</span><span class="p">:</span>
735 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedFile</span><span class="p">(</span><span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">create_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_access_time</span><span class="p">),</span>
736 <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_write_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_attr_change_time</span><span class="p">),</span>
737 <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">short_name</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">file_id</span><span class="p">))</span>
692738
693739 <span class="k">if</span> <span class="n">next_offset</span><span class="p">:</span>
694740 <span class="n">offset</span> <span class="o">+=</span> <span class="n">next_offset</span>
695741 <span class="k">else</span><span class="p">:</span>
696742 <span class="k">break</span>
697 <span class="k">return</span> <span class="s1">&#39;&#39;</span>
698
699 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">results</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
743 <span class="k">return</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
744
745 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">results</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
700746 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
701747 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
702748 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
704750 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
705751
706752 <span class="k">def</span> <span class="nf">closeCB</span><span class="p">(</span><span class="n">close_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
707 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
753 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
708754 <span class="n">callback</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">])</span>
709 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
710 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Query failed with errorcode 0x</span><span class="si">%08x</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
711
712 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
755 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
756 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xC000000F</span><span class="p">:</span> <span class="c1"># [MS-ERREF]: STATUS_NO_SUCH_FILE</span>
757 <span class="c1"># Remote server returns STATUS_NO_SUCH_FILE error so we assume that the search returns no matching files</span>
758 <span class="n">callback</span><span class="p">([</span> <span class="p">])</span>
759 <span class="k">else</span><span class="p">:</span>
760 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Query failed with errorcode 0x</span><span class="si">%08x</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
761
762 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
713763 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
714764 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
715765 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
718768 <span class="k">else</span><span class="p">:</span>
719769 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
720770
721 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
771 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
722772 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
723773 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
724774 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
757807 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">create_context_data</span><span class="p">))</span>
758808 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
759809 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
760 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
810 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">)</span>
761811 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
762812
763813 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
764814 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span>
765815 <span class="k">if</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
766816 <span class="n">p</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span>
817 <span class="n">filename</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_extractLastPathComponent</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
767818 <span class="n">info</span> <span class="o">=</span> <span class="n">SharedFile</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">create_time</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">lastaccess_time</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">lastwrite_time</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">change_time</span><span class="p">,</span>
768819 <span class="n">p</span><span class="o">.</span><span class="n">file_size</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">allocation_size</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">,</span>
769 <span class="nb">unicode</span><span class="p">(</span><span class="n">path</span><span class="p">),</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
770 <span class="n">closeFid</span><span class="p">(</span><span class="n">create_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="n">info</span> <span class="o">=</span> <span class="n">info</span><span class="p">)</span>
820 <span class="n">filename</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
821 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">p</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="n">info</span> <span class="o">=</span> <span class="n">info</span><span class="p">)</span>
771822 <span class="k">else</span><span class="p">:</span>
772823 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to get attributes for </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open remote file object&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
773824
774 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">info</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
825 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">info</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
775826 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
776827 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
777828 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
779830 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
780831
781832 <span class="k">def</span> <span class="nf">closeCB</span><span class="p">(</span><span class="n">close_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
782 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;info&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
833 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;info&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
783834 <span class="n">callback</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;info&#39;</span><span class="p">])</span>
784 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
835 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
785836 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to get attributes for </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Query failed with errorcode 0x</span><span class="si">%08x</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
786837
787 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
838 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
788839 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
789840 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
790841 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
793844 <span class="k">else</span><span class="p">:</span>
794845 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to get attributes for </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
795846
796 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
847 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
797848 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
798849 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
799850 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
800851 <span class="k">else</span><span class="p">:</span>
801852 <span class="n">sendCreate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
802853
803 <span class="k">def</span> <span class="nf">_retrieveFile_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
804 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="il">0L</span><span class="p">,</span> <span class="o">-</span><span class="il">1L</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
805
806 <span class="k">def</span> <span class="nf">_retrieveFileFromOffset_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">max_length</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
854 <span class="k">def</span> <span class="nf">_getSecurity_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
807855 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
808856 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
809857
817865 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
818866
819867 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
820 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
868 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">path</span><span class="p">,</span>
869 <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
870 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">FILE_READ_DATA</span> <span class="o">|</span> <span class="n">FILE_READ_EA</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span> <span class="o">|</span> <span class="n">READ_CONTROL</span> <span class="o">|</span> <span class="n">SYNCHRONIZE</span><span class="p">,</span>
871 <span class="n">share_access</span> <span class="o">=</span> <span class="n">FILE_SHARE_READ</span> <span class="o">|</span> <span class="n">FILE_SHARE_WRITE</span> <span class="o">|</span> <span class="n">FILE_SHARE_DELETE</span><span class="p">,</span>
872 <span class="n">oplock</span> <span class="o">=</span> <span class="n">SMB2_OPLOCK_LEVEL_NONE</span><span class="p">,</span>
873 <span class="n">impersonation</span> <span class="o">=</span> <span class="n">SEC_IMPERSONATE</span><span class="p">,</span>
874 <span class="n">create_options</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
875 <span class="n">create_disp</span> <span class="o">=</span> <span class="n">FILE_OPEN</span><span class="p">))</span>
876 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
877 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
878 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">)</span>
879 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
880
881 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
882 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span>
883 <span class="k">if</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
884 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2QueryInfoRequest</span><span class="p">(</span><span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span>
885 <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
886 <span class="n">additional_info</span> <span class="o">=</span> <span class="n">OWNER_SECURITY_INFORMATION</span> <span class="o">|</span> <span class="n">GROUP_SECURITY_INFORMATION</span> <span class="o">|</span> <span class="n">DACL_SECURITY_INFORMATION</span><span class="p">,</span>
887 <span class="n">info_type</span> <span class="o">=</span> <span class="n">SMB2_INFO_SECURITY</span><span class="p">,</span>
888 <span class="n">file_info_class</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="c1"># [MS-SMB2] 2.2.37, 3.2.4.12</span>
889 <span class="n">input_buf</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
890 <span class="n">output_buf_len</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_transact_size</span><span class="p">))</span>
891 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">]</span>
892 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
893 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">queryCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
894 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
895 <span class="k">else</span><span class="p">:</span>
896 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to get the security descriptor of </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open file or directory&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
897
898 <span class="k">def</span> <span class="nf">queryCB</span><span class="p">(</span><span class="n">query_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
899 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">query_message</span><span class="p">)</span>
900 <span class="k">if</span> <span class="n">query_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
901 <span class="n">security</span> <span class="o">=</span> <span class="n">SecurityDescriptor</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">query_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
902 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">result</span> <span class="o">=</span> <span class="n">security</span><span class="p">)</span>
903 <span class="k">else</span><span class="p">:</span>
904 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">error</span> <span class="o">=</span> <span class="n">query_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
905
906 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">result</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
907 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
908 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
909 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
910 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">closeCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">result</span> <span class="o">=</span> <span class="n">result</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="n">error</span><span class="p">)</span>
911 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
912
913 <span class="k">def</span> <span class="nf">closeCB</span><span class="p">(</span><span class="n">close_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
914 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;result&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
915 <span class="n">callback</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;result&#39;</span><span class="p">])</span>
916 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
917 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to get the security descriptor of </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Query failed with errorcode 0x</span><span class="si">%08x</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
918
919 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
920 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
921 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
922 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
923 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span>
924 <span class="n">sendCreate</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span>
925 <span class="k">else</span><span class="p">:</span>
926 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to get the security descriptor of </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
927
928 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
929 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
930 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
931 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
932 <span class="k">else</span><span class="p">:</span>
933 <span class="n">sendCreate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
934
935 <span class="k">def</span> <span class="nf">_retrieveFile_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
936 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
937
938 <span class="k">def</span> <span class="nf">_retrieveFileFromOffset_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">max_length</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
939 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
940 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
941
942 <span class="n">expiry_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">timeout</span>
943 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
944 <span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">):</span>
945 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
946 <span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">):</span>
947 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
948 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
949 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
950
951 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
952 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
821953 <span class="s2">28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
822954 <span class="s2">44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
823955 <span class="s2">00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00</span>
824956 <span class="s2">00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
825957 <span class="s2">00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00</span>
826958 <span class="s2">51 46 69 64 00 00 00 00</span>
827 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
959 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
828960 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">path</span><span class="p">,</span>
829961 <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
830962 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">FILE_READ_DATA</span> <span class="o">|</span> <span class="n">FILE_READ_EA</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span> <span class="o">|</span> <span class="n">READ_CONTROL</span> <span class="o">|</span> <span class="n">SYNCHRONIZE</span><span class="p">,</span>
831 <span class="n">share_access</span> <span class="o">=</span> <span class="n">FILE_SHARE_READ</span><span class="p">,</span>
963 <span class="n">share_access</span> <span class="o">=</span> <span class="n">FILE_SHARE_READ</span> <span class="o">|</span> <span class="n">FILE_SHARE_WRITE</span><span class="p">,</span>
832964 <span class="n">oplock</span> <span class="o">=</span> <span class="n">SMB2_OPLOCK_LEVEL_NONE</span><span class="p">,</span>
833965 <span class="n">impersonation</span> <span class="o">=</span> <span class="n">SEC_IMPERSONATE</span><span class="p">,</span>
834966 <span class="n">create_options</span> <span class="o">=</span> <span class="n">FILE_SEQUENTIAL_ONLY</span> <span class="o">|</span> <span class="n">FILE_NON_DIRECTORY_FILE</span><span class="p">,</span>
846978 <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
847979 <span class="n">additional_info</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
848980 <span class="n">info_type</span> <span class="o">=</span> <span class="n">SMB2_INFO_FILE</span><span class="p">,</span>
849 <span class="n">file_info_class</span> <span class="o">=</span> <span class="mh">0x16</span><span class="p">,</span> <span class="c1"># FileStreamInformation [MS-FSCC] 2.4</span>
850 <span class="n">input_buf</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
981 <span class="n">file_info_class</span> <span class="o">=</span> <span class="mh">0x05</span><span class="p">,</span> <span class="c1"># FileStandardInformation [MS-FSCC] 2.4</span>
982 <span class="n">input_buf</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span>
851983 <span class="n">output_buf_len</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">))</span>
852 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">tid</span>
984 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">]</span>
853985 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
854986 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">infoCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span>
855 <span class="n">fid</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="n">file_attributes</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">)</span>
987 <span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span>
988 <span class="n">fid</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span>
989 <span class="n">file_attributes</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">)</span>
856990 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
857991 <span class="k">else</span><span class="p">:</span>
858 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open file&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
992 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to retrieve </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open file&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
859993
860994 <span class="k">def</span> <span class="nf">infoCB</span><span class="p">(</span><span class="n">info_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
861995 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">info_message</span><span class="p">)</span>
8701004 <span class="n">remaining_len</span> <span class="o">=</span> <span class="n">file_len</span>
8711005 <span class="k">if</span> <span class="n">starting_offset</span> <span class="o">+</span> <span class="n">remaining_len</span> <span class="o">&gt;</span> <span class="n">file_len</span><span class="p">:</span>
8721006 <span class="n">remaining_len</span> <span class="o">=</span> <span class="n">file_len</span> <span class="o">-</span> <span class="n">starting_offset</span>
873 <span class="n">sendRead</span><span class="p">(</span><span class="n">info_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">remaining_len</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;file_attributes&#39;</span><span class="p">])</span>
874 <span class="k">else</span><span class="p">:</span>
875 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to retrieve information on file&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
1007 <span class="n">sendRead</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">remaining_len</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;file_attributes&#39;</span><span class="p">])</span>
1008 <span class="k">else</span><span class="p">:</span>
1009 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to retrieve </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to retrieve information on file&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
8761010
8771011 <span class="k">def</span> <span class="nf">sendRead</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">remaining_len</span><span class="p">,</span> <span class="n">read_len</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">):</span>
8781012 <span class="n">read_count</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_read_size</span><span class="p">,</span> <span class="n">remaining_len</span><span class="p">)</span>
8801014 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
8811015 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
8821016 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">readCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span>
883 <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span><span class="p">,</span>
1017 <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span><span class="p">,</span>
8841018 <span class="n">remaining_len</span> <span class="o">=</span> <span class="n">remaining_len</span><span class="p">,</span>
8851019 <span class="n">read_len</span> <span class="o">=</span> <span class="n">read_len</span><span class="p">,</span>
8861020 <span class="n">file_attributes</span> <span class="o">=</span> <span class="n">file_attributes</span><span class="p">)</span>
8941028 <span class="n">remaining_len</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;remaining_len&#39;</span><span class="p">]</span> <span class="o">-</span> <span class="n">data_len</span>
8951029
8961030 <span class="k">if</span> <span class="n">remaining_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
897 <span class="n">sendRead</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;offset&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_len</span><span class="p">,</span> <span class="n">remaining_len</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;read_len&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_len</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;file_attributes&#39;</span><span class="p">])</span>
898 <span class="k">else</span><span class="p">:</span>
899 <span class="n">closeFid</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">ret</span> <span class="o">=</span> <span class="p">(</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;file_attributes&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;read_len&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_len</span> <span class="p">))</span>
1031 <span class="n">sendRead</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;offset&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_len</span><span class="p">,</span> <span class="n">remaining_len</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;read_len&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_len</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;file_attributes&#39;</span><span class="p">])</span>
1032 <span class="k">else</span><span class="p">:</span>
1033 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">ret</span> <span class="o">=</span> <span class="p">(</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;file_attributes&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;read_len&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_len</span> <span class="p">))</span>
9001034 <span class="k">else</span><span class="p">:</span>
9011035 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">read_message</span><span class="p">)</span>
902 <span class="n">closeFid</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">error</span> <span class="o">=</span> <span class="n">read_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
903
904 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">ret</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
1036 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">error</span> <span class="o">=</span> <span class="n">read_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
1037
1038 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">ret</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
9051039 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
9061040 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
9071041 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
9091043 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
9101044
9111045 <span class="k">def</span> <span class="nf">closeCB</span><span class="p">(</span><span class="n">close_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
912 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;ret&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
1046 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;ret&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
9131047 <span class="n">callback</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;ret&#39;</span><span class="p">])</span>
914 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
1048 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
9151049 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to retrieve </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Read failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
9161050
917 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
1051 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
9181052 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
9191053 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
9201054 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
9231057 <span class="k">else</span><span class="p">:</span>
9241058 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to retrieve </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
9251059
926 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
1060 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
9271061 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
9281062 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
9291063 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
9311065 <span class="n">sendCreate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
9321066
9331067 <span class="k">def</span> <span class="nf">_storeFile_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
934 <span class="bp">self</span><span class="o">.</span><span class="n">_storeFileFromOffset_SMB2</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="il">0L</span><span class="p">,</span> <span class="bp">True</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
935
936 <span class="k">def</span> <span class="nf">_storeFileFromOffset_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">truncate</span> <span class="o">=</span> <span class="bp">False</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
1068 <span class="bp">self</span><span class="o">.</span><span class="n">_storeFileFromOffset_SMB2</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="kc">True</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
1069
1070 <span class="k">def</span> <span class="nf">_storeFileFromOffset_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">truncate</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
9371071 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
9381072 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
9391073
1074 <span class="n">expiry_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">timeout</span>
9401075 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
9411076 <span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">):</span>
9421077 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
9451080 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
9461081
9471082 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
948 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
1083 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
9491084 <span class="s2">28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
9501085 <span class="s2">44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
9511086 <span class="s2">00 00 00 00 00 00 00 00 20 00 00 00 10 00 04 00</span>
9541089 <span class="s2">00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
9551090 <span class="s2">00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00</span>
9561091 <span class="s2">51 46 69 64 00 00 00 00</span>
957 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
1092 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
9581093 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">path</span><span class="p">,</span>
9591094 <span class="n">file_attributes</span> <span class="o">=</span> <span class="n">ATTR_ARCHIVE</span><span class="p">,</span>
9601095 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">FILE_READ_DATA</span> <span class="o">|</span> <span class="n">FILE_WRITE_DATA</span> <span class="o">|</span> <span class="n">FILE_APPEND_DATA</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span> <span class="o">|</span> <span class="n">FILE_WRITE_ATTRIBUTES</span> <span class="o">|</span> <span class="n">FILE_READ_EA</span> <span class="o">|</span> <span class="n">FILE_WRITE_EA</span> <span class="o">|</span> <span class="n">READ_CONTROL</span> <span class="o">|</span> <span class="n">SYNCHRONIZE</span><span class="p">,</span>
9701105 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
9711106
9721107 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
1108 <span class="n">create_message</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">]</span>
9731109 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span>
9741110 <span class="k">if</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
9751111 <span class="n">sendWrite</span><span class="p">(</span><span class="n">create_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">)</span>
9841120 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2WriteRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">offset</span><span class="p">))</span>
9851121 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
9861122 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
987 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">writeCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span><span class="o">+</span><span class="n">data_len</span><span class="p">)</span>
1123 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">writeCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span><span class="o">+</span><span class="n">data_len</span><span class="p">)</span>
9881124 <span class="k">else</span><span class="p">:</span>
9891125 <span class="n">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span><span class="p">)</span>
9901126
9911127 <span class="k">def</span> <span class="nf">writeCB</span><span class="p">(</span><span class="n">write_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
9921128 <span class="c1"># To avoid crazy memory usage when saving large files, we do not save every write_message in messages_history.</span>
9931129 <span class="k">if</span> <span class="n">write_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
994 <span class="n">sendWrite</span><span class="p">(</span><span class="n">write_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;offset&#39;</span><span class="p">])</span>
1130 <span class="n">sendWrite</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;offset&#39;</span><span class="p">])</span>
9951131 <span class="k">else</span><span class="p">:</span>
9961132 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">write_message</span><span class="p">)</span>
997 <span class="n">closeFid</span><span class="p">(</span><span class="n">write_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
1133 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
9981134 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to store </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Write failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
9991135
1000 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
1136 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
10011137 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
10021138 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
10031139 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
10051141 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
10061142
10071143 <span class="k">def</span> <span class="nf">closeCB</span><span class="p">(</span><span class="n">close_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
1008 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;offset&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
1144 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;offset&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
10091145 <span class="n">callback</span><span class="p">((</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;offset&#39;</span><span class="p">]</span> <span class="p">))</span> <span class="c1"># Note that this is a tuple of 2-elements</span>
1010 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
1146 <span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
10111147 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to store </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Write failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
10121148
1013 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
1149 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
10141150 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
10151151 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
10161152 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
10191155 <span class="k">else</span><span class="p">:</span>
10201156 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to store </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
10211157
1022 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
1158 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
10231159 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
10241160 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
10251161 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
10271163 <span class="n">sendCreate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
10281164
10291165
1030 <span class="k">def</span> <span class="nf">_deleteFiles_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
1166 <span class="k">def</span> <span class="nf">_deleteFiles_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
10311167 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
10321168 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
10331169
10341170 <span class="n">expiry_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">timeout</span>
1171 <span class="n">pattern</span> <span class="o">=</span> <span class="kc">None</span>
10351172 <span class="n">path</span> <span class="o">=</span> <span class="n">path_file_pattern</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
10361173 <span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">):</span>
10371174 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
10381175 <span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">):</span>
10391176 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
1177 <span class="k">else</span><span class="p">:</span>
1178 <span class="n">path_components</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
1179 <span class="k">if</span> <span class="n">path_components</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1</span> <span class="ow">or</span> <span class="n">path_components</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;?&#39;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
1180 <span class="n">path</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path_components</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
1181 <span class="n">pattern</span> <span class="o">=</span> <span class="n">path_components</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
1182 <span class="n">messages_history</span><span class="p">,</span> <span class="n">files_queue</span> <span class="o">=</span> <span class="p">[</span> <span class="p">],</span> <span class="p">[</span> <span class="p">]</span>
1183
1184 <span class="k">if</span> <span class="n">pattern</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1185 <span class="n">path_components</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
1186 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">path_components</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
1187 <span class="n">files_queue</span><span class="o">.</span><span class="n">append</span><span class="p">((</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path_components</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="n">path_components</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="p">))</span>
1188 <span class="k">else</span><span class="p">:</span>
1189 <span class="n">files_queue</span><span class="o">.</span><span class="n">append</span><span class="p">((</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">path</span> <span class="p">))</span>
1190
1191 <span class="k">def</span> <span class="nf">deleteCB</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
1192 <span class="k">if</span> <span class="n">files_queue</span><span class="p">:</span>
1193 <span class="n">p</span><span class="p">,</span> <span class="n">filename</span> <span class="o">=</span> <span class="n">files_queue</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
1194 <span class="k">if</span> <span class="n">filename</span><span class="p">:</span>
1195 <span class="k">if</span> <span class="n">p</span><span class="p">:</span>
1196 <span class="n">filename</span> <span class="o">=</span> <span class="n">p</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="n">filename</span>
1197 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteFiles_SMB2__del</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">],</span> <span class="n">filename</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
1198 <span class="k">else</span><span class="p">:</span>
1199 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteDirectory_SMB2</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
1200 <span class="k">else</span><span class="p">:</span>
1201 <span class="n">callback</span><span class="p">(</span><span class="n">path_file_pattern</span><span class="p">)</span>
1202
1203 <span class="k">def</span> <span class="nf">listCB</span><span class="p">(</span><span class="n">files_list</span><span class="p">):</span>
1204 <span class="n">files_queue</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">files_list</span><span class="p">)</span>
1205 <span class="n">deleteCB</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
1206
1207 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
1208 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
1209 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
1210 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1211 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span>
1212 <span class="k">if</span> <span class="n">files_queue</span><span class="p">:</span>
1213 <span class="n">deleteCB</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
1214 <span class="k">else</span><span class="p">:</span>
1215 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteFiles_SMB2__list</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">listCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
1216 <span class="k">else</span><span class="p">:</span>
1217 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
1218
1219 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
1220 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1221 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
1222 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1223 <span class="k">else</span><span class="p">:</span>
1224 <span class="k">if</span> <span class="n">files_queue</span><span class="p">:</span>
1225 <span class="n">deleteCB</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
1226 <span class="k">else</span><span class="p">:</span>
1227 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteFiles_SMB2__list</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">listCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
1228
1229 <span class="k">def</span> <span class="nf">_deleteFiles_SMB2__list</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
1230 <span class="n">folder_queue</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
1231 <span class="n">files_list</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
1232 <span class="n">current_path</span> <span class="o">=</span> <span class="p">[</span> <span class="n">path</span> <span class="p">]</span>
1233 <span class="n">search</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_READONLY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_DIRECTORY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_ARCHIVE</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_INCL_NORMAL</span>
1234
1235 <span class="k">def</span> <span class="nf">listCB</span><span class="p">(</span><span class="n">results</span><span class="p">):</span>
1236 <span class="n">files</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
1237 <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">filename</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span> <span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="s1">&#39;..&#39;</span> <span class="p">],</span> <span class="n">results</span><span class="p">):</span>
1238 <span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">isDirectory</span><span class="p">:</span>
1239 <span class="k">if</span> <span class="n">delete_matching_folders</span><span class="p">:</span>
1240 <span class="n">folder_queue</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">+</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="o">+</span><span class="n">f</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span>
1241 <span class="k">else</span><span class="p">:</span>
1242 <span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">((</span> <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="o">.</span><span class="n">filename</span> <span class="p">))</span>
1243 <span class="k">if</span> <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">!=</span><span class="n">path</span> <span class="ow">and</span> <span class="n">delete_matching_folders</span><span class="p">:</span>
1244 <span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">((</span> <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="kc">None</span> <span class="p">))</span>
1245
1246 <span class="k">if</span> <span class="n">files</span><span class="p">:</span>
1247 <span class="n">files_list</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">files</span>
1248
1249 <span class="k">if</span> <span class="n">folder_queue</span><span class="p">:</span>
1250 <span class="n">p</span> <span class="o">=</span> <span class="n">folder_queue</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
1251 <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">p</span>
1252 <span class="bp">self</span><span class="o">.</span><span class="n">_listPath_SMB2</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">listCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">search</span> <span class="o">=</span> <span class="n">search</span><span class="p">,</span> <span class="n">pattern</span> <span class="o">=</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">)</span>
1253 <span class="k">else</span><span class="p">:</span>
1254 <span class="n">callback</span><span class="p">(</span><span class="n">files_list</span><span class="p">)</span>
1255
1256 <span class="bp">self</span><span class="o">.</span><span class="n">_listPath_SMB2</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">listCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">search</span> <span class="o">=</span> <span class="n">search</span><span class="p">,</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
1257
1258 <span class="k">def</span> <span class="nf">_deleteFiles_SMB2__del</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">tid</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
10401259 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
10411260
10421261 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
1043 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
1044 <span class="s2">28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
1045 <span class="s2">44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
1046 <span class="s2">00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00</span>
1047 <span class="s2">00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
1048 <span class="s2">00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00</span>
1049 <span class="s2">51 46 69 64 00 00 00 00</span>
1050 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
1262 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
1263 <span class="s2"> 28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
1264 <span class="s2"> 44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
1265 <span class="s2"> 00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00</span>
1266 <span class="s2"> 00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
1267 <span class="s2"> 00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00</span>
1268 <span class="s2"> 51 46 69 64 00 00 00 00</span>
1269 <span class="s2"> &quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
10511270 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">path</span><span class="p">,</span>
10521271 <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
10531272 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">DELETE</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span><span class="p">,</span>
10631282 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
10641283
10651284 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">open_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
1285 <span class="n">open_message</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">]</span>
10661286 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">open_message</span><span class="p">)</span>
10671287 <span class="k">if</span> <span class="n">open_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
10681288 <span class="n">sendDelete</span><span class="p">(</span><span class="n">open_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
1289 <span class="k">elif</span> <span class="n">open_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xc0000034</span><span class="p">:</span> <span class="c1"># STATUS_OBJECT_NAME_NOT_FOUND</span>
1290 <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
1291 <span class="k">elif</span> <span class="n">open_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mh">0xC00000BA</span><span class="p">:</span> <span class="c1"># [MS-ERREF]: STATUS_FILE_IS_A_DIRECTORY</span>
1292 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Cannot delete a folder. Please use deleteDirectory() method or append &quot;/*&quot; to your path if you wish to delete all files in the folder.&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
10691293 <span class="k">else</span><span class="p">:</span>
10701294 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open file&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
10711295
10741298 <span class="n">additional_info</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
10751299 <span class="n">info_type</span> <span class="o">=</span> <span class="n">SMB2_INFO_FILE</span><span class="p">,</span>
10761300 <span class="n">file_info_class</span> <span class="o">=</span> <span class="mh">0x0d</span><span class="p">,</span> <span class="c1"># SMB2_FILE_DISPOSITION_INFO</span>
1077 <span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\x01</span><span class="s1">&#39;</span><span class="p">))</span>
1078 <span class="sd">&#39;&#39;&#39;</span>
1079 <span class="sd"> Resources:</span>
1080 <span class="sd"> https://msdn.microsoft.com/en-us/library/cc246560.aspx</span>
1081 <span class="sd"> https://msdn.microsoft.com/en-us/library/cc232098.aspx</span>
1082 <span class="sd"> &#39;&#39;&#39;</span>
1083 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
1084 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1085 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">)</span>
1301 <span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x01</span><span class="s1">&#39;</span><span class="p">))</span>
1302 <span class="c1"># [MS-SMB2]: 2.2.39, [MS-FSCC]: 2.4.11</span>
1303 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
1304 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1305 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">)</span>
10861306 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
10871307
10881308 <span class="k">def</span> <span class="nf">deleteCB</span><span class="p">(</span><span class="n">delete_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
10891309 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">delete_message</span><span class="p">)</span>
10901310 <span class="k">if</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1091 <span class="n">closeFid</span><span class="p">(</span><span class="n">delete_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
1092 <span class="k">else</span><span class="p">:</span>
1093 <span class="n">closeFid</span><span class="p">(</span><span class="n">delete_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
1094
1095 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
1311 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
1312 <span class="k">else</span><span class="p">:</span>
1313 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
1314
1315 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
10961316 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
10971317 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
10981318 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
11011321
11021322 <span class="k">def</span> <span class="nf">closeCB</span><span class="p">(</span><span class="n">close_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
11031323 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;status&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1104 <span class="n">callback</span><span class="p">(</span><span class="n">path_file_pattern</span><span class="p">)</span>
1324 <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
11051325 <span class="k">else</span><span class="p">:</span>
11061326 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Delete failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
11071327
1108 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
1109 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
1110 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
1111 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1112 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span>
1113 <span class="n">sendCreate</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span>
1114 <span class="k">else</span><span class="p">:</span>
1115 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
1116
1117 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
1118 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1119 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
1120 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1121 <span class="k">else</span><span class="p">:</span>
1122 <span class="n">sendCreate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
1123
1124 <span class="k">def</span> <span class="nf">_resetFileAttributes_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
1328 <span class="n">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">)</span>
1329
1330 <span class="k">def</span> <span class="nf">_resetFileAttributes_SMB2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">file_attributes</span> <span class="o">=</span> <span class="n">ATTR_NORMAL</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
11251331 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
11261332 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
11271333
11341340 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
11351341
11361342 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
1137 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
1343 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
11381344 <span class="s2">28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
11391345 <span class="s2">44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
11401346 <span class="s2">00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00</span>
11411347 <span class="s2">00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
11421348 <span class="s2">00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00</span>
11431349 <span class="s2">51 46 69 64 00 00 00 00</span>
1144 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
1350 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
11451351
11461352 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">path</span><span class="p">,</span>
11471353 <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
11601366 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">open_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
11611367 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">open_message</span><span class="p">)</span>
11621368 <span class="k">if</span> <span class="n">open_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1163 <span class="n">sendReset</span><span class="p">(</span><span class="n">open_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
1369 <span class="n">sendReset</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
11641370 <span class="k">else</span><span class="p">:</span>
11651371 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to reset attributes of </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open file&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
11661372
11691375 <span class="n">additional_info</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
11701376 <span class="n">info_type</span> <span class="o">=</span> <span class="n">SMB2_INFO_FILE</span><span class="p">,</span>
11711377 <span class="n">file_info_class</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span> <span class="c1"># FileBasicInformation</span>
1172 <span class="n">data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;qqqqii&#39;</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mh">0x80</span><span class="p">,</span><span class="mi">0</span><span class="p">)))</span> <span class="c1"># FILE_ATTRIBUTE_NORMAL</span>
1173 <span class="sd">&#39;&#39;&#39;</span>
1174 <span class="sd"> Resources:</span>
1175 <span class="sd"> https://msdn.microsoft.com/en-us/library/cc246560.aspx</span>
1176 <span class="sd"> https://msdn.microsoft.com/en-us/library/cc232064.aspx</span>
1177 <span class="sd"> https://msdn.microsoft.com/en-us/library/cc232094.aspx</span>
1178 <span class="sd"> https://msdn.microsoft.com/en-us/library/cc232110.aspx</span>
1179 <span class="sd"> &#39;&#39;&#39;</span>
1180 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
1181 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1182 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">resetCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">)</span>
1378 <span class="n">data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;qqqqii&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="mi">0</span><span class="p">)))</span>
1379 <span class="c1"># [MS-SMB2]: 2.2.39, [MS-FSCC]: 2.4, [MS-FSCC]: 2.4.7, [MS-FSCC]: 2.6</span>
1380 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
1381 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1382 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">resetCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">)</span>
11831383 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
11841384
11851385 <span class="k">def</span> <span class="nf">resetCB</span><span class="p">(</span><span class="n">reset_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
11861386 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">reset_message</span><span class="p">)</span>
11871387 <span class="k">if</span> <span class="n">reset_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1188 <span class="n">closeFid</span><span class="p">(</span><span class="n">reset_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
1189 <span class="k">else</span><span class="p">:</span>
1190 <span class="n">closeFid</span><span class="p">(</span><span class="n">reset_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="n">reset_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
1191
1192 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
1388 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
1389 <span class="k">else</span><span class="p">:</span>
1390 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="n">reset_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
1391
1392 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
11931393 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
11941394 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
11951395 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
12021402 <span class="k">else</span><span class="p">:</span>
12031403 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to reset attributes of </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Reset failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
12041404
1205 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
1405 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
12061406 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
12071407 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
12081408 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
12111411 <span class="k">else</span><span class="p">:</span>
12121412 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to reset attributes of </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
12131413
1214 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
1414 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
12151415 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
12161416 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
12171417 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
12311431 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
12321432
12331433 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
1234 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
1434 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
12351435 <span class="s2">28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
12361436 <span class="s2">44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
12371437 <span class="s2">00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00</span>
12381438 <span class="s2">00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
12391439 <span class="s2">00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00</span>
12401440 <span class="s2">51 46 69 64 00 00 00 00</span>
1241 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
1441 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
12421442 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">path</span><span class="p">,</span>
12431443 <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
12441444 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">FILE_READ_DATA</span> <span class="o">|</span> <span class="n">FILE_WRITE_DATA</span> <span class="o">|</span> <span class="n">FILE_READ_EA</span> <span class="o">|</span> <span class="n">FILE_WRITE_EA</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span> <span class="o">|</span> <span class="n">FILE_WRITE_ATTRIBUTES</span> <span class="o">|</span> <span class="n">READ_CONTROL</span> <span class="o">|</span> <span class="n">DELETE</span> <span class="o">|</span> <span class="n">SYNCHRONIZE</span><span class="p">,</span>
12501450 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">create_context_data</span><span class="p">))</span>
12511451 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
12521452 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1253 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
1453 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">)</span>
12541454 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
12551455
12561456 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
12571457 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span>
12581458 <span class="k">if</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1259 <span class="n">closeFid</span><span class="p">(</span><span class="n">create_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
1459 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
12601460 <span class="k">else</span><span class="p">:</span>
12611461 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to create directory </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Create failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
12621462
12701470 <span class="k">def</span> <span class="nf">closeCB</span><span class="p">(</span><span class="n">close_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
12711471 <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
12721472
1273 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
1473 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
12741474 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
12751475 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
12761476 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
12791479 <span class="k">else</span><span class="p">:</span>
12801480 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to create directory </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
12811481
1282 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
1482 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
12831483 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
12841484 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
12851485 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
12991499 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
13001500
13011501 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
1302 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
1502 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
13031503 <span class="s2">28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
13041504 <span class="s2">44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
13051505 <span class="s2">00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00</span>
13061506 <span class="s2">00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
13071507 <span class="s2">00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00</span>
13081508 <span class="s2">51 46 69 64 00 00 00 00</span>
1309 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
1509 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
13101510 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">path</span><span class="p">,</span>
13111511 <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
13121512 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">DELETE</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span><span class="p">,</span>
13241524 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">open_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
13251525 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">open_message</span><span class="p">)</span>
13261526 <span class="k">if</span> <span class="n">open_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1327 <span class="n">sendDelete</span><span class="p">(</span><span class="n">open_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
1527 <span class="n">sendDelete</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
13281528 <span class="k">else</span><span class="p">:</span>
13291529 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open directory&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
13301530
13331533 <span class="n">additional_info</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
13341534 <span class="n">info_type</span> <span class="o">=</span> <span class="n">SMB2_INFO_FILE</span><span class="p">,</span>
13351535 <span class="n">file_info_class</span> <span class="o">=</span> <span class="mh">0x0d</span><span class="p">,</span> <span class="c1"># SMB2_FILE_DISPOSITION_INFO</span>
1336 <span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\x01</span><span class="s1">&#39;</span><span class="p">))</span>
1337 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
1338 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1339 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">)</span>
1536 <span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x01</span><span class="s1">&#39;</span><span class="p">))</span>
1537 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
1538 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1539 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">)</span>
13401540 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
13411541
13421542 <span class="k">def</span> <span class="nf">deleteCB</span><span class="p">(</span><span class="n">delete_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
13431543 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">delete_message</span><span class="p">)</span>
13441544 <span class="k">if</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1345 <span class="n">closeFid</span><span class="p">(</span><span class="n">delete_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
1346 <span class="k">else</span><span class="p">:</span>
1347 <span class="n">closeFid</span><span class="p">(</span><span class="n">delete_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
1348
1349 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
1545 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
1546 <span class="k">else</span><span class="p">:</span>
1547 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
1548
1549 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
13501550 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
13511551 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
13521552 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
13591559 <span class="k">else</span><span class="p">:</span>
13601560 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Delete failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
13611561
1362 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
1562 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
13631563 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
13641564 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
13651565 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
13681568 <span class="k">else</span><span class="p">:</span>
13691569 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
13701570
1371 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
1571 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
13721572 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
13731573 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
13741574 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
13951595 <span class="n">old_path</span> <span class="o">=</span> <span class="n">old_path</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
13961596
13971597 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
1398 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
1598 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
13991599 <span class="s2">28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
14001600 <span class="s2">44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
14011601 <span class="s2">00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00</span>
14021602 <span class="s2">00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
14031603 <span class="s2">00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00</span>
14041604 <span class="s2">51 46 69 64 00 00 00 00</span>
1405 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
1605 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
14061606 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">old_path</span><span class="p">,</span>
14071607 <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
14081608 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">DELETE</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span> <span class="o">|</span> <span class="n">SYNCHRONIZE</span><span class="p">,</span>
14201620 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
14211621 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span>
14221622 <span class="k">if</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1423 <span class="n">sendRename</span><span class="p">(</span><span class="n">create_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
1623 <span class="n">sendRename</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
14241624 <span class="k">else</span><span class="p">:</span>
14251625 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to rename </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open file/directory&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
14261626
14271627 <span class="k">def</span> <span class="nf">sendRename</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">):</span>
1428 <span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\x00</span><span class="s1">&#39;</span><span class="o">*</span><span class="mi">16</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">new_path</span><span class="p">)</span><span class="o">*</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="n">new_path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
1628 <span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x00</span><span class="s1">&#39;</span><span class="o">*</span><span class="mi">16</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">new_path</span><span class="p">)</span><span class="o">*</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="n">new_path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
14291629 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2SetInfoRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">,</span>
14301630 <span class="n">additional_info</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
14311631 <span class="n">info_type</span> <span class="o">=</span> <span class="n">SMB2_INFO_FILE</span><span class="p">,</span>
14331633 <span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">))</span>
14341634 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
14351635 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1436 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">renameCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">)</span>
1636 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">renameCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">)</span>
14371637 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
14381638
14391639 <span class="k">def</span> <span class="nf">renameCB</span><span class="p">(</span><span class="n">rename_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
14401640 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rename_message</span><span class="p">)</span>
14411641 <span class="k">if</span> <span class="n">rename_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1442 <span class="n">closeFid</span><span class="p">(</span><span class="n">rename_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
1443 <span class="k">else</span><span class="p">:</span>
1444 <span class="n">closeFid</span><span class="p">(</span><span class="n">rename_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="n">rename_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
1445
1446 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
1642 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
1643 <span class="k">else</span><span class="p">:</span>
1644 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="n">rename_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
1645
1646 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
14471647 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
14481648 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
14491649 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
14561656 <span class="k">else</span><span class="p">:</span>
14571657 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to rename </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Rename failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
14581658
1459 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
1659 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
14601660 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
14611661 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
14621662 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
14651665 <span class="k">else</span><span class="p">:</span>
14661666 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to rename </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
14671667
1468 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
1668 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
14691669 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
14701670 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
14711671 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
14851685 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
14861686
14871687 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
1488 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
1688 <span class="n">create_context_data</span> <span class="o">=</span> <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
14891689 <span class="s2">28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00</span>
14901690 <span class="s2">44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00</span>
14911691 <span class="s2">00 00 00 00 00 00 00 00 00 00 00 00 10 00 04 00</span>
14921692 <span class="s2">00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00</span>
1493 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
1693 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
14941694 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CreateRequest</span><span class="p">(</span><span class="n">path</span><span class="p">,</span>
14951695 <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
14961696 <span class="n">access_mask</span> <span class="o">=</span> <span class="n">FILE_READ_DATA</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span> <span class="o">|</span> <span class="n">SYNCHRONIZE</span><span class="p">,</span>
15081708 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
15091709 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span>
15101710 <span class="k">if</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1511 <span class="n">sendEnumSnapshots</span><span class="p">(</span><span class="n">create_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
1711 <span class="n">sendEnumSnapshots</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
15121712 <span class="k">else</span><span class="p">:</span>
15131713 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list snapshots </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open file/directory&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
15141714
15161716 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2IoctlRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">,</span>
15171717 <span class="n">ctlcode</span> <span class="o">=</span> <span class="mh">0x00144064</span><span class="p">,</span> <span class="c1"># FSCTL_SRV_ENUMERATE_SNAPSHOTS</span>
15181718 <span class="n">flags</span> <span class="o">=</span> <span class="mh">0x0001</span><span class="p">,</span>
1519 <span class="n">in_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
1719 <span class="n">in_data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
15201720 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
15211721 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
15221722 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">enumSnapshotsCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">)</span>
15281728 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
15291729 <span class="n">snapshots_count</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">enum_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">out_data</span><span class="p">[</span><span class="mi">4</span><span class="p">:</span><span class="mi">8</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span>
15301730 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">snapshots_count</span><span class="p">):</span>
1531 <span class="n">s</span> <span class="o">=</span> <span class="n">enum_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">out_data</span><span class="p">[</span><span class="mi">12</span><span class="o">+</span><span class="n">i</span><span class="o">*</span><span class="mi">50</span><span class="p">:</span><span class="mi">12</span><span class="o">+</span><span class="mi">48</span><span class="o">+</span><span class="n">i</span><span class="o">*</span><span class="mi">50</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
1532 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">datetime</span><span class="p">(</span><span class="o">*</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="p">(</span> <span class="n">s</span><span class="p">[</span><span class="mi">5</span><span class="p">:</span><span class="mi">9</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">10</span><span class="p">:</span><span class="mi">12</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">13</span><span class="p">:</span><span class="mi">15</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">16</span><span class="p">:</span><span class="mi">18</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">19</span><span class="p">:</span><span class="mi">21</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">24</span><span class="p">]</span> <span class="p">))))</span>
1731 <span class="n">s</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">enum_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">out_data</span><span class="p">[</span><span class="mi">12</span><span class="o">+</span><span class="n">i</span><span class="o">*</span><span class="mi">50</span><span class="p">:</span><span class="mi">12</span><span class="o">+</span><span class="mi">48</span><span class="o">+</span><span class="n">i</span><span class="o">*</span><span class="mi">50</span><span class="p">])</span>
1732 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">datetime</span><span class="p">(</span><span class="o">*</span><span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="p">(</span> <span class="n">s</span><span class="p">[</span><span class="mi">5</span><span class="p">:</span><span class="mi">9</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">10</span><span class="p">:</span><span class="mi">12</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">13</span><span class="p">:</span><span class="mi">15</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">16</span><span class="p">:</span><span class="mi">18</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">19</span><span class="p">:</span><span class="mi">21</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">24</span><span class="p">]</span> <span class="p">)))))</span>
15331733 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">results</span> <span class="o">=</span> <span class="n">results</span><span class="p">)</span>
15341734 <span class="k">else</span><span class="p">:</span>
15351735 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">status</span> <span class="o">=</span> <span class="n">enum_message</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
15361736
1537 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">results</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
1737 <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">results</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
15381738 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2CloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span>
15391739 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
15401740 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
15421742 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
15431743
15441744 <span class="k">def</span> <span class="nf">closeCB</span><span class="p">(</span><span class="n">close_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
1545 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
1745 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
15461746 <span class="n">callback</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">])</span>
15471747 <span class="k">else</span><span class="p">:</span>
15481748 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list snapshots </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: List failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
15491749
1550 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
1750 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
15511751 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
15521752 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
15531753 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
15561756 <span class="k">else</span><span class="p">:</span>
15571757 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list snapshots </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
15581758
1559 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
1759 <span class="n">m</span> <span class="o">=</span> <span class="n">SMB2Message</span><span class="p">(</span><span class="n">SMB2TreeConnectRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">)))</span>
15601760 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
15611761 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
15621762 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
16201820 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">isReply</span><span class="p">:</span>
16211821 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_NEGOTIATE</span><span class="p">:</span>
16221822 <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
1623 <span class="bp">self</span><span class="o">.</span><span class="n">has_negotiated</span> <span class="o">=</span> <span class="bp">True</span>
1823 <span class="bp">self</span><span class="o">.</span><span class="n">has_negotiated</span> <span class="o">=</span> <span class="kc">True</span>
16241824 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;SMB dialect negotiation successful (ExtendedSecurity:</span><span class="si">%s</span><span class="s1">)&#39;</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">hasExtendedSecurity</span><span class="p">)</span>
16251825 <span class="bp">self</span><span class="o">.</span><span class="n">_updateServerInfo</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="p">)</span>
16261826 <span class="bp">self</span><span class="o">.</span><span class="n">_handleNegotiateResponse</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
16351835 <span class="k">if</span> <span class="n">result</span> <span class="o">==</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">RESULT_ACCEPT_COMPLETED</span><span class="p">:</span>
16361836 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s1">&#39;SMB uid is now </span><span class="si">%d</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span><span class="p">)</span>
16371837 <span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span>
1638 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">True</span>
1838 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">True</span>
16391839 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (with extended security) successful!&#39;</span><span class="p">)</span>
16401840 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthOK</span><span class="p">()</span>
16411841 <span class="k">else</span><span class="p">:</span>
16421842 <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s1">&#39;SMB_COM_SESSION_SETUP_ANDX status is 0 but security blob negResult value is </span><span class="si">%d</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">result</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span>
1643 <span class="k">except</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
1843 <span class="k">except</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
16441844 <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">),</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span>
16451845 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc0000016</span><span class="p">:</span> <span class="c1"># STATUS_MORE_PROCESSING_REQUIRED</span>
16461846 <span class="k">try</span><span class="p">:</span>
16471847 <span class="n">result</span><span class="p">,</span> <span class="n">ntlm_token</span> <span class="o">=</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">decodeChallengeSecurityBlob</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">security_blob</span><span class="p">)</span>
16481848 <span class="k">if</span> <span class="n">result</span> <span class="o">==</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">RESULT_ACCEPT_INCOMPLETE</span><span class="p">:</span>
16491849 <span class="bp">self</span><span class="o">.</span><span class="n">_handleSessionChallenge</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">ntlm_token</span><span class="p">)</span>
1650 <span class="k">except</span> <span class="p">(</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span><span class="p">,</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">UnsupportedSecurityProvider</span> <span class="p">),</span> <span class="n">ex</span><span class="p">:</span>
1850 <span class="k">except</span> <span class="p">(</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span><span class="p">,</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">UnsupportedSecurityProvider</span> <span class="p">)</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
16511851 <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">),</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span>
1652 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc000006d</span><span class="p">:</span> <span class="c1"># STATUS_LOGON_FAILURE</span>
1653 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">False</span>
1654 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (with extended security) failed. Please check username and password. You may need to enable/disable NTLMv2 authentication.&#39;</span><span class="p">)</span>
1852 <span class="k">elif</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc000006d</span> <span class="c1"># STATUS_LOGON_FAILURE</span>
1853 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc0000064</span> <span class="c1"># STATUS_NO_SUCH_USER</span>
1854 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc000006a</span><span class="p">):</span> <span class="c1"># STATUS_WRONG_PASSWORD</span>
1855 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
1856 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (with extended security) failed. Please check username and password.&#39;</span><span class="p">)</span>
1857 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
1858 <span class="k">elif</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc0000193</span> <span class="c1"># STATUS_ACCOUNT_EXPIRED</span>
1859 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xC0000071</span><span class="p">):</span> <span class="c1"># STATUS_PASSWORD_EXPIRED</span>
1860 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
1861 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (with extended security) failed. Account or password has expired.&#39;</span><span class="p">)</span>
1862 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
1863 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc0000234</span><span class="p">:</span> <span class="c1"># STATUS_ACCOUNT_LOCKED_OUT</span>
1864 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
1865 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (with extended security) failed. Account has been locked due to too many invalid logon attempts.&#39;</span><span class="p">)</span>
1866 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
1867 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc0000072</span><span class="p">:</span> <span class="c1"># STATUS_ACCOUNT_DISABLED</span>
1868 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
1869 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (with extended security) failed. Account has been disabled.&#39;</span><span class="p">)</span>
1870 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
1871 <span class="k">elif</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc000006f</span> <span class="c1"># STATUS_INVALID_LOGON_HOURS</span>
1872 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc000015b</span> <span class="c1"># STATUS_LOGON_TYPE_NOT_GRANTED</span>
1873 <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc0000070</span><span class="p">):</span> <span class="c1"># STATUS_INVALID_WORKSTATION</span>
1874 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
1875 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (with extended security) failed. Not allowed.&#39;</span><span class="p">)</span>
1876 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
1877 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc000018c</span><span class="p">:</span> <span class="c1"># STATUS_TRUSTED_DOMAIN_FAILURE</span>
1878 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
1879 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (with extended security) failed. Domain not trusted.&#39;</span><span class="p">)</span>
1880 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
1881 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc000018d</span><span class="p">:</span> <span class="c1"># STATUS_TRUSTED_RELATIONSHIP_FAILURE</span>
1882 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
1883 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (with extended security) failed. Workstation not trusted.&#39;</span><span class="p">)</span>
16551884 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
16561885 <span class="k">else</span><span class="p">:</span>
16571886 <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s1">&#39;Unknown status value (0x</span><span class="si">%08X</span><span class="s1">) in SMB_COM_SESSION_SETUP_ANDX (with extended security)&#39;</span> <span class="o">%</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span><span class="p">,</span>
16601889 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
16611890 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s1">&#39;SMB uid is now </span><span class="si">%d</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span><span class="p">)</span>
16621891 <span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span>
1663 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">True</span>
1892 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">True</span>
16641893 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (without extended security) successful!&#39;</span><span class="p">)</span>
16651894 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthOK</span><span class="p">()</span>
16661895 <span class="k">else</span><span class="p">:</span>
1667 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">False</span>
1896 <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="kc">False</span>
16681897 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Authentication (without extended security) failed. Please check username and password&#39;</span><span class="p">)</span>
16691898 <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span>
16701899 <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_TREE_CONNECT_ANDX</span><span class="p">:</span>
16761905 <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
16771906 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">req</span><span class="o">.</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;path&#39;</span><span class="p">]]</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">tid</span>
16781907
1679 <span class="n">req</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
1908 <span class="n">req</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
16801909 <span class="k">if</span> <span class="n">req</span><span class="p">:</span>
16811910 <span class="n">req</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">req</span><span class="o">.</span><span class="n">kwargs</span><span class="p">)</span>
1682 <span class="k">return</span> <span class="bp">True</span>
1911 <span class="k">return</span> <span class="kc">True</span>
16831912
16841913
16851914 <span class="k">def</span> <span class="nf">_updateServerInfo_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">payload</span><span class="p">):</span>
17111940
17121941 <span class="k">else</span><span class="p">:</span>
17131942 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Performing NTLMv1 authentication (with extended security) with server challenge &quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">server_challenge</span><span class="p">))</span>
1714 <span class="n">nt_challenge_response</span><span class="p">,</span> <span class="n">lm_challenge_response</span><span class="p">,</span> <span class="n">session_key</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateChallengeResponseV1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">server_challenge</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>
1715
1716 <span class="n">ntlm_data</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateAuthenticateMessage</span><span class="p">(</span><span class="n">server_flags</span><span class="p">,</span>
1717 <span class="n">nt_challenge_response</span><span class="p">,</span>
1718 <span class="n">lm_challenge_response</span><span class="p">,</span>
1719 <span class="n">session_key</span><span class="p">,</span>
1720 <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span>
1721 <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">)</span>
1943 <span class="n">nt_challenge_response</span><span class="p">,</span> <span class="n">lm_challenge_response</span><span class="p">,</span> <span class="n">session_key</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateChallengeResponseV1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">server_challenge</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
1944
1945 <span class="n">ntlm_data</span><span class="p">,</span> <span class="n">signing_session_key</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateAuthenticateMessage</span><span class="p">(</span><span class="n">server_flags</span><span class="p">,</span>
1946 <span class="n">nt_challenge_response</span><span class="p">,</span>
1947 <span class="n">lm_challenge_response</span><span class="p">,</span>
1948 <span class="n">session_key</span><span class="p">,</span>
1949 <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span>
1950 <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span>
1951 <span class="bp">self</span><span class="o">.</span><span class="n">my_name</span><span class="p">)</span>
17221952
17231953 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">):</span>
17241954 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s1">&#39;NT challenge response is &quot;</span><span class="si">%s</span><span class="s1">&quot; (</span><span class="si">%d</span><span class="s1"> bytes)&#39;</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">nt_challenge_response</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">nt_challenge_response</span><span class="p">))</span>
17341964 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Server supports SMB signing&#39;</span><span class="p">)</span>
17351965 <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sign_options</span> <span class="o">==</span> <span class="n">SMB</span><span class="o">.</span><span class="n">SIGN_WHEN_SUPPORTED</span><span class="p">)</span>
17361966 <span class="k">else</span><span class="p">:</span>
1737 <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="o">=</span> <span class="bp">False</span>
1967 <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="o">=</span> <span class="kc">False</span>
17381968
17391969 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span><span class="p">:</span>
17401970 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;SMB signing activated. All SMB messages will be signed.&quot;</span><span class="p">)</span>
1741 <span class="bp">self</span><span class="o">.</span><span class="n">signing_session_key</span> <span class="o">=</span> <span class="n">session_key</span>
1971 <span class="bp">self</span><span class="o">.</span><span class="n">signing_session_key</span> <span class="o">=</span> <span class="n">signing_session_key</span>
17421972 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">capabilities</span> <span class="o">&amp;</span> <span class="n">CAP_EXTENDED_SECURITY</span><span class="p">:</span>
1743 <span class="bp">self</span><span class="o">.</span><span class="n">signing_challenge_response</span> <span class="o">=</span> <span class="bp">None</span>
1973 <span class="bp">self</span><span class="o">.</span><span class="n">signing_challenge_response</span> <span class="o">=</span> <span class="kc">None</span>
17441974 <span class="k">else</span><span class="p">:</span>
17451975 <span class="bp">self</span><span class="o">.</span><span class="n">signing_challenge_response</span> <span class="o">=</span> <span class="n">blob</span>
17461976 <span class="k">else</span><span class="p">:</span>
17561986 <span class="n">blob</span> <span class="o">=</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">generateNegotiateSecurityBlob</span><span class="p">(</span><span class="n">ntlm_data</span><span class="p">)</span>
17571987 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComSessionSetupAndxRequest__WithSecurityExtension</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">session_key</span><span class="p">,</span> <span class="n">blob</span><span class="p">)))</span>
17581988 <span class="k">else</span><span class="p">:</span>
1759 <span class="n">nt_password</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateChallengeResponseV1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">challenge</span><span class="p">,</span> <span class="bp">False</span><span class="p">)</span>
1989 <span class="n">nt_password</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateChallengeResponseV1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">challenge</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
17601990 <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;Performing NTLMv1 authentication (without extended security) with challenge &quot;</span><span class="si">%s</span><span class="s1">&quot; and hashed password of &quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span><span class="p">,</span>
17611991 <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">challenge</span><span class="p">),</span>
17621992 <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">nt_password</span><span class="p">))</span>
17631993 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComSessionSetupAndxRequest__NoSecurityExtension</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">session_key</span><span class="p">,</span>
17641994 <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span>
17651995 <span class="n">nt_password</span><span class="p">,</span>
1766 <span class="bp">True</span><span class="p">,</span>
1996 <span class="kc">True</span><span class="p">,</span>
17671997 <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">)))</span>
17681998
17691999 <span class="k">def</span> <span class="nf">_listShares_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
17972027 <span class="c1"># The data_bytes are binding call to Server Service RPC using DCE v1.1 RPC over SMB. See [MS-SRVS] and [C706]</span>
17982028 <span class="c1"># If you wish to understand the meanings of the byte stream, I would suggest you use a recent version of WireShark to packet capture the stream</span>
17992029 <span class="n">data_bytes</span> <span class="o">=</span> \
1800 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;05 00 0b 03 10 00 00 00 48 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
2030 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;05 00 0b 03 10 00 00 00 48 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
18012031 <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">call_id</span><span class="p">)</span> <span class="o">+</span> \
1802 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
2032 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
18032033 <span class="s2">b8 10 b8 10 00 00 00 00 01 00 00 00 00 00 01 00</span>
18042034 <span class="s2">c8 4f 32 4b 70 16 d3 01 12 78 5a 47 bf 6e e1 88</span>
18052035 <span class="s2">03 00 00 00 04 5d 88 8a eb 1c c9 11 9f e8 08 00</span>
1806 <span class="s2">2b 10 48 60 02 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2036 <span class="s2">2b 10 48 60 02 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
18072037 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTransactionRequest</span><span class="p">(</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
18082038 <span class="n">max_data_count</span> <span class="o">=</span> <span class="mi">4280</span><span class="p">,</span>
18092039 <span class="n">max_setup_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
18212051 <span class="k">if</span> <span class="ow">not</span> <span class="n">trans_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
18222052 <span class="n">call_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getNextRPCCallID</span><span class="p">()</span>
18232053
1824 <span class="n">padding</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
2054 <span class="n">padding</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
18252055 <span class="n">server_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
18262056 <span class="n">server_bytes_len</span> <span class="o">=</span> <span class="n">server_len</span> <span class="o">*</span> <span class="mi">2</span>
18272057 <span class="k">if</span> <span class="n">server_len</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
1828 <span class="n">padding</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
2058 <span class="n">padding</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
18292059 <span class="n">server_bytes_len</span> <span class="o">+=</span> <span class="mi">2</span>
18302060
18312061 <span class="c1"># See [MS-CIFS]: 2.2.5.6.1 for more information on TRANS_TRANSACT_NMPIPE (0x0026) parameters</span>
18332063 <span class="c1"># The data bytes are the RPC call to NetrShareEnum (Opnum 15) at Server Service RPC.</span>
18342064 <span class="c1"># If you wish to understand the meanings of the byte stream, I would suggest you use a recent version of WireShark to packet capture the stream</span>
18352065 <span class="n">data_bytes</span> <span class="o">=</span> \
1836 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;05 00 00 03 10 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
2066 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;05 00 00 03 10 00 00 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
18372067 <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;HHI&#39;</span><span class="p">,</span> <span class="mi">72</span><span class="o">+</span><span class="n">server_bytes_len</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">call_id</span><span class="p">)</span> <span class="o">+</span> \
1838 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;4c 00 00 00 00 00 0f 00 00 00 02 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
2068 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;4c 00 00 00 00 00 0f 00 00 00 02 00&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span> <span class="o">+</span> \
18392069 <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;III&#39;</span><span class="p">,</span> <span class="n">server_len</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">server_len</span><span class="p">)</span> <span class="o">+</span> \
18402070 <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="n">padding</span> <span class="o">+</span> \
1841 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
2071 <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;&quot;</span>
18422072 <span class="s2">01 00 00 00 01 00 00 00 04 00 02 00 00 00 00 00</span>
18432073 <span class="s2">00 00 00 00 ff ff ff ff 08 00 02 00 00 00 00 00</span>
1844 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2074 <span class="s2">&quot;&quot;&quot;</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">))</span>
18452075 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTransactionRequest</span><span class="p">(</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
18462076 <span class="n">max_data_count</span> <span class="o">=</span> <span class="mi">4280</span><span class="p">,</span>
18472077 <span class="n">max_setup_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
18612091 <span class="c1"># The payload.data_bytes will contain the results of the RPC call to NetrShareEnum (Opnum 15) at Server Service RPC.</span>
18622092 <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">result_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span>
18632093
1864 <span class="k">if</span> <span class="nb">ord</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span> <span class="o">&amp;</span> <span class="mh">0x02</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
2094 <span class="k">if</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mh">0x02</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
18652095 <span class="n">sendReadRequest</span><span class="p">(</span><span class="n">result_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">data_bytes</span><span class="p">)</span>
18662096 <span class="k">else</span><span class="p">:</span>
18672097 <span class="n">decodeResults</span><span class="p">(</span><span class="n">result_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">data_bytes</span><span class="p">)</span>
18742104 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> <span class="c1"># A list of SharedDevice instances</span>
18752105 <span class="n">offset</span> <span class="o">=</span> <span class="mi">36</span> <span class="o">+</span> <span class="mi">12</span> <span class="c1"># You need to study the byte stream to understand the meaning of these constants</span>
18762106 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">shares_count</span><span class="p">):</span>
1877 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedDevice</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="mi">4</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">8</span><span class="p">])[</span><span class="mi">0</span><span class="p">],</span> <span class="bp">None</span><span class="p">,</span> <span class="bp">None</span><span class="p">))</span>
2107 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedDevice</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="mi">4</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">8</span><span class="p">])[</span><span class="mi">0</span><span class="p">],</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">))</span>
18782108 <span class="n">offset</span> <span class="o">+=</span> <span class="mi">12</span>
18792109
18802110 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">shares_count</span><span class="p">):</span>
18812111 <span class="n">max_length</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;III&#39;</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">12</span><span class="p">])</span>
18822112 <span class="n">offset</span> <span class="o">+=</span> <span class="mi">12</span>
1883 <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">],</span> <span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
2113 <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">])</span>
18842114
18852115 <span class="k">if</span> <span class="n">length</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
18862116 <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="n">length</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span>
18892119
18902120 <span class="n">max_length</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;III&#39;</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">12</span><span class="p">])</span>
18912121 <span class="n">offset</span> <span class="o">+=</span> <span class="mi">12</span>
1892 <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">comments</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">],</span> <span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
2122 <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">comments</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">])</span>
18932123
18942124 <span class="k">if</span> <span class="n">length</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
18952125 <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="n">length</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span>
19122142 <span class="k">def</span> <span class="nf">readCB</span><span class="p">(</span><span class="n">read_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
19132143 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">read_message</span><span class="p">)</span>
19142144 <span class="k">if</span> <span class="ow">not</span> <span class="n">read_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
1915 <span class="n">data_len</span> <span class="o">=</span> <span class="n">read_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_length</span>
19162145 <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">read_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data</span>
19172146
1918 <span class="k">if</span> <span class="nb">ord</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span> <span class="o">&amp;</span> <span class="mh">0x02</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
1919 <span class="n">sendReadRequest</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_bytes&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">24</span><span class="p">:</span><span class="n">data_len</span><span class="o">-</span><span class="mi">24</span><span class="p">])</span>
1920 <span class="k">else</span><span class="p">:</span>
1921 <span class="n">decodeResults</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_bytes&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">24</span><span class="p">:</span><span class="n">data_len</span><span class="o">-</span><span class="mi">24</span><span class="p">])</span>
2147 <span class="k">if</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mh">0x02</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
2148 <span class="n">sendReadRequest</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_bytes&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">24</span><span class="p">:])</span>
2149 <span class="k">else</span><span class="p">:</span>
2150 <span class="n">decodeResults</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_bytes&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">24</span><span class="p">:])</span>
19222151 <span class="k">else</span><span class="p">:</span>
19232152 <span class="n">closeFid</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
19242153 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list shares: Unable to retrieve shared device list&#39;</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span>
19372166 <span class="k">else</span><span class="p">:</span>
19382167 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list shares: Unable to connect to IPC$&#39;</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span>
19392168
1940 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">path</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2169 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">path</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
19412170 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
19422171 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">)</span>
19432172 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
19532182 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
19542183 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
19552184
1956 <span class="k">def</span> <span class="nf">sendFindFirst</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">support_dfs</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
2185 <span class="k">def</span> <span class="nf">sendFindFirst</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">support_dfs</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
19572186 <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;H&#39;</span><span class="p">,</span> <span class="mh">0x0001</span><span class="p">)</span> <span class="c1"># TRANS2_FIND_FIRST2 sub-command. See [MS-CIFS]: 2.2.6.2.1</span>
19582187 <span class="n">params_bytes</span> <span class="o">=</span> \
19592188 <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;HHHHI&#39;</span><span class="p">,</span>
1960 <span class="n">search</span><span class="p">,</span> <span class="c1"># SearchAttributes</span>
2189 <span class="n">search</span> <span class="o">&amp;</span> <span class="mh">0xFFFF</span><span class="p">,</span> <span class="c1"># SearchAttributes (need to restrict the values due to introduction of SMB_FILE_ATTRIBUTE_INCL_NORMAL)</span>
19612190 <span class="mi">100</span><span class="p">,</span> <span class="c1"># SearchCount</span>
19622191 <span class="mh">0x0006</span><span class="p">,</span> <span class="c1"># Flags: SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS</span>
19632192 <span class="mh">0x0104</span><span class="p">,</span> <span class="c1"># InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO</span>
1964 <span class="mh">0x0000</span><span class="p">)</span> <span class="c1"># SearchStorageType</span>
2193 <span class="mh">0x0000</span><span class="p">)</span> <span class="c1"># SearchStorageType (seems to be ignored by Windows)</span>
19652194 <span class="k">if</span> <span class="n">support_dfs</span><span class="p">:</span>
19662195 <span class="n">params_bytes</span> <span class="o">+=</span> <span class="p">(</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\\</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="n">service_name</span> <span class="o">+</span> <span class="n">path</span> <span class="o">+</span> <span class="n">pattern</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
19672196 <span class="k">else</span><span class="p">:</span>
1968 <span class="n">params_bytes</span> <span class="o">+=</span> <span class="p">(</span><span class="n">path</span> <span class="o">+</span> <span class="n">pattern</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
2197 <span class="n">params_bytes</span> <span class="o">+=</span> <span class="p">(</span><span class="n">path</span> <span class="o">+</span> <span class="n">pattern</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
19692198
19702199 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTransaction2Request</span><span class="p">(</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span>
19712200 <span class="n">max_data_count</span> <span class="o">=</span> <span class="mi">16644</span><span class="p">,</span>
19762205 <span class="k">if</span> <span class="n">support_dfs</span><span class="p">:</span>
19772206 <span class="n">m</span><span class="o">.</span><span class="n">flags2</span> <span class="o">|=</span> <span class="n">SMB_FLAGS2_DFS</span>
19782207 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
1979 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">findFirstCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">support_dfs</span><span class="o">=</span><span class="n">support_dfs</span><span class="p">)</span>
2208 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">findFirstCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
19802209 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
19812210
19822211 <span class="k">def</span> <span class="nf">decodeFindStruct</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">):</span>
19992228 <span class="k">if</span> <span class="n">offset2</span> <span class="o">+</span> <span class="n">filename_length</span> <span class="o">&gt;</span> <span class="n">data_length</span><span class="p">:</span>
20002229 <span class="k">return</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:]</span>
20012230
2002 <span class="n">filename</span> <span class="o">=</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset2</span><span class="p">:</span><span class="n">offset2</span><span class="o">+</span><span class="n">filename_length</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
2003 <span class="n">short_name</span> <span class="o">=</span> <span class="n">short_name</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
2004 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedFile</span><span class="p">(</span><span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">create_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_access_time</span><span class="p">),</span>
2005 <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_write_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_attr_change_time</span><span class="p">),</span>
2006 <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">short_name</span><span class="p">,</span> <span class="n">filename</span><span class="p">))</span>
2231 <span class="n">filename</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset2</span><span class="p">:</span><span class="n">offset2</span><span class="o">+</span><span class="n">filename_length</span><span class="p">])</span>
2232 <span class="n">short_name</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">short_name</span><span class="p">)</span>
2233
2234 <span class="n">accept_result</span> <span class="o">=</span> <span class="kc">False</span>
2235 <span class="k">if</span> <span class="p">(</span><span class="n">file_attributes</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span> <span class="mh">0x00</span><span class="p">,</span> <span class="n">ATTR_NORMAL</span> <span class="p">):</span> <span class="c1"># Only the first 8-bits are compared. We ignore other bits like temp, compressed, encryption, sparse, indexed, etc</span>
2236 <span class="n">accept_result</span> <span class="o">=</span> <span class="p">(</span><span class="n">search</span> <span class="o">==</span> <span class="n">SMB_FILE_ATTRIBUTE_NORMAL</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="n">search</span> <span class="o">&amp;</span> <span class="n">SMB_FILE_ATTRIBUTE_INCL_NORMAL</span><span class="p">)</span>
2237 <span class="k">else</span><span class="p">:</span>
2238 <span class="n">accept_result</span> <span class="o">=</span> <span class="p">(</span><span class="n">file_attributes</span> <span class="o">&amp;</span> <span class="n">search</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span>
2239 <span class="k">if</span> <span class="n">accept_result</span><span class="p">:</span>
2240 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedFile</span><span class="p">(</span><span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">create_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_access_time</span><span class="p">),</span>
2241 <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_write_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_attr_change_time</span><span class="p">),</span>
2242 <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">short_name</span><span class="p">,</span> <span class="n">filename</span><span class="p">))</span>
20072243
20082244 <span class="k">if</span> <span class="n">next_offset</span><span class="p">:</span>
20092245 <span class="n">offset</span> <span class="o">+=</span> <span class="n">next_offset</span>
20102246 <span class="k">else</span><span class="p">:</span>
20112247 <span class="k">break</span>
2012 <span class="k">return</span> <span class="s1">&#39;&#39;</span>
2248 <span class="k">return</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
20132249
20142250 <span class="k">def</span> <span class="nf">findFirstCB</span><span class="p">(</span><span class="n">find_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
20152251 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">find_message</span><span class="p">)</span>
20162252 <span class="k">if</span> <span class="ow">not</span> <span class="n">find_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2017 <span class="k">if</span> <span class="ow">not</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="s1">&#39;total_count&#39;</span><span class="p">):</span>
2253 <span class="k">if</span> <span class="s1">&#39;total_count&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
20182254 <span class="c1"># TRANS2_FIND_FIRST2 response. [MS-CIFS]: 2.2.6.2.2</span>
20192255 <span class="n">sid</span><span class="p">,</span> <span class="n">search_count</span><span class="p">,</span> <span class="n">end_of_search</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">last_name_offset</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;HHHHH&#39;</span><span class="p">,</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">params_bytes</span><span class="p">[:</span><span class="mi">10</span><span class="p">])</span>
2020 <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span> <span class="s1">&#39;sid&#39;</span><span class="p">:</span> <span class="n">sid</span><span class="p">,</span> <span class="s1">&#39;end_of_search&#39;</span><span class="p">:</span> <span class="n">end_of_search</span><span class="p">,</span> <span class="s1">&#39;last_name_offset&#39;</span><span class="p">:</span> <span class="n">last_name_offset</span><span class="p">,</span> <span class="s1">&#39;data_buf&#39;</span><span class="p">:</span> <span class="s1">&#39;&#39;</span> <span class="p">})</span>
2256 <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span> <span class="s1">&#39;sid&#39;</span><span class="p">:</span> <span class="n">sid</span><span class="p">,</span> <span class="s1">&#39;end_of_search&#39;</span><span class="p">:</span> <span class="n">end_of_search</span><span class="p">,</span> <span class="s1">&#39;last_name_offset&#39;</span><span class="p">:</span> <span class="n">last_name_offset</span><span class="p">,</span> <span class="s1">&#39;data_buf&#39;</span><span class="p">:</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span> <span class="p">})</span>
20212257 <span class="k">else</span><span class="p">:</span>
20222258 <span class="n">sid</span><span class="p">,</span> <span class="n">end_of_search</span><span class="p">,</span> <span class="n">last_name_offset</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;sid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;end_of_search&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;last_name_offset&#39;</span><span class="p">]</span>
20232259
2024 <span class="n">send_next</span> <span class="o">=</span> <span class="bp">True</span>
2260 <span class="n">send_next</span> <span class="o">=</span> <span class="kc">True</span>
20252261 <span class="k">if</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">:</span>
20262262 <span class="n">d</span> <span class="o">=</span> <span class="n">decodeFindStruct</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_buf&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span>
2027 <span class="k">if</span> <span class="ow">not</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="s1">&#39;data_count&#39;</span><span class="p">):</span>
2263 <span class="k">if</span> <span class="s1">&#39;data_count&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
20282264 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span> <span class="o">!=</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">:</span>
20292265 <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span> <span class="s1">&#39;data_count&#39;</span><span class="p">:</span> <span class="nb">len</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">),</span>
20302266 <span class="s1">&#39;total_count&#39;</span><span class="p">:</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">,</span>
20312267 <span class="s1">&#39;data_buf&#39;</span><span class="p">:</span> <span class="n">d</span><span class="p">,</span>
20322268 <span class="p">})</span>
2033 <span class="n">send_next</span> <span class="o">=</span> <span class="bp">False</span>
2269 <span class="n">send_next</span> <span class="o">=</span> <span class="kc">False</span>
20342270 <span class="k">else</span><span class="p">:</span>
20352271 <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_count&#39;</span><span class="p">]</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span>
20362272 <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;total_count&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;total_count&#39;</span><span class="p">])</span>
20372273 <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_buf&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">d</span>
20382274 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_count&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;total_count&#39;</span><span class="p">]:</span>
2039 <span class="n">send_next</span> <span class="o">=</span> <span class="bp">False</span>
2275 <span class="n">send_next</span> <span class="o">=</span> <span class="kc">False</span>
20402276
20412277 <span class="k">if</span> <span class="ow">not</span> <span class="n">send_next</span><span class="p">:</span>
20422278 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">find_message</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">findFirstCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
20432279 <span class="k">elif</span> <span class="n">end_of_search</span><span class="p">:</span>
20442280 <span class="n">callback</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
20452281 <span class="k">else</span><span class="p">:</span>
2046 <span class="n">sendFindNext</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">sid</span><span class="p">,</span> <span class="n">last_name_offset</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;support_dfs&#39;</span><span class="p">,</span> <span class="bp">False</span><span class="p">))</span>
2047 <span class="k">else</span><span class="p">:</span>
2048 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to retrieve file list&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2049
2050 <span class="k">def</span> <span class="nf">sendFindNext</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">sid</span><span class="p">,</span> <span class="n">resume_key</span><span class="p">,</span> <span class="n">support_dfs</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
2282 <span class="n">sendFindNext</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">sid</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">results</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;support_dfs&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">))</span>
2283 <span class="k">else</span><span class="p">:</span>
2284 <span class="k">if</span> <span class="n">find_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xC000000F</span><span class="p">:</span> <span class="c1"># [MS-ERREF]: STATUS_NO_SUCH_FILE</span>
2285 <span class="c1"># Remote server returns STATUS_NO_SUCH_FILE error so we assume that the search returns no matching files</span>
2286 <span class="n">callback</span><span class="p">([</span> <span class="p">])</span>
2287 <span class="k">else</span><span class="p">:</span>
2288 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to retrieve file list&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2289
2290 <span class="k">def</span> <span class="nf">sendFindNext</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">sid</span><span class="p">,</span> <span class="n">resume_key</span><span class="p">,</span> <span class="n">resume_file</span><span class="p">,</span> <span class="n">support_dfs</span><span class="p">):</span>
20512291 <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;H&#39;</span><span class="p">,</span> <span class="mh">0x0002</span><span class="p">)</span> <span class="c1"># TRANS2_FIND_NEXT2 sub-command. See [MS-CIFS]: 2.2.6.3.1</span>
20522292 <span class="n">params_bytes</span> <span class="o">=</span> \
20532293 <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;HHHIH&#39;</span><span class="p">,</span>
20552295 <span class="mi">100</span><span class="p">,</span> <span class="c1"># SearchCount</span>
20562296 <span class="mh">0x0104</span><span class="p">,</span> <span class="c1"># InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO</span>
20572297 <span class="n">resume_key</span><span class="p">,</span> <span class="c1"># ResumeKey</span>
2058 <span class="mh">0x000a</span><span class="p">)</span> <span class="c1"># Flags: SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS</span>
2059 <span class="k">if</span> <span class="n">support_dfs</span><span class="p">:</span>
2060 <span class="n">params_bytes</span> <span class="o">+=</span> <span class="p">(</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\\</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="n">service_name</span> <span class="o">+</span> <span class="n">path</span> <span class="o">+</span> <span class="n">pattern</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
2061 <span class="k">else</span><span class="p">:</span>
2062 <span class="n">params_bytes</span> <span class="o">+=</span> <span class="p">(</span><span class="n">path</span> <span class="o">+</span> <span class="n">pattern</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
2298 <span class="mh">0x0006</span><span class="p">)</span> <span class="c1"># Flags: SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS</span>
2299 <span class="n">params_bytes</span> <span class="o">+=</span> <span class="p">(</span><span class="n">resume_file</span><span class="o">+</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
20632300
20642301 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTransaction2Request</span><span class="p">(</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span>
20652302 <span class="n">max_data_count</span> <span class="o">=</span> <span class="mi">16644</span><span class="p">,</span>
20762313 <span class="k">def</span> <span class="nf">findNextCB</span><span class="p">(</span><span class="n">find_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
20772314 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">find_message</span><span class="p">)</span>
20782315 <span class="k">if</span> <span class="ow">not</span> <span class="n">find_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2079 <span class="k">if</span> <span class="ow">not</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="s1">&#39;total_count&#39;</span><span class="p">):</span>
2316 <span class="k">if</span> <span class="s1">&#39;total_count&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
20802317 <span class="c1"># TRANS2_FIND_NEXT2 response. [MS-CIFS]: 2.2.6.3.2</span>
20812318 <span class="n">search_count</span><span class="p">,</span> <span class="n">end_of_search</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">last_name_offset</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;HHHH&#39;</span><span class="p">,</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">params_bytes</span><span class="p">[:</span><span class="mi">8</span><span class="p">])</span>
2082 <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span> <span class="s1">&#39;end_of_search&#39;</span><span class="p">:</span> <span class="n">end_of_search</span><span class="p">,</span> <span class="s1">&#39;last_name_offset&#39;</span><span class="p">:</span> <span class="n">last_name_offset</span><span class="p">,</span> <span class="s1">&#39;data_buf&#39;</span><span class="p">:</span> <span class="s1">&#39;&#39;</span> <span class="p">})</span>
2319 <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span> <span class="s1">&#39;end_of_search&#39;</span><span class="p">:</span> <span class="n">end_of_search</span><span class="p">,</span> <span class="s1">&#39;last_name_offset&#39;</span><span class="p">:</span> <span class="n">last_name_offset</span><span class="p">,</span> <span class="s1">&#39;data_buf&#39;</span><span class="p">:</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span> <span class="p">})</span>
20832320 <span class="k">else</span><span class="p">:</span>
20842321 <span class="n">end_of_search</span><span class="p">,</span> <span class="n">last_name_offset</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;end_of_search&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;last_name_offset&#39;</span><span class="p">]</span>
20852322
2086 <span class="n">send_next</span> <span class="o">=</span> <span class="bp">True</span>
2323 <span class="n">send_next</span> <span class="o">=</span> <span class="kc">True</span>
20872324 <span class="k">if</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">:</span>
20882325 <span class="n">d</span> <span class="o">=</span> <span class="n">decodeFindStruct</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_buf&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span>
2089 <span class="k">if</span> <span class="ow">not</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="s1">&#39;data_count&#39;</span><span class="p">):</span>
2326 <span class="k">if</span> <span class="s1">&#39;data_count&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
20902327 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span> <span class="o">!=</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">:</span>
20912328 <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span> <span class="s1">&#39;data_count&#39;</span><span class="p">:</span> <span class="nb">len</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">),</span>
20922329 <span class="s1">&#39;total_count&#39;</span><span class="p">:</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">,</span>
20932330 <span class="s1">&#39;data_buf&#39;</span><span class="p">:</span> <span class="n">d</span><span class="p">,</span>
20942331 <span class="p">})</span>
2095 <span class="n">send_next</span> <span class="o">=</span> <span class="bp">False</span>
2332 <span class="n">send_next</span> <span class="o">=</span> <span class="kc">False</span>
20962333 <span class="k">else</span><span class="p">:</span>
20972334 <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_count&#39;</span><span class="p">]</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span>
20982335 <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;total_count&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;total_count&#39;</span><span class="p">])</span>
20992336 <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_buf&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">d</span>
21002337 <span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;data_count&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;total_count&#39;</span><span class="p">]:</span>
2101 <span class="n">send_next</span> <span class="o">=</span> <span class="bp">False</span>
2338 <span class="n">send_next</span> <span class="o">=</span> <span class="kc">False</span>
21022339
21032340 <span class="k">if</span> <span class="ow">not</span> <span class="n">send_next</span><span class="p">:</span>
21042341 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">find_message</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">findNextCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
21052342 <span class="k">elif</span> <span class="n">end_of_search</span><span class="p">:</span>
21062343 <span class="n">callback</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
21072344 <span class="k">else</span><span class="p">:</span>
2108 <span class="n">sendFindNext</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;sid&#39;</span><span class="p">],</span> <span class="n">last_name_offset</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;support_dfs&#39;</span><span class="p">,</span> <span class="bp">False</span><span class="p">))</span>
2345 <span class="n">sendFindNext</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;sid&#39;</span><span class="p">],</span> <span class="mi">0</span><span class="p">,</span> <span class="n">results</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;support_dfs&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">))</span>
21092346 <span class="k">else</span><span class="p">:</span>
21102347 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to retrieve file list&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
21112348
21252362 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
21262363
21272364 <span class="k">def</span> <span class="nf">dfsReferralCB</span><span class="p">(</span><span class="n">dfs_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
2128 <span class="n">sendFindFirst</span><span class="p">(</span><span class="n">dfs_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>
2129
2130 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
2365 <span class="n">sendFindFirst</span><span class="p">(</span><span class="n">dfs_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
2366
2367 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
21312368 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
21322369 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
21332370 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
21352372 <span class="k">if</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">optional_support</span> <span class="o">&amp;</span> <span class="n">SMB_TREE_CONNECTX_SUPPORT_DFS</span><span class="p">:</span>
21362373 <span class="n">sendDFSReferral</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span>
21372374 <span class="k">else</span><span class="p">:</span>
2138 <span class="n">sendFindFirst</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="bp">False</span><span class="p">)</span>
2375 <span class="n">sendFindFirst</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
21392376 <span class="k">else</span><span class="p">:</span>
21402377 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
21412378
2142 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2379 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
21432380 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
21442381 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
21452382 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
21832420 <span class="n">info_size</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">info_format</span><span class="p">)</span>
21842421 <span class="n">create_time</span><span class="p">,</span> <span class="n">last_access_time</span><span class="p">,</span> <span class="n">last_write_time</span><span class="p">,</span> <span class="n">last_attr_change_time</span><span class="p">,</span> \
21852422 <span class="n">file_attributes</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_size</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="n">info_format</span><span class="p">,</span> <span class="n">query_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">[:</span><span class="n">info_size</span><span class="p">])</span>
2186
2187 <span class="n">info</span> <span class="o">=</span> <span class="n">SharedFile</span><span class="p">(</span><span class="n">create_time</span><span class="p">,</span> <span class="n">last_access_time</span><span class="p">,</span> <span class="n">last_write_time</span><span class="p">,</span> <span class="n">last_attr_change_time</span><span class="p">,</span>
2188 <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">path</span><span class="p">),</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
2423 <span class="n">filename</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_extractLastPathComponent</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
2424
2425 <span class="n">info</span> <span class="o">=</span> <span class="n">SharedFile</span><span class="p">(</span><span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">create_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_access_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_write_time</span><span class="p">),</span> <span class="n">convertFILETIMEtoEpoch</span><span class="p">(</span><span class="n">last_attr_change_time</span><span class="p">),</span>
2426 <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
21892427 <span class="n">callback</span><span class="p">(</span><span class="n">info</span><span class="p">)</span>
21902428 <span class="k">else</span><span class="p">:</span>
21912429 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to get attributes for </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Read failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
21922430
2193 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
2431 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
21942432 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
21952433 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
21962434 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
21992437 <span class="k">else</span><span class="p">:</span>
22002438 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to get attributes for </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
22012439
2202 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2440 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
22032441 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
22042442 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
22052443 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
22062444 <span class="k">else</span><span class="p">:</span>
22072445 <span class="n">sendQuery</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
22082446
2447 <span class="k">def</span> <span class="nf">_getSecurity_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2448 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;getSecurity is not yet implemented for SMB1&#39;</span><span class="p">)</span>
2449
22092450 <span class="k">def</span> <span class="nf">_retrieveFile_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2210 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="il">0L</span><span class="p">,</span> <span class="o">-</span><span class="il">1L</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
2451 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFileFromOffset</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
22112452
22122453 <span class="k">def</span> <span class="nf">_retrieveFileFromOffset_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">max_length</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
22132454 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
22322473 <span class="k">if</span> <span class="ow">not</span> <span class="n">open_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
22332474 <span class="k">if</span> <span class="n">max_length</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
22342475 <span class="n">closeFid</span><span class="p">(</span><span class="n">open_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span>
2235 <span class="n">callback</span><span class="p">((</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">,</span> <span class="il">0L</span> <span class="p">))</span>
2236 <span class="k">else</span><span class="p">:</span>
2237 <span class="n">sendRead</span><span class="p">(</span><span class="n">open_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">,</span> <span class="il">0L</span><span class="p">,</span> <span class="n">max_length</span><span class="p">)</span>
2476 <span class="n">callback</span><span class="p">((</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">,</span> <span class="mi">0</span> <span class="p">))</span>
2477 <span class="k">else</span><span class="p">:</span>
2478 <span class="n">sendRead</span><span class="p">(</span><span class="n">open_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">max_length</span><span class="p">)</span>
22382479 <span class="k">else</span><span class="p">:</span>
22392480 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to retrieve </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open file&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
22402481
22842525 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
22852526 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
22862527
2287 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
2528 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
22882529 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
22892530 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
22902531 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
22932534 <span class="k">else</span><span class="p">:</span>
22942535 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to retrieve </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
22952536
2296 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2537 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
22972538 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
22982539 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
22992540 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
23012542 <span class="n">sendOpen</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
23022543
23032544 <span class="k">def</span> <span class="nf">_storeFile_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2304 <span class="bp">self</span><span class="o">.</span><span class="n">_storeFileFromOffset_SMB1</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="il">0L</span><span class="p">,</span> <span class="bp">True</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
2305
2306 <span class="k">def</span> <span class="nf">_storeFileFromOffset_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">truncate</span> <span class="o">=</span> <span class="bp">False</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2545 <span class="bp">self</span><span class="o">.</span><span class="n">_storeFileFromOffset_SMB1</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="kc">True</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
2546
2547 <span class="k">def</span> <span class="nf">_storeFileFromOffset_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">starting_offset</span><span class="p">,</span> <span class="n">truncate</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
23072548 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
23082549 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
23092550
23292570 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to store </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to open file&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
23302571
23312572 <span class="k">def</span> <span class="nf">sendWrite</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span><span class="p">):</span>
2332 <span class="c1"># For message signing, the total SMB message size must be not exceed the max_buffer_size. Non-message signing does not have this limitation</span>
2333 <span class="n">write_count</span> <span class="o">=</span> <span class="nb">min</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">is_signing_active</span> <span class="ow">and</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_buffer_size</span><span class="o">-</span><span class="mi">64</span><span class="p">))</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_raw_size</span><span class="p">,</span> <span class="mh">0xFFFF</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># Need to minus 1 byte from 0xFFFF because of the first NULL byte in the ComWriteAndxRequest message data</span>
2573 <span class="c1"># [MS-SMB] 2.2.4.5.2.2: The total SMB message size (inclusive of SMB header) must be not exceed the max_buffer_size.</span>
2574 <span class="n">write_count</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_buffer_size</span><span class="o">-</span><span class="mi">64</span><span class="p">,</span> <span class="mh">0xFFFF</span><span class="o">-</span><span class="mi">64</span><span class="p">)</span> <span class="c1"># SMB header is 32-bytes. We factor in another 32-bytes for the message parameter block</span>
23342575 <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">file_obj</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">write_count</span><span class="p">)</span>
23352576 <span class="n">data_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">)</span>
23362577 <span class="k">if</span> <span class="n">data_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
23572598 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
23582599 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
23592600
2360 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
2601 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
23612602 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
23622603 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
23632604 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
23662607 <span class="k">else</span><span class="p">:</span>
23672608 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to store </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
23682609
2369 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2610 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
23702611 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
23712612 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
23722613 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
23732614 <span class="k">else</span><span class="p">:</span>
23742615 <span class="n">sendOpen</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
23752616
2376 <span class="k">def</span> <span class="nf">_deleteFiles_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2617 <span class="k">def</span> <span class="nf">_deleteFiles_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
23772618 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
23782619 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
23792620
2621 <span class="n">expiry_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">timeout</span>
2622 <span class="n">pattern</span> <span class="o">=</span> <span class="kc">None</span>
23802623 <span class="n">path</span> <span class="o">=</span> <span class="n">path_file_pattern</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
2624 <span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">):</span>
2625 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
2626 <span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">):</span>
2627 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
2628 <span class="k">else</span><span class="p">:</span>
2629 <span class="n">path_components</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
2630 <span class="k">if</span> <span class="n">path_components</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1</span> <span class="ow">or</span> <span class="n">path_components</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;?&#39;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
2631 <span class="n">path</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path_components</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
2632 <span class="n">pattern</span> <span class="o">=</span> <span class="n">path_components</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
2633 <span class="n">messages_history</span><span class="p">,</span> <span class="n">files_queue</span> <span class="o">=</span> <span class="p">[</span> <span class="p">],</span> <span class="p">[</span> <span class="p">]</span>
2634
2635 <span class="k">if</span> <span class="n">pattern</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
2636 <span class="n">path_components</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
2637 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">path_components</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
2638 <span class="n">files_queue</span><span class="o">.</span><span class="n">append</span><span class="p">((</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path_components</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="n">path_components</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="p">))</span>
2639 <span class="k">else</span><span class="p">:</span>
2640 <span class="n">files_queue</span><span class="o">.</span><span class="n">append</span><span class="p">((</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">path</span> <span class="p">))</span>
2641
2642 <span class="k">def</span> <span class="nf">deleteCB</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
2643 <span class="k">if</span> <span class="n">files_queue</span><span class="p">:</span>
2644 <span class="n">p</span><span class="p">,</span> <span class="n">filename</span> <span class="o">=</span> <span class="n">files_queue</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
2645 <span class="k">if</span> <span class="n">filename</span><span class="p">:</span>
2646 <span class="k">if</span> <span class="n">p</span><span class="p">:</span>
2647 <span class="n">filename</span> <span class="o">=</span> <span class="n">p</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="n">filename</span>
2648 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteFiles_SMB1__del</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">],</span> <span class="n">filename</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
2649 <span class="k">else</span><span class="p">:</span>
2650 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteDirectory_SMB1</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">)</span>
2651 <span class="k">else</span><span class="p">:</span>
2652 <span class="n">callback</span><span class="p">(</span><span class="n">path_file_pattern</span><span class="p">)</span>
2653
2654 <span class="k">def</span> <span class="nf">listCB</span><span class="p">(</span><span class="n">files_list</span><span class="p">):</span>
2655 <span class="n">files_queue</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">files_list</span><span class="p">)</span>
2656 <span class="n">deleteCB</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
2657
2658 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
2659 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
2660 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
2661 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2662 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span>
2663 <span class="k">if</span> <span class="n">files_queue</span><span class="p">:</span>
2664 <span class="n">deleteCB</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
2665 <span class="k">else</span><span class="p">:</span>
2666 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteFiles_SMB1__list</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">listCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
2667 <span class="k">else</span><span class="p">:</span>
2668 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2669
2670 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2671 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2672 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
2673 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2674 <span class="k">else</span><span class="p">:</span>
2675 <span class="k">if</span> <span class="n">files_queue</span><span class="p">:</span>
2676 <span class="n">deleteCB</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
2677 <span class="k">else</span><span class="p">:</span>
2678 <span class="bp">self</span><span class="o">.</span><span class="n">_deleteFiles_SMB1__list</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">listCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
2679
2680 <span class="k">def</span> <span class="nf">_deleteFiles_SMB1__list</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">delete_matching_folders</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2681 <span class="n">folder_queue</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
2682 <span class="n">files_list</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
2683 <span class="n">current_path</span> <span class="o">=</span> <span class="p">[</span> <span class="n">path</span> <span class="p">]</span>
2684 <span class="n">search</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_READONLY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_DIRECTORY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_ARCHIVE</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_INCL_NORMAL</span>
2685
2686 <span class="k">def</span> <span class="nf">listCB</span><span class="p">(</span><span class="n">results</span><span class="p">):</span>
2687 <span class="n">files</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
2688 <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">filename</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span> <span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="s1">&#39;..&#39;</span> <span class="p">],</span> <span class="n">results</span><span class="p">):</span>
2689 <span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">isDirectory</span><span class="p">:</span>
2690 <span class="k">if</span> <span class="n">delete_matching_folders</span><span class="p">:</span>
2691 <span class="n">folder_queue</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">+</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="o">+</span><span class="n">f</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span>
2692 <span class="k">else</span><span class="p">:</span>
2693 <span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">((</span> <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="o">.</span><span class="n">filename</span> <span class="p">))</span>
2694 <span class="k">if</span> <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">!=</span><span class="n">path</span> <span class="ow">and</span> <span class="n">delete_matching_folders</span><span class="p">:</span>
2695 <span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">((</span> <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="kc">None</span> <span class="p">))</span>
2696
2697 <span class="k">if</span> <span class="n">files</span><span class="p">:</span>
2698 <span class="n">files_list</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">files</span>
2699
2700 <span class="k">if</span> <span class="n">folder_queue</span><span class="p">:</span>
2701 <span class="n">p</span> <span class="o">=</span> <span class="n">folder_queue</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
2702 <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">p</span>
2703 <span class="bp">self</span><span class="o">.</span><span class="n">_listPath_SMB1</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">current_path</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">listCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">search</span> <span class="o">=</span> <span class="n">search</span><span class="p">,</span> <span class="n">pattern</span> <span class="o">=</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">)</span>
2704 <span class="k">else</span><span class="p">:</span>
2705 <span class="n">callback</span><span class="p">(</span><span class="n">files_list</span><span class="p">)</span>
2706
2707 <span class="bp">self</span><span class="o">.</span><span class="n">_listPath_SMB1</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">listCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">search</span> <span class="o">=</span> <span class="n">search</span><span class="p">,</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span>
2708
2709 <span class="k">def</span> <span class="nf">_deleteFiles_SMB1__del</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">tid</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
23812710 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
23822711
23832712 <span class="k">def</span> <span class="nf">sendDelete</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
23912720 <span class="k">def</span> <span class="nf">deleteCB</span><span class="p">(</span><span class="n">delete_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
23922721 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">delete_message</span><span class="p">)</span>
23932722 <span class="k">if</span> <span class="ow">not</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2723 <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
2724 <span class="k">elif</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xC000000F</span><span class="p">:</span> <span class="c1"># [MS-ERREF]: STATUS_NO_SUCH_FILE</span>
2725 <span class="c1"># If there are no matching files, we just treat as success instead of failing</span>
23942726 <span class="n">callback</span><span class="p">(</span><span class="n">path_file_pattern</span><span class="p">)</span>
2395 <span class="k">else</span><span class="p">:</span>
2396 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to store </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Delete failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2397
2398 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
2727 <span class="k">elif</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xC00000BA</span><span class="p">:</span> <span class="c1"># [MS-ERREF]: STATUS_FILE_IS_A_DIRECTORY</span>
2728 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Cannot delete a folder. Please use deleteDirectory() method or append &quot;/*&quot; to your path if you wish to delete all files in the folder.&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2729 <span class="k">elif</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xC0000034</span><span class="p">:</span> <span class="c1"># [MS-ERREF]: STATUS_OBJECT_NAME_INVALID</span>
2730 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Path not found&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2731 <span class="k">else</span><span class="p">:</span>
2732 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Delete failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2733
2734 <span class="n">sendDelete</span><span class="p">(</span><span class="n">tid</span><span class="p">)</span>
2735
2736 <span class="k">def</span> <span class="nf">_resetFileAttributes_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">file_attributes</span><span class="o">=</span><span class="n">ATTR_NORMAL</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2737 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;resetFileAttributes is not yet implemented for SMB1&#39;</span><span class="p">)</span>
2738
2739 <span class="k">def</span> <span class="nf">_createDirectory_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2740 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
2741 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
2742
2743 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
2744 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
2745
2746 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
2747 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComCreateDirectoryRequest</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
2748 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
2749 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2750 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
2751 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2752
2753 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
2754 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span>
2755 <span class="k">if</span> <span class="ow">not</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2756 <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
2757 <span class="k">else</span><span class="p">:</span>
2758 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to create directory </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Create failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2759
2760 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
2761 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
2762 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
2763 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2764 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span>
2765 <span class="n">sendCreate</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span>
2766 <span class="k">else</span><span class="p">:</span>
2767 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to create directory </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2768
2769 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2770 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2771 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
2772 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2773 <span class="k">else</span><span class="p">:</span>
2774 <span class="n">sendCreate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
2775
2776 <span class="k">def</span> <span class="nf">_deleteDirectory_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2777 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
2778 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
2779
2780 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
2781 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
2782
2783 <span class="k">def</span> <span class="nf">sendDelete</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
2784 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComDeleteDirectoryRequest</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
2785 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
2786 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2787 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
2788 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2789
2790 <span class="k">def</span> <span class="nf">deleteCB</span><span class="p">(</span><span class="n">delete_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
2791 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">delete_message</span><span class="p">)</span>
2792 <span class="k">if</span> <span class="ow">not</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2793 <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
2794 <span class="k">else</span><span class="p">:</span>
2795 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete directory </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Delete failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2796
2797 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
23992798 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
24002799 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
24012800 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
24022801 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span>
24032802 <span class="n">sendDelete</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span>
24042803 <span class="k">else</span><span class="p">:</span>
2405 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2406
2407 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2408 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2409 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
2410 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2411 <span class="k">else</span><span class="p">:</span>
2412 <span class="n">sendDelete</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
2413
2414 <span class="k">def</span> <span class="nf">_resetFileAttributes_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2415 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;resetFileAttributes is not yet implemented for SMB1&#39;</span><span class="p">)</span>
2416
2417 <span class="k">def</span> <span class="nf">_createDirectory_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2418 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
2419 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
2420
2421 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
2422 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
2423
2424 <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
2425 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComCreateDirectoryRequest</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
2426 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
2427 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2428 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
2429 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2430
2431 <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
2432 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span>
2433 <span class="k">if</span> <span class="ow">not</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2434 <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
2435 <span class="k">else</span><span class="p">:</span>
2436 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to create directory </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Create failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2437
2438 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
2439 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
2440 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
2441 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2442 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span>
2443 <span class="n">sendCreate</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span>
2444 <span class="k">else</span><span class="p">:</span>
2445 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to create directory </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2446
2447 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2448 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2449 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
2450 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2451 <span class="k">else</span><span class="p">:</span>
2452 <span class="n">sendCreate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span>
2453
2454 <span class="k">def</span> <span class="nf">_deleteDirectory_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
2455 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span>
2456 <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s1">&#39;SMB connection not authenticated&#39;</span><span class="p">)</span>
2457
2458 <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span>
2459 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
2460
2461 <span class="k">def</span> <span class="nf">sendDelete</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span>
2462 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComDeleteDirectoryRequest</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
2463 <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span>
2464 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2465 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
2466 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
2467
2468 <span class="k">def</span> <span class="nf">deleteCB</span><span class="p">(</span><span class="n">delete_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
2469 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">delete_message</span><span class="p">)</span>
2470 <span class="k">if</span> <span class="ow">not</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2471 <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
2472 <span class="k">else</span><span class="p">:</span>
2473 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete directory </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Delete failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2474
2475 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
2476 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
2477 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
2478 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
2479 <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span>
2480 <span class="n">sendDelete</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span>
2481 <span class="k">else</span><span class="p">:</span>
2482 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2483
2484 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2804 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to delete directory </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
2805
2806 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
24852807 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
24862808 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
24872809 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
25122834 <span class="k">else</span><span class="p">:</span>
25132835 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to rename </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Rename failed&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
25142836
2515 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
2837 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
25162838 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
25172839 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
25182840 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
25212843 <span class="k">else</span><span class="p">:</span>
25222844 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to rename </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
25232845
2524 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2846 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
25252847 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
25262848 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
25272849 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
25812903 <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
25822904 <span class="n">snapshots_count</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">enum_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">[</span><span class="mi">4</span><span class="p">:</span><span class="mi">8</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span>
25832905 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">snapshots_count</span><span class="p">):</span>
2584 <span class="n">s</span> <span class="o">=</span> <span class="n">enum_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">[</span><span class="mi">12</span><span class="o">+</span><span class="n">i</span><span class="o">*</span><span class="mi">50</span><span class="p">:</span><span class="mi">12</span><span class="o">+</span><span class="mi">48</span><span class="o">+</span><span class="n">i</span><span class="o">*</span><span class="mi">50</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
2585 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">datetime</span><span class="p">(</span><span class="o">*</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="p">(</span> <span class="n">s</span><span class="p">[</span><span class="mi">5</span><span class="p">:</span><span class="mi">9</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">10</span><span class="p">:</span><span class="mi">12</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">13</span><span class="p">:</span><span class="mi">15</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">16</span><span class="p">:</span><span class="mi">18</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">19</span><span class="p">:</span><span class="mi">21</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">24</span><span class="p">]</span> <span class="p">))))</span>
2906 <span class="n">s</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">enum_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">[</span><span class="mi">12</span><span class="o">+</span><span class="n">i</span><span class="o">*</span><span class="mi">50</span><span class="p">:</span><span class="mi">12</span><span class="o">+</span><span class="mi">48</span><span class="o">+</span><span class="n">i</span><span class="o">*</span><span class="mi">50</span><span class="p">])</span>
2907 <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">datetime</span><span class="p">(</span><span class="o">*</span><span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="p">(</span> <span class="n">s</span><span class="p">[</span><span class="mi">5</span><span class="p">:</span><span class="mi">9</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">10</span><span class="p">:</span><span class="mi">12</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">13</span><span class="p">:</span><span class="mi">15</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">16</span><span class="p">:</span><span class="mi">18</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">19</span><span class="p">:</span><span class="mi">21</span><span class="p">],</span> <span class="n">s</span><span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">24</span><span class="p">]</span> <span class="p">)))))</span>
25862908 <span class="n">closeFid</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;tid&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">&#39;fid&#39;</span><span class="p">])</span>
25872909 <span class="n">callback</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
25882910 <span class="k">else</span><span class="p">:</span>
25952917 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
25962918 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
25972919
2598 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span>
2920 <span class="k">if</span> <span class="n">service_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">:</span>
25992921 <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
26002922 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span>
26012923 <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span>
26042926 <span class="k">else</span><span class="p">:</span>
26052927 <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s1">&#39;Failed to list snapshots </span><span class="si">%s</span><span class="s1"> on </span><span class="si">%s</span><span class="s1">: Unable to connect to shared device&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span>
26062928
2607 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s1">r&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
2929 <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;</span><span class="se">\\</span><span class="si">%s</span><span class="s1">\</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
26082930 <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
26092931 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span>
26102932 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
26132935
26142936 <span class="k">def</span> <span class="nf">_echo_SMB1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span>
26152937 <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
2938
2939 <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)):</span>
2940 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Echo data must be </span><span class="si">%s</span><span class="s1"> not </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">data</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
26162941
26172942 <span class="k">def</span> <span class="nf">echoCB</span><span class="p">(</span><span class="n">echo_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
26182943 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">echo_message</span><span class="p">)</span>
26262951 <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">echoCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span>
26272952 <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
26282953
2954 <span class="k">def</span> <span class="nf">_extractLastPathComponent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
2955 <span class="k">return</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
2956
26292957
26302958 <div class="viewcode-block" id="SharedDevice"><a class="viewcode-back" href="../../api/smb_SharedDevice.html#smb.base.SharedDevice">[docs]</a><span class="k">class</span> <span class="nc">SharedDevice</span><span class="p">:</span>
26312959 <span class="sd">&quot;&quot;&quot;</span>
26322960 <span class="sd"> Contains information about a single shared device on the remote server.</span>
2961
2962 <span class="sd"> The following attributes are available:</span>
2963
2964 <span class="sd"> * name : An unicode string containing the name of the shared device</span>
2965 <span class="sd"> * comments : An unicode string containing the user description of the shared device</span>
26332966 <span class="sd"> &quot;&quot;&quot;</span>
26342967
26352968 <span class="c1"># The following constants are taken from [MS-SRVS]: 2.2.2.4</span>
26392972 <span class="n">COMM_DEVICE</span> <span class="o">=</span> <span class="mh">0x02</span>
26402973 <span class="n">IPC</span> <span class="o">=</span> <span class="mh">0x03</span>
26412974
2642 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">comments</span><span class="p">):</span>
2975 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">comments</span><span class="p">):</span>
26432976 <span class="bp">self</span><span class="o">.</span><span class="n">_type</span> <span class="o">=</span> <span class="nb">type</span>
26442977 <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span> <span class="c1">#: An unicode string containing the name of the shared device</span>
26452978 <span class="bp">self</span><span class="o">.</span><span class="n">comments</span> <span class="o">=</span> <span class="n">comments</span> <span class="c1">#: An unicode string containing the user description of the shared device</span>
26723005 <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_type</span> <span class="o">&amp;</span> <span class="mh">0x40000000</span><span class="p">)</span>
26733006
26743007 <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
2675 <span class="k">return</span> <span class="s1">u&#39;Shared device: </span><span class="si">%s</span><span class="s1"> (type:0x</span><span class="si">%02x</span><span class="s1"> comments:</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">comments</span> <span class="p">)</span></div>
3008 <span class="k">return</span> <span class="s1">&#39;Shared device: </span><span class="si">%s</span><span class="s1"> (type:0x</span><span class="si">%02x</span><span class="s1"> comments:</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">comments</span> <span class="p">)</span></div>
26763009
26773010
26783011 <div class="viewcode-block" id="SharedFile"><a class="viewcode-back" href="../../api/smb_SharedFile.html#smb.base.SharedFile">[docs]</a><span class="k">class</span> <span class="nc">SharedFile</span><span class="p">:</span>
26843017
26853018 <span class="sd"> If you encounter *SharedFile* instance where its short_name attribute is empty but the filename attribute contains a short name which does not correspond</span>
26863019 <span class="sd"> to any files/folders on your remote shared device, it could be that the original filename on the file/folder entry on the shared device contains</span>
2687 <span class="sd"> one of these prohibited characters: &quot;\/[]:+|&lt;&gt;=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).</span>
3020 <span class="sd"> one of these prohibited characters: &quot;\\/[]:+|&lt;&gt;=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).</span>
3021
3022 <span class="sd"> The following attributes are available:</span>
3023
3024 <span class="sd"> * create_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server</span>
3025 <span class="sd"> * last_access_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server</span>
3026 <span class="sd"> * last_write_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server</span>
3027 <span class="sd"> * last_attr_change_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server</span>
3028 <span class="sd"> * file_size : File size in number of bytes</span>
3029 <span class="sd"> * alloc_size : Total number of bytes allocated to store this file</span>
3030 <span class="sd"> * file_attributes : A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3. You can perform bit-wise tests to determine the status of the file using the ATTR_xxx constants in smb_constants.py.</span>
3031 <span class="sd"> * short_name : Unicode string containing the short name of this file (usually in 8.3 notation)</span>
3032 <span class="sd"> * filename : Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.</span>
3033 <span class="sd"> * file_id : Long value representing the file reference number for the file. If the remote system does not support this field, this field will be None or 0. See [MS-FSCC]: 2.4.17</span>
26883034 <span class="sd"> &quot;&quot;&quot;</span>
26893035
2690 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">create_time</span><span class="p">,</span> <span class="n">last_access_time</span><span class="p">,</span> <span class="n">last_write_time</span><span class="p">,</span> <span class="n">last_attr_change_time</span><span class="p">,</span> <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">short_name</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
3036 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">create_time</span><span class="p">,</span> <span class="n">last_access_time</span><span class="p">,</span> <span class="n">last_write_time</span><span class="p">,</span> <span class="n">last_attr_change_time</span><span class="p">,</span> <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">short_name</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">file_id</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
26913037 <span class="bp">self</span><span class="o">.</span><span class="n">create_time</span> <span class="o">=</span> <span class="n">create_time</span> <span class="c1">#: Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server</span>
26923038 <span class="bp">self</span><span class="o">.</span><span class="n">last_access_time</span> <span class="o">=</span> <span class="n">last_access_time</span> <span class="c1">#: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server</span>
26933039 <span class="bp">self</span><span class="o">.</span><span class="n">last_write_time</span> <span class="o">=</span> <span class="n">last_write_time</span> <span class="c1">#: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server</span>
26943040 <span class="bp">self</span><span class="o">.</span><span class="n">last_attr_change_time</span> <span class="o">=</span> <span class="n">last_attr_change_time</span> <span class="c1">#: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server</span>
26953041 <span class="bp">self</span><span class="o">.</span><span class="n">file_size</span> <span class="o">=</span> <span class="n">file_size</span> <span class="c1">#: File size in number of bytes</span>
26963042 <span class="bp">self</span><span class="o">.</span><span class="n">alloc_size</span> <span class="o">=</span> <span class="n">alloc_size</span> <span class="c1">#: Total number of bytes allocated to store this file</span>
2697 <span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span> <span class="o">=</span> <span class="n">file_attributes</span> <span class="c1">#: A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3</span>
3043 <span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span> <span class="o">=</span> <span class="n">file_attributes</span> <span class="c1">#: A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3. You can perform bit-wise tests to determine the status of the file using the ATTR_xxx constants in smb_constants.py.</span>
26983044 <span class="bp">self</span><span class="o">.</span><span class="n">short_name</span> <span class="o">=</span> <span class="n">short_name</span> <span class="c1">#: Unicode string containing the short name of this file (usually in 8.3 notation)</span>
26993045 <span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span> <span class="c1">#: Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.</span>
3046 <span class="bp">self</span><span class="o">.</span><span class="n">file_id</span> <span class="o">=</span> <span class="n">file_id</span> <span class="c1">#: Long value representing the file reference number for the file. If the remote system does not support this field, this field will be None or 0. See [MS-FSCC]: 2.4.17</span>
27003047
27013048 <span class="nd">@property</span>
27023049 <span class="k">def</span> <span class="nf">isDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
2703 <span class="sd">&quot;&quot;&quot;A convenient property to return True if this file resource is a directory on the remote server&quot;&quot;&quot;</span>
3050 <span class="sd">&quot;&quot;&quot;A convenience property to return True if this file resource is a directory on the remote server&quot;&quot;&quot;</span>
27043051 <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span> <span class="o">&amp;</span> <span class="n">ATTR_DIRECTORY</span><span class="p">)</span>
27053052
27063053 <span class="nd">@property</span>
27083055 <span class="sd">&quot;&quot;&quot;A convenient property to return True if this file resource is read-only on the remote server&quot;&quot;&quot;</span>
27093056 <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span> <span class="o">&amp;</span> <span class="n">ATTR_READONLY</span><span class="p">)</span>
27103057
3058 <span class="nd">@property</span>
3059 <span class="k">def</span> <span class="nf">isNormal</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
3060 <span class="sd">&quot;&quot;&quot;</span>
3061 <span class="sd"> A convenient property to return True if this is a normal file.</span>
3062
3063 <span class="sd"> Note that pysmb defines a normal file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.</span>
3064 <span class="sd"> It ignores other attributes like compression, indexed, sparse, temporary and encryption.</span>
3065 <span class="sd"> &quot;&quot;&quot;</span>
3066 <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span><span class="o">==</span><span class="n">ATTR_NORMAL</span><span class="p">)</span> <span class="ow">or</span> <span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">)</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span>
3067
27113068 <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
2712 <span class="k">return</span> <span class="s1">u&#39;Shared file: </span><span class="si">%s</span><span class="s1"> (FileSize:</span><span class="si">%d</span><span class="s1"> bytes, isDirectory:</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">file_size</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">isDirectory</span> <span class="p">)</span></div>
3069 <span class="k">return</span> <span class="s1">&#39;Shared file: </span><span class="si">%s</span><span class="s1"> (FileSize:</span><span class="si">%d</span><span class="s1"> bytes, isDirectory:</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">file_size</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">isDirectory</span> <span class="p">)</span></div>
27133070
27143071
27153072 <span class="k">class</span> <span class="nc">_PendingRequest</span><span class="p">:</span>
27163073
2717 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
3074 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
27183075 <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="n">mid</span>
27193076 <span class="bp">self</span><span class="o">.</span><span class="n">expiry_time</span> <span class="o">=</span> <span class="n">expiry_time</span>
27203077 <span class="bp">self</span><span class="o">.</span><span class="n">callback</span> <span class="o">=</span> <span class="n">callback</span>
27223079 <span class="bp">self</span><span class="o">.</span><span class="n">kwargs</span> <span class="o">=</span> <span class="n">kwargs</span>
27233080 </pre></div>
27243081
3082 <div class="clearer"></div>
27253083 </div>
3084 </div>
3085 </div>
3086 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
3087 <div class="sphinxsidebarwrapper">
3088 <div id="searchbox" style="display: none" role="search">
3089 <h3 id="searchlabel">Quick search</h3>
3090 <div class="searchformwrapper">
3091 <form class="search" action="../../search.html" method="get">
3092 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
3093 <input type="submit" value="Go" />
3094 </form>
3095 </div>
3096 </div>
3097 <script>document.getElementById('searchbox').style.display = "block"</script>
27263098 </div>
27273099 </div>
27283100 <div class="clearer"></div>
27333105 <li class="right" style="margin-right: 10px">
27343106 <a href="../../genindex.html" title="General Index"
27353107 >index</a></li>
2736 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
2737 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &raquo;</li>
3108 <li class="right" >
3109 <a href="../../py-modindex.html" title="Python Module Index"
3110 >modules</a> |</li>
3111 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
3112 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &#187;</li>
3113 <li class="nav-item nav-item-this"><a href="">smb.base</a></li>
27383114 </ul>
27393115 </div>
27403116 <div class="footer" role="contentinfo">
2741 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
2742 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
3117 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
3118 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
27433119 </div>
27443120 </body>
27453121 </html>
0
1 <!DOCTYPE html>
2
3 <html>
4 <head>
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>smb.security_descriptors &#8212; pysmb 1.2.7 documentation</title>
8 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
9 <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
10 <script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
11 <script src="../../_static/jquery.js"></script>
12 <script src="../../_static/underscore.js"></script>
13 <script src="../../_static/doctools.js"></script>
14 <link rel="index" title="Index" href="../../genindex.html" />
15 <link rel="search" title="Search" href="../../search.html" />
16 </head><body>
17 <div class="related" role="navigation" aria-label="related navigation">
18 <h3>Navigation</h3>
19 <ul>
20 <li class="right" style="margin-right: 10px">
21 <a href="../../genindex.html" title="General Index"
22 accesskey="I">index</a></li>
23 <li class="right" >
24 <a href="../../py-modindex.html" title="Python Module Index"
25 >modules</a> |</li>
26 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.7 documentation</a> &#187;</li>
27 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &#187;</li>
28 <li class="nav-item nav-item-this"><a href="">smb.security_descriptors</a></li>
29 </ul>
30 </div>
31
32 <div class="document">
33 <div class="documentwrapper">
34 <div class="bodywrapper">
35 <div class="body" role="main">
36
37 <h1>Source code for smb.security_descriptors</h1><div class="highlight"><pre>
38 <span></span><span class="sd">&quot;&quot;&quot;</span>
39 <span class="sd">This module implements security descriptors, and the partial structures</span>
40 <span class="sd">used in them, as specified in [MS-DTYP].</span>
41 <span class="sd">&quot;&quot;&quot;</span>
42
43 <span class="kn">import</span> <span class="nn">struct</span>
44
45
46 <span class="c1"># Security descriptor control flags</span>
47 <span class="c1"># [MS-DTYP]: 2.4.6</span>
48 <span class="n">SECURITY_DESCRIPTOR_OWNER_DEFAULTED</span> <span class="o">=</span> <span class="mh">0x0001</span>
49 <span class="n">SECURITY_DESCRIPTOR_GROUP_DEFAULTED</span> <span class="o">=</span> <span class="mh">0x0002</span>
50 <span class="n">SECURITY_DESCRIPTOR_DACL_PRESENT</span> <span class="o">=</span> <span class="mh">0x0004</span>
51 <span class="n">SECURITY_DESCRIPTOR_DACL_DEFAULTED</span> <span class="o">=</span> <span class="mh">0x0008</span>
52 <span class="n">SECURITY_DESCRIPTOR_SACL_PRESENT</span> <span class="o">=</span> <span class="mh">0x0010</span>
53 <span class="n">SECURITY_DESCRIPTOR_SACL_DEFAULTED</span> <span class="o">=</span> <span class="mh">0x0020</span>
54 <span class="n">SECURITY_DESCRIPTOR_SERVER_SECURITY</span> <span class="o">=</span> <span class="mh">0x0040</span>
55 <span class="n">SECURITY_DESCRIPTOR_DACL_TRUSTED</span> <span class="o">=</span> <span class="mh">0x0080</span>
56 <span class="n">SECURITY_DESCRIPTOR_DACL_COMPUTED_INHERITANCE_REQUIRED</span> <span class="o">=</span> <span class="mh">0x0100</span>
57 <span class="n">SECURITY_DESCRIPTOR_SACL_COMPUTED_INHERITANCE_REQUIRED</span> <span class="o">=</span> <span class="mh">0x0200</span>
58 <span class="n">SECURITY_DESCRIPTOR_DACL_AUTO_INHERITED</span> <span class="o">=</span> <span class="mh">0x0400</span>
59 <span class="n">SECURITY_DESCRIPTOR_SACL_AUTO_INHERITED</span> <span class="o">=</span> <span class="mh">0x0800</span>
60 <span class="n">SECURITY_DESCRIPTOR_DACL_PROTECTED</span> <span class="o">=</span> <span class="mh">0x1000</span>
61 <span class="n">SECURITY_DESCRIPTOR_SACL_PROTECTED</span> <span class="o">=</span> <span class="mh">0x2000</span>
62 <span class="n">SECURITY_DESCRIPTOR_RM_CONTROL_VALID</span> <span class="o">=</span> <span class="mh">0x4000</span>
63 <span class="n">SECURITY_DESCRIPTOR_SELF_RELATIVE</span> <span class="o">=</span> <span class="mh">0x8000</span>
64
65 <span class="c1"># ACE types</span>
66 <span class="c1"># [MS-DTYP]: 2.4.4.1</span>
67 <span class="n">ACE_TYPE_ACCESS_ALLOWED</span> <span class="o">=</span> <span class="mh">0x00</span>
68 <span class="n">ACE_TYPE_ACCESS_DENIED</span> <span class="o">=</span> <span class="mh">0x01</span>
69 <span class="n">ACE_TYPE_SYSTEM_AUDIT</span> <span class="o">=</span> <span class="mh">0x02</span>
70 <span class="n">ACE_TYPE_SYSTEM_ALARM</span> <span class="o">=</span> <span class="mh">0x03</span>
71 <span class="n">ACE_TYPE_ACCESS_ALLOWED_COMPOUND</span> <span class="o">=</span> <span class="mh">0x04</span>
72 <span class="n">ACE_TYPE_ACCESS_ALLOWED_OBJECT</span> <span class="o">=</span> <span class="mh">0x05</span>
73 <span class="n">ACE_TYPE_ACCESS_DENIED_OBJECT</span> <span class="o">=</span> <span class="mh">0x06</span>
74 <span class="n">ACE_TYPE_SYSTEM_AUDIT_OBJECT</span> <span class="o">=</span> <span class="mh">0x07</span>
75 <span class="n">ACE_TYPE_SYSTEM_ALARM_OBJECT</span> <span class="o">=</span> <span class="mh">0x08</span>
76 <span class="n">ACE_TYPE_ACCESS_ALLOWED_CALLBACK</span> <span class="o">=</span> <span class="mh">0x09</span>
77 <span class="n">ACE_TYPE_ACCESS_DENIED_CALLBACK</span> <span class="o">=</span> <span class="mh">0x0A</span>
78 <span class="n">ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT</span> <span class="o">=</span> <span class="mh">0x0B</span>
79 <span class="n">ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT</span> <span class="o">=</span> <span class="mh">0x0C</span>
80 <span class="n">ACE_TYPE_SYSTEM_AUDIT_CALLBACK</span> <span class="o">=</span> <span class="mh">0x0D</span>
81 <span class="n">ACE_TYPE_SYSTEM_ALARM_CALLBACK</span> <span class="o">=</span> <span class="mh">0x0E</span>
82 <span class="n">ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT</span> <span class="o">=</span> <span class="mh">0x0F</span>
83 <span class="n">ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT</span> <span class="o">=</span> <span class="mh">0x10</span>
84 <span class="n">ACE_TYPE_SYSTEM_MANDATORY_LABEL</span> <span class="o">=</span> <span class="mh">0x11</span>
85 <span class="n">ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE</span> <span class="o">=</span> <span class="mh">0x12</span>
86 <span class="n">ACE_TYPE_SYSTEM_SCOPED_POLICY_ID</span> <span class="o">=</span> <span class="mh">0x13</span>
87
88 <span class="c1"># ACE flags</span>
89 <span class="c1"># [MS-DTYP]: 2.4.4.1</span>
90 <span class="n">ACE_FLAG_OBJECT_INHERIT</span> <span class="o">=</span> <span class="mh">0x01</span>
91 <span class="n">ACE_FLAG_CONTAINER_INHERIT</span> <span class="o">=</span> <span class="mh">0x02</span>
92 <span class="n">ACE_FLAG_NO_PROPAGATE_INHERIT</span> <span class="o">=</span> <span class="mh">0x04</span>
93 <span class="n">ACE_FLAG_INHERIT_ONLY</span> <span class="o">=</span> <span class="mh">0x08</span>
94 <span class="n">ACE_FLAG_INHERITED</span> <span class="o">=</span> <span class="mh">0x10</span>
95 <span class="n">ACE_FLAG_SUCCESSFUL_ACCESS</span> <span class="o">=</span> <span class="mh">0x40</span>
96 <span class="n">ACE_FLAG_FAILED_ACCESS</span> <span class="o">=</span> <span class="mh">0x80</span>
97
98 <span class="c1"># Pre-defined well-known SIDs</span>
99 <span class="c1"># [MS-DTYP]: 2.4.2.4</span>
100 <span class="n">SID_NULL</span> <span class="o">=</span> <span class="s2">&quot;S-1-0-0&quot;</span>
101 <span class="n">SID_EVERYONE</span> <span class="o">=</span> <span class="s2">&quot;S-1-1-0&quot;</span>
102 <span class="n">SID_LOCAL</span> <span class="o">=</span> <span class="s2">&quot;S-1-2-0&quot;</span>
103 <span class="n">SID_CONSOLE_LOGON</span> <span class="o">=</span> <span class="s2">&quot;S-1-2-1&quot;</span>
104 <span class="n">SID_CREATOR_OWNER</span> <span class="o">=</span> <span class="s2">&quot;S-1-3-0&quot;</span>
105 <span class="n">SID_CREATOR_GROUP</span> <span class="o">=</span> <span class="s2">&quot;S-1-3-1&quot;</span>
106 <span class="n">SID_OWNER_SERVER</span> <span class="o">=</span> <span class="s2">&quot;S-1-3-2&quot;</span>
107 <span class="n">SID_GROUP_SERVER</span> <span class="o">=</span> <span class="s2">&quot;S-1-3-3&quot;</span>
108 <span class="n">SID_OWNER_RIGHTS</span> <span class="o">=</span> <span class="s2">&quot;S-1-3-4&quot;</span>
109 <span class="n">SID_NT_AUTHORITY</span> <span class="o">=</span> <span class="s2">&quot;S-1-5&quot;</span>
110 <span class="n">SID_DIALUP</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-1&quot;</span>
111 <span class="n">SID_NETWORK</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-2&quot;</span>
112 <span class="n">SID_BATCH</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-3&quot;</span>
113 <span class="n">SID_INTERACTIVE</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-4&quot;</span>
114 <span class="n">SID_SERVICE</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-6&quot;</span>
115 <span class="n">SID_ANONYMOUS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-7&quot;</span>
116 <span class="n">SID_PROXY</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-8&quot;</span>
117 <span class="n">SID_ENTERPRISE_DOMAIN_CONTROLLERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-9&quot;</span>
118 <span class="n">SID_PRINCIPAL_SELF</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-10&quot;</span>
119 <span class="n">SID_AUTHENTICATED_USERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-11&quot;</span>
120 <span class="n">SID_RESTRICTED_CODE</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-12&quot;</span>
121 <span class="n">SID_TERMINAL_SERVER_USER</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-13&quot;</span>
122 <span class="n">SID_REMOTE_INTERACTIVE_LOGON</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-14&quot;</span>
123 <span class="n">SID_THIS_ORGANIZATION</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-15&quot;</span>
124 <span class="n">SID_IUSR</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-17&quot;</span>
125 <span class="n">SID_LOCAL_SYSTEM</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-18&quot;</span>
126 <span class="n">SID_LOCAL_SERVICE</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-19&quot;</span>
127 <span class="n">SID_NETWORK_SERVICE</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-20&quot;</span>
128 <span class="n">SID_COMPOUNDED_AUTHENTICATION</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-21-0-0-0-496&quot;</span>
129 <span class="n">SID_CLAIMS_VALID</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-21-0-0-0-497&quot;</span>
130 <span class="n">SID_BUILTIN_ADMINISTRATORS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-544&quot;</span>
131 <span class="n">SID_BUILTIN_USERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-545&quot;</span>
132 <span class="n">SID_BUILTIN_GUESTS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-546&quot;</span>
133 <span class="n">SID_POWER_USERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-547&quot;</span>
134 <span class="n">SID_ACCOUNT_OPERATORS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-548&quot;</span>
135 <span class="n">SID_SERVER_OPERATORS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-549&quot;</span>
136 <span class="n">SID_PRINTER_OPERATORS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-550&quot;</span>
137 <span class="n">SID_BACKUP_OPERATORS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-551&quot;</span>
138 <span class="n">SID_REPLICATOR</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-552&quot;</span>
139 <span class="n">SID_ALIAS_PREW2KCOMPACC</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-554&quot;</span>
140 <span class="n">SID_REMOTE_DESKTOP</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-555&quot;</span>
141 <span class="n">SID_NETWORK_CONFIGURATION_OPS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-556&quot;</span>
142 <span class="n">SID_INCOMING_FOREST_TRUST_BUILDERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-557&quot;</span>
143 <span class="n">SID_PERFMON_USERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-558&quot;</span>
144 <span class="n">SID_PERFLOG_USERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-559&quot;</span>
145 <span class="n">SID_WINDOWS_AUTHORIZATION_ACCESS_GROUP</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-560&quot;</span>
146 <span class="n">SID_TERMINAL_SERVER_LICENSE_SERVERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-561&quot;</span>
147 <span class="n">SID_DISTRIBUTED_COM_USERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-562&quot;</span>
148 <span class="n">SID_IIS_IUSRS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-568&quot;</span>
149 <span class="n">SID_CRYPTOGRAPHIC_OPERATORS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-569&quot;</span>
150 <span class="n">SID_EVENT_LOG_READERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-573&quot;</span>
151 <span class="n">SID_CERTIFICATE_SERVICE_DCOM_ACCESS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-574&quot;</span>
152 <span class="n">SID_RDS_REMOTE_ACCESS_SERVERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-575&quot;</span>
153 <span class="n">SID_RDS_ENDPOINT_SERVERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-576&quot;</span>
154 <span class="n">SID_RDS_MANAGEMENT_SERVERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-577&quot;</span>
155 <span class="n">SID_HYPER_V_ADMINS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-578&quot;</span>
156 <span class="n">SID_ACCESS_CONTROL_ASSISTANCE_OPS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-579&quot;</span>
157 <span class="n">SID_REMOTE_MANAGEMENT_USERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-32-580&quot;</span>
158 <span class="n">SID_WRITE_RESTRICTED_CODE</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-33&quot;</span>
159 <span class="n">SID_NTLM_AUTHENTICATION</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-64-10&quot;</span>
160 <span class="n">SID_SCHANNEL_AUTHENTICATION</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-64-14&quot;</span>
161 <span class="n">SID_DIGEST_AUTHENTICATION</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-64-21&quot;</span>
162 <span class="n">SID_THIS_ORGANIZATION_CERTIFICATE</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-65-1&quot;</span>
163 <span class="n">SID_NT_SERVICE</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-80&quot;</span>
164 <span class="n">SID_USER_MODE_DRIVERS</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-84-0-0-0-0-0&quot;</span>
165 <span class="n">SID_LOCAL_ACCOUNT</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-113&quot;</span>
166 <span class="n">SID_LOCAL_ACCOUNT_AND_MEMBER_OF_ADMINISTRATORS_GROUP</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-114&quot;</span>
167 <span class="n">SID_OTHER_ORGANIZATION</span> <span class="o">=</span> <span class="s2">&quot;S-1-5-1000&quot;</span>
168 <span class="n">SID_ALL_APP_PACKAGES</span> <span class="o">=</span> <span class="s2">&quot;S-1-15-2-1&quot;</span>
169 <span class="n">SID_ML_UNTRUSTED</span> <span class="o">=</span> <span class="s2">&quot;S-1-16-0&quot;</span>
170 <span class="n">SID_ML_LOW</span> <span class="o">=</span> <span class="s2">&quot;S-1-16-4096&quot;</span>
171 <span class="n">SID_ML_MEDIUM</span> <span class="o">=</span> <span class="s2">&quot;S-1-16-8192&quot;</span>
172 <span class="n">SID_ML_MEDIUM_PLUS</span> <span class="o">=</span> <span class="s2">&quot;S-1-16-8448&quot;</span>
173 <span class="n">SID_ML_HIGH</span> <span class="o">=</span> <span class="s2">&quot;S-1-16-12288&quot;</span>
174 <span class="n">SID_ML_SYSTEM</span> <span class="o">=</span> <span class="s2">&quot;S-1-16-16384&quot;</span>
175 <span class="n">SID_ML_PROTECTED_PROCESS</span> <span class="o">=</span> <span class="s2">&quot;S-1-16-20480&quot;</span>
176 <span class="n">SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY</span> <span class="o">=</span> <span class="s2">&quot;S-1-18-1&quot;</span>
177 <span class="n">SID_SERVICE_ASSERTED_IDENTITY</span> <span class="o">=</span> <span class="s2">&quot;S-1-18-2&quot;</span>
178 <span class="n">SID_FRESH_PUBLIC_KEY_IDENTITY</span> <span class="o">=</span> <span class="s2">&quot;S-1-18-3&quot;</span>
179 <span class="n">SID_KEY_TRUST_IDENTITY</span> <span class="o">=</span> <span class="s2">&quot;S-1-18-4&quot;</span>
180 <span class="n">SID_KEY_PROPERTY_MFA</span> <span class="o">=</span> <span class="s2">&quot;S-1-18-5&quot;</span>
181 <span class="n">SID_KEY_PROPERTY_ATTESTATION</span> <span class="o">=</span> <span class="s2">&quot;S-1-18-6&quot;</span>
182
183
184 <div class="viewcode-block" id="SID"><a class="viewcode-back" href="../../api/smb_security_descriptors.html#smb.security_descriptors.SID">[docs]</a><span class="k">class</span> <span class="nc">SID</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
185 <span class="sd">&quot;&quot;&quot;</span>
186 <span class="sd"> A Windows security identifier. Represents a single principal, such a</span>
187 <span class="sd"> user or a group, as a sequence of numbers consisting of the revision,</span>
188 <span class="sd"> identifier authority, and a variable-length list of subauthorities.</span>
189
190 <span class="sd"> See [MS-DTYP]: 2.4.2</span>
191 <span class="sd"> &quot;&quot;&quot;</span>
192 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">revision</span><span class="p">,</span> <span class="n">identifier_authority</span><span class="p">,</span> <span class="n">subauthorities</span><span class="p">):</span>
193 <span class="c1">#: Revision, should always be 1.</span>
194 <span class="bp">self</span><span class="o">.</span><span class="n">revision</span> <span class="o">=</span> <span class="n">revision</span>
195 <span class="c1">#: An integer representing the identifier authority.</span>
196 <span class="bp">self</span><span class="o">.</span><span class="n">identifier_authority</span> <span class="o">=</span> <span class="n">identifier_authority</span>
197 <span class="c1">#: A list of integers representing all subauthorities.</span>
198 <span class="bp">self</span><span class="o">.</span><span class="n">subauthorities</span> <span class="o">=</span> <span class="n">subauthorities</span>
199
200 <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
201 <span class="sd">&quot;&quot;&quot;</span>
202 <span class="sd"> String representation, as specified in [MS-DTYP]: 2.4.2.1</span>
203 <span class="sd"> &quot;&quot;&quot;</span>
204 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">identifier_authority</span> <span class="o">&gt;=</span> <span class="mi">2</span><span class="o">**</span><span class="mi">32</span><span class="p">:</span>
205 <span class="n">id_auth</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%#x</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">identifier_authority</span><span class="p">,)</span>
206 <span class="k">else</span><span class="p">:</span>
207 <span class="n">id_auth</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">identifier_authority</span>
208 <span class="n">auths</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">revision</span><span class="p">,</span> <span class="n">id_auth</span><span class="p">]</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">subauthorities</span>
209 <span class="k">return</span> <span class="s1">&#39;S-&#39;</span> <span class="o">+</span> <span class="s1">&#39;-&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">subauth</span><span class="p">)</span> <span class="k">for</span> <span class="n">subauth</span> <span class="ow">in</span> <span class="n">auths</span><span class="p">)</span>
210
211 <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
212 <span class="k">return</span> <span class="s1">&#39;SID(</span><span class="si">%r</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">),)</span>
213
214 <span class="nd">@classmethod</span>
215 <span class="k">def</span> <span class="nf">from_bytes</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">return_tail</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
216 <span class="n">revision</span><span class="p">,</span> <span class="n">subauth_count</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;BB&#39;</span><span class="p">,</span> <span class="n">data</span><span class="p">[:</span><span class="mi">2</span><span class="p">])</span>
217 <span class="n">identifier_authority</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&gt;Q&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x00\x00</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="n">data</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">8</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span>
218 <span class="n">subauth_data</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="mi">8</span><span class="p">:]</span>
219 <span class="n">subauthorities</span> <span class="o">=</span> <span class="p">[</span><span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;L&#39;</span><span class="p">,</span> <span class="n">subauth_data</span><span class="p">[</span><span class="mi">4</span> <span class="o">*</span> <span class="n">i</span> <span class="p">:</span> <span class="mi">4</span> <span class="o">*</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)])[</span><span class="mi">0</span><span class="p">]</span>
220 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">subauth_count</span><span class="p">)]</span>
221 <span class="n">sid</span> <span class="o">=</span> <span class="bp">cls</span><span class="p">(</span><span class="n">revision</span><span class="p">,</span> <span class="n">identifier_authority</span><span class="p">,</span> <span class="n">subauthorities</span><span class="p">)</span>
222 <span class="k">if</span> <span class="n">return_tail</span><span class="p">:</span>
223 <span class="k">return</span> <span class="n">sid</span><span class="p">,</span> <span class="n">subauth_data</span><span class="p">[</span><span class="mi">4</span> <span class="o">*</span> <span class="n">subauth_count</span> <span class="p">:]</span>
224 <span class="k">return</span> <span class="n">sid</span></div>
225
226
227 <div class="viewcode-block" id="ACE"><a class="viewcode-back" href="../../api/smb_security_descriptors.html#smb.security_descriptors.ACE">[docs]</a><span class="k">class</span> <span class="nc">ACE</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
228 <span class="sd">&quot;&quot;&quot;</span>
229 <span class="sd"> Represents a single access control entry.</span>
230
231 <span class="sd"> See [MS-DTYP]: 2.4.4</span>
232 <span class="sd"> &quot;&quot;&quot;</span>
233 <span class="n">HEADER_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;BBH&#39;</span>
234
235 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">mask</span><span class="p">,</span> <span class="n">sid</span><span class="p">,</span> <span class="n">additional_data</span><span class="p">):</span>
236 <span class="c1">#: An integer representing the type of the ACE. One of the</span>
237 <span class="c1">#: ``ACE_TYPE_*`` constants. Corresponds to the ``AceType`` field</span>
238 <span class="c1">#: from [MS-DTYP] 2.4.4.1.</span>
239 <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">type_</span>
240 <span class="c1">#: An integer bitmask with ACE flags, corresponds to the</span>
241 <span class="c1">#: ``AceFlags`` field.</span>
242 <span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">flags</span>
243 <span class="c1">#: An integer representing the ``ACCESS_MASK`` as specified in</span>
244 <span class="c1">#: [MS-DTYP] 2.4.3.</span>
245 <span class="bp">self</span><span class="o">.</span><span class="n">mask</span> <span class="o">=</span> <span class="n">mask</span>
246 <span class="c1">#: The :class:`SID` of a trustee.</span>
247 <span class="bp">self</span><span class="o">.</span><span class="n">sid</span> <span class="o">=</span> <span class="n">sid</span>
248 <span class="c1">#: A dictionary of additional fields present in the ACE, depending</span>
249 <span class="c1">#: on the type. The following fields can be present:</span>
250 <span class="c1">#:</span>
251 <span class="c1">#: * ``flags``</span>
252 <span class="c1">#: * ``object_type``</span>
253 <span class="c1">#: * ``inherited_object_type``</span>
254 <span class="c1">#: * ``application_data``</span>
255 <span class="c1">#: * ``attribute_data``</span>
256 <span class="bp">self</span><span class="o">.</span><span class="n">additional_data</span> <span class="o">=</span> <span class="n">additional_data</span>
257
258 <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
259 <span class="k">return</span> <span class="s2">&quot;ACE(type=</span><span class="si">%#04x</span><span class="s2">, flags=</span><span class="si">%#04x</span><span class="s2">, mask=</span><span class="si">%#010x</span><span class="s2">, sid=</span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span>
260 <span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mask</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sid</span><span class="p">,</span>
261 <span class="p">)</span>
262
263 <span class="nd">@property</span>
264 <span class="k">def</span> <span class="nf">isInheritOnly</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
265 <span class="sd">&quot;&quot;&quot;Convenience property which indicates if this ACE is inherit</span>
266 <span class="sd"> only, meaning that it doesn&#39;t apply to the object itself.&quot;&quot;&quot;</span>
267 <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">&amp;</span> <span class="n">ACE_FLAG_INHERIT_ONLY</span><span class="p">)</span>
268
269 <span class="nd">@classmethod</span>
270 <span class="k">def</span> <span class="nf">from_bytes</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
271 <span class="n">header_size</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">HEADER_FORMAT</span><span class="p">)</span>
272 <span class="n">header</span> <span class="o">=</span> <span class="n">data</span><span class="p">[:</span><span class="n">header_size</span><span class="p">]</span>
273 <span class="n">type_</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">size</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">HEADER_FORMAT</span><span class="p">,</span> <span class="n">header</span><span class="p">)</span>
274
275 <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">size</span>
276
277 <span class="n">body</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">header_size</span><span class="p">:</span><span class="n">size</span><span class="p">]</span>
278 <span class="n">additional_data</span> <span class="o">=</span> <span class="p">{}</span>
279
280 <span class="c1"># In all ACE types, the mask immediately follows the header.</span>
281 <span class="n">mask</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">body</span><span class="p">[:</span><span class="mi">4</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span>
282 <span class="n">body</span> <span class="o">=</span> <span class="n">body</span><span class="p">[</span><span class="mi">4</span><span class="p">:]</span>
283
284 <span class="c1"># All OBJECT-type ACEs contain additional flags, and two GUIDs as</span>
285 <span class="c1"># the following fields.</span>
286 <span class="k">if</span> <span class="n">type_</span> <span class="ow">in</span> <span class="p">(</span><span class="n">ACE_TYPE_ACCESS_ALLOWED_OBJECT</span><span class="p">,</span>
287 <span class="n">ACE_TYPE_ACCESS_DENIED_OBJECT</span><span class="p">,</span>
288 <span class="n">ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT</span><span class="p">,</span>
289 <span class="n">ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT</span><span class="p">,</span>
290 <span class="n">ACE_TYPE_SYSTEM_AUDIT_OBJECT</span><span class="p">,</span>
291 <span class="n">ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT</span><span class="p">):</span>
292 <span class="n">additional_data</span><span class="p">[</span><span class="s1">&#39;flags&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;I&#39;</span><span class="p">,</span> <span class="n">body</span><span class="p">[:</span><span class="mi">4</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span>
293 <span class="n">additional_data</span><span class="p">[</span><span class="s1">&#39;object_type&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">body</span><span class="p">[</span><span class="mi">4</span><span class="p">:</span><span class="mi">20</span><span class="p">]</span>
294 <span class="n">additional_data</span><span class="p">[</span><span class="s1">&#39;inherited_object_type&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">body</span><span class="p">[</span><span class="mi">20</span><span class="p">:</span><span class="mi">36</span><span class="p">]</span>
295 <span class="n">body</span> <span class="o">=</span> <span class="n">body</span><span class="p">[</span><span class="mi">36</span><span class="p">:]</span>
296
297 <span class="c1"># Then the SID in all types.</span>
298 <span class="n">sid</span><span class="p">,</span> <span class="n">body</span> <span class="o">=</span> <span class="n">SID</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">body</span><span class="p">,</span> <span class="n">return_tail</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
299
300 <span class="c1"># CALLBACK-type ACEs (and for some obscure reason,</span>
301 <span class="c1"># SYSTEM_AUDIT_OBJECT) have a final tail of application data.</span>
302 <span class="k">if</span> <span class="n">type_</span> <span class="ow">in</span> <span class="p">(</span><span class="n">ACE_TYPE_ACCESS_ALLOWED_CALLBACK</span><span class="p">,</span>
303 <span class="n">ACE_TYPE_ACCESS_DENIED_CALLBACK</span><span class="p">,</span>
304 <span class="n">ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT</span><span class="p">,</span>
305 <span class="n">ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT</span><span class="p">,</span>
306 <span class="n">ACE_TYPE_SYSTEM_AUDIT_OBJECT</span><span class="p">,</span>
307 <span class="n">ACE_TYPE_SYSTEM_AUDIT_CALLBACK</span><span class="p">,</span>
308 <span class="n">ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT</span><span class="p">):</span>
309 <span class="n">additional_data</span><span class="p">[</span><span class="s1">&#39;application_data&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">body</span>
310
311 <span class="c1"># SYSTEM_RESOURCE_ATTRIBUTE ACEs have a tail of attribute data.</span>
312 <span class="k">if</span> <span class="n">type_</span> <span class="o">==</span> <span class="n">ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE</span><span class="p">:</span>
313 <span class="n">additional_data</span><span class="p">[</span><span class="s1">&#39;attribute_data&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">body</span>
314
315 <span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="n">type_</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">mask</span><span class="p">,</span> <span class="n">sid</span><span class="p">,</span> <span class="n">additional_data</span><span class="p">)</span></div>
316
317
318 <div class="viewcode-block" id="ACL"><a class="viewcode-back" href="../../api/smb_security_descriptors.html#smb.security_descriptors.ACL">[docs]</a><span class="k">class</span> <span class="nc">ACL</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
319 <span class="sd">&quot;&quot;&quot;</span>
320 <span class="sd"> Access control list, encapsulating a sequence of access control</span>
321 <span class="sd"> entries.</span>
322
323 <span class="sd"> See [MS-DTYP]: 2.4.5</span>
324 <span class="sd"> &quot;&quot;&quot;</span>
325 <span class="n">HEADER_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;BBHHH&#39;</span>
326
327 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">revision</span><span class="p">,</span> <span class="n">aces</span><span class="p">):</span>
328 <span class="c1">#: Integer value of the revision.</span>
329 <span class="bp">self</span><span class="o">.</span><span class="n">revision</span> <span class="o">=</span> <span class="n">revision</span>
330 <span class="c1">#: List of :class:`ACE` instances.</span>
331 <span class="bp">self</span><span class="o">.</span><span class="n">aces</span> <span class="o">=</span> <span class="n">aces</span>
332
333 <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
334 <span class="k">return</span> <span class="s2">&quot;ACL(</span><span class="si">%r</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">aces</span><span class="p">,)</span>
335
336 <span class="nd">@classmethod</span>
337 <span class="k">def</span> <span class="nf">from_bytes</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
338 <span class="n">revision</span> <span class="o">=</span> <span class="kc">None</span>
339 <span class="n">aces</span> <span class="o">=</span> <span class="p">[]</span>
340
341 <span class="n">header_size</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">HEADER_FORMAT</span><span class="p">)</span>
342 <span class="n">header</span><span class="p">,</span> <span class="n">remaining</span> <span class="o">=</span> <span class="n">data</span><span class="p">[:</span><span class="n">header_size</span><span class="p">],</span> <span class="n">data</span><span class="p">[</span><span class="n">header_size</span><span class="p">:]</span>
343 <span class="n">revision</span><span class="p">,</span> <span class="n">sbz1</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">sbz2</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">HEADER_FORMAT</span><span class="p">,</span> <span class="n">header</span><span class="p">)</span>
344
345 <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">size</span>
346
347 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">count</span><span class="p">):</span>
348 <span class="n">ace_size</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;H&#39;</span><span class="p">,</span> <span class="n">remaining</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">4</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span>
349 <span class="n">ace_data</span><span class="p">,</span> <span class="n">remaining</span> <span class="o">=</span> <span class="n">remaining</span><span class="p">[:</span><span class="n">ace_size</span><span class="p">],</span> <span class="n">remaining</span><span class="p">[</span><span class="n">ace_size</span><span class="p">:]</span>
350 <span class="n">aces</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">ACE</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">ace_data</span><span class="p">))</span>
351
352 <span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="n">revision</span><span class="p">,</span> <span class="n">aces</span><span class="p">)</span></div>
353
354
355 <div class="viewcode-block" id="SecurityDescriptor"><a class="viewcode-back" href="../../api/smb_security_descriptors.html#smb.security_descriptors.SecurityDescriptor">[docs]</a><span class="k">class</span> <span class="nc">SecurityDescriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
356 <span class="sd">&quot;&quot;&quot;</span>
357 <span class="sd"> Represents a security descriptor.</span>
358
359 <span class="sd"> See [MS-DTYP]: 2.4.6</span>
360 <span class="sd"> &quot;&quot;&quot;</span>
361
362 <span class="n">HEADER_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;BBHIIII&#39;</span>
363
364 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">owner</span><span class="p">,</span> <span class="n">group</span><span class="p">,</span> <span class="n">dacl</span><span class="p">,</span> <span class="n">sacl</span><span class="p">):</span>
365 <span class="c1">#: Integer bitmask of control flags. Corresponds to the</span>
366 <span class="c1">#: ``Control`` field in [MS-DTYP] 2.4.6.</span>
367 <span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">flags</span>
368 <span class="c1">#: Instance of :class:`SID` representing the owner user.</span>
369 <span class="bp">self</span><span class="o">.</span><span class="n">owner</span> <span class="o">=</span> <span class="n">owner</span>
370 <span class="c1">#: Instance of :class:`SID` representing the owner group.</span>
371 <span class="bp">self</span><span class="o">.</span><span class="n">group</span> <span class="o">=</span> <span class="n">group</span>
372 <span class="c1">#: Instance of :class:`ACL` representing the discretionary access</span>
373 <span class="c1">#: control list, which specifies access restrictions of an object.</span>
374 <span class="bp">self</span><span class="o">.</span><span class="n">dacl</span> <span class="o">=</span> <span class="n">dacl</span>
375 <span class="c1">#: Instance of :class:`ACL` representing the system access control</span>
376 <span class="c1">#: list, which specifies audit logging of an object.</span>
377 <span class="bp">self</span><span class="o">.</span><span class="n">sacl</span> <span class="o">=</span> <span class="n">sacl</span>
378
379 <span class="nd">@classmethod</span>
380 <span class="k">def</span> <span class="nf">from_bytes</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
381 <span class="n">owner</span> <span class="o">=</span> <span class="kc">None</span>
382 <span class="n">group</span> <span class="o">=</span> <span class="kc">None</span>
383 <span class="n">dacl</span> <span class="o">=</span> <span class="kc">None</span>
384 <span class="n">sacl</span> <span class="o">=</span> <span class="kc">None</span>
385
386 <span class="n">header</span> <span class="o">=</span> <span class="n">data</span><span class="p">[:</span><span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">HEADER_FORMAT</span><span class="p">)]</span>
387 <span class="p">(</span><span class="n">revision</span><span class="p">,</span> <span class="n">sbz1</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">owner_offset</span><span class="p">,</span> <span class="n">group_offset</span><span class="p">,</span> <span class="n">sacl_offset</span><span class="p">,</span>
388 <span class="n">dacl_offset</span><span class="p">)</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">HEADER_FORMAT</span><span class="p">,</span> <span class="n">header</span><span class="p">)</span>
389
390 <span class="k">assert</span> <span class="n">revision</span> <span class="o">==</span> <span class="mi">1</span>
391 <span class="k">assert</span> <span class="n">flags</span> <span class="o">&amp;</span> <span class="n">SECURITY_DESCRIPTOR_SELF_RELATIVE</span>
392 <span class="k">for</span> <span class="n">offset</span> <span class="ow">in</span> <span class="p">(</span><span class="n">owner_offset</span><span class="p">,</span> <span class="n">group_offset</span><span class="p">,</span> <span class="n">sacl_offset</span><span class="p">,</span> <span class="n">dacl_offset</span><span class="p">):</span>
393 <span class="k">assert</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">offset</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
394
395 <span class="k">if</span> <span class="n">owner_offset</span><span class="p">:</span>
396 <span class="n">owner</span> <span class="o">=</span> <span class="n">SID</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">owner_offset</span><span class="p">:])</span>
397 <span class="k">if</span> <span class="n">group_offset</span><span class="p">:</span>
398 <span class="n">group</span> <span class="o">=</span> <span class="n">SID</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">group_offset</span><span class="p">:])</span>
399 <span class="k">if</span> <span class="n">dacl_offset</span><span class="p">:</span>
400 <span class="n">dacl</span> <span class="o">=</span> <span class="n">ACL</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">dacl_offset</span><span class="p">:])</span>
401 <span class="k">if</span> <span class="n">sacl_offset</span><span class="p">:</span>
402 <span class="n">sacl</span> <span class="o">=</span> <span class="n">ACL</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">sacl_offset</span><span class="p">:])</span>
403
404 <span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="n">flags</span><span class="p">,</span> <span class="n">owner</span><span class="p">,</span> <span class="n">group</span><span class="p">,</span> <span class="n">dacl</span><span class="p">,</span> <span class="n">sacl</span><span class="p">)</span></div>
405 </pre></div>
406
407 <div class="clearer"></div>
408 </div>
409 </div>
410 </div>
411 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
412 <div class="sphinxsidebarwrapper">
413 <div id="searchbox" style="display: none" role="search">
414 <h3 id="searchlabel">Quick search</h3>
415 <div class="searchformwrapper">
416 <form class="search" action="../../search.html" method="get">
417 <input type="text" name="q" aria-labelledby="searchlabel" />
418 <input type="submit" value="Go" />
419 </form>
420 </div>
421 </div>
422 <script>$('#searchbox').show(0);</script>
423 </div>
424 </div>
425 <div class="clearer"></div>
426 </div>
427 <div class="related" role="navigation" aria-label="related navigation">
428 <h3>Navigation</h3>
429 <ul>
430 <li class="right" style="margin-right: 10px">
431 <a href="../../genindex.html" title="General Index"
432 >index</a></li>
433 <li class="right" >
434 <a href="../../py-modindex.html" title="Python Module Index"
435 >modules</a> |</li>
436 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.7 documentation</a> &#187;</li>
437 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &#187;</li>
438 <li class="nav-item nav-item-this"><a href="">smb.security_descriptors</a></li>
439 </ul>
440 </div>
441 <div class="footer" role="contentinfo">
442 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
443 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.4.3.
444 </div>
445 </body>
446 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>smb.smb_structs &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../../_static/jquery.js"></script>
23 <script type="text/javascript" src="../../_static/underscore.js"></script>
24 <script type="text/javascript" src="../../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../../index.html" />
26 <link rel="up" title="Module code" href="../index.html" />
27 </head>
28 <body role="document">
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>smb.smb_structs &#8212; pysmb 1.2.8 documentation</title>
8 <link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
9 <link rel="stylesheet" type="text/css" href="../../_static/sphinxdoc.css" />
10 <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
11 <script src="../../_static/jquery.js"></script>
12 <script src="../../_static/underscore.js"></script>
13 <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
14 <script src="../../_static/doctools.js"></script>
15 <link rel="index" title="Index" href="../../genindex.html" />
16 <link rel="search" title="Search" href="../../search.html" />
17 </head><body>
2918 <div class="related" role="navigation" aria-label="related navigation">
3019 <h3>Navigation</h3>
3120 <ul>
3221 <li class="right" style="margin-right: 10px">
3322 <a href="../../genindex.html" title="General Index"
3423 accesskey="I">index</a></li>
35 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
24 <li class="right" >
25 <a href="../../py-modindex.html" title="Python Module Index"
26 >modules</a> |</li>
27 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
28 <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &#187;</li>
29 <li class="nav-item nav-item-this"><a href="">smb.smb_structs</a></li>
3730 </ul>
38 </div>
39 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
40 <div class="sphinxsidebarwrapper">
41 <div id="searchbox" style="display: none" role="search">
42 <h3>Quick search</h3>
43 <form class="search" action="../../search.html" method="get">
44 <input type="text" name="q" />
45 <input type="submit" value="Go" />
46 <input type="hidden" name="check_keywords" value="yes" />
47 <input type="hidden" name="area" value="default" />
48 </form>
49 <p class="searchtip" style="font-size: 90%">
50 Enter search terms or a module, class or function name.
51 </p>
52 </div>
53 <script type="text/javascript">$('#searchbox').show(0);</script>
54 </div>
55 </div>
31 </div>
5632
5733 <div class="document">
5834 <div class="documentwrapper">
6036 <div class="body" role="main">
6137
6238 <h1>Source code for smb.smb_structs</h1><div class="highlight"><pre>
63
39 <span></span>
6440 <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">sys</span><span class="o">,</span> <span class="nn">struct</span><span class="o">,</span> <span class="nn">types</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">binascii</span><span class="o">,</span> <span class="nn">time</span>
65 <span class="kn">from</span> <span class="nn">StringIO</span> <span class="kn">import</span> <span class="n">StringIO</span>
66 <span class="kn">from</span> <span class="nn">smb_constants</span> <span class="kn">import</span> <span class="o">*</span>
67
41 <span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">StringIO</span>
42 <span class="kn">from</span> <span class="nn">.smb_constants</span> <span class="kn">import</span> <span class="o">*</span>
43 <span class="kn">from</span> <span class="nn">.strategy</span> <span class="kn">import</span> <span class="n">DataFaultToleranceStrategy</span>
6844
6945 <span class="c1"># Set to True if you want to enable support for extended security. Required for Windows Vista and later</span>
70 <span class="n">SUPPORT_EXTENDED_SECURITY</span> <span class="o">=</span> <span class="bp">True</span>
46 <span class="n">SUPPORT_EXTENDED_SECURITY</span> <span class="o">=</span> <span class="kc">True</span>
7147
7248 <span class="c1"># Set to True if you want to enable SMB2 protocol.</span>
73 <span class="n">SUPPORT_SMB2</span> <span class="o">=</span> <span class="bp">True</span>
49 <span class="n">SUPPORT_SMB2</span> <span class="o">=</span> <span class="kc">True</span>
7450
7551 <span class="c1"># Supported dialects</span>
7652 <span class="n">DIALECTS</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
77 <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="p">(</span> <span class="n">name</span><span class="p">,</span> <span class="n">dialect</span> <span class="p">)</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">([</span> <span class="p">(</span> <span class="s1">&#39;NT_LAN_MANAGER_DIALECT&#39;</span><span class="p">,</span> <span class="s1">&#39;NT LM 0.12&#39;</span> <span class="p">),</span> <span class="p">]):</span>
53 <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="p">(</span> <span class="n">name</span><span class="p">,</span> <span class="n">dialect</span> <span class="p">)</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">([</span> <span class="p">(</span> <span class="s1">&#39;NT_LAN_MANAGER_DIALECT&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;NT LM 0.12&#39;</span> <span class="p">),</span> <span class="p">]):</span>
7854 <span class="n">DIALECTS</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span>
7955 <span class="nb">globals</span><span class="p">()[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span>
8056
8157 <span class="n">DIALECTS2</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span>
82 <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="p">(</span> <span class="n">name</span><span class="p">,</span> <span class="n">dialect</span> <span class="p">)</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">([</span> <span class="p">(</span> <span class="s1">&#39;SMB2_DIALECT&#39;</span><span class="p">,</span> <span class="s1">&#39;SMB 2.002&#39;</span> <span class="p">)</span> <span class="p">]):</span>
58 <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="p">(</span> <span class="n">name</span><span class="p">,</span> <span class="n">dialect</span> <span class="p">)</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">([</span> <span class="p">(</span> <span class="s1">&#39;SMB2_DIALECT&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;SMB 2.002&#39;</span> <span class="p">)</span> <span class="p">]):</span>
8359 <span class="n">DIALECTS2</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span>
8460 <span class="nb">globals</span><span class="p">()[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">DIALECTS</span><span class="p">)</span>
8561
9470
9571 <div class="viewcode-block" id="ProtocolError"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.smb_structs.ProtocolError">[docs]</a><span class="k">class</span> <span class="nc">ProtocolError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
9672
97 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">data_buf</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">smb_message</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
73 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">data_buf</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">smb_message</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
9874 <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
9975 <span class="bp">self</span><span class="o">.</span><span class="n">data_buf</span> <span class="o">=</span> <span class="n">data_buf</span>
10076 <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span> <span class="o">=</span> <span class="n">smb_message</span>
10177
102 <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
78 <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
10379 <span class="n">b</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>
10480 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span>
10581 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="p">:</span>
10884
10985 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_buf</span><span class="p">:</span>
11086 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;=&#39;</span> <span class="o">*</span> <span class="mi">20</span> <span class="o">+</span> <span class="s1">&#39; SMB Data Packet (hex) &#39;</span> <span class="o">+</span> <span class="s1">&#39;=&#39;</span> <span class="o">*</span> <span class="mi">20</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span>
111 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_buf</span><span class="p">))</span>
87 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_buf</span><span class="p">)))</span>
11288 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span>
11389
11490 <span class="k">return</span> <span class="n">b</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span></div>
11591
11692 <span class="k">class</span> <span class="nc">SMB2ProtocolHeaderError</span><span class="p">(</span><span class="n">ProtocolError</span><span class="p">):</span>
11793
118 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
119 <span class="n">ProtocolError</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;Packet header belongs to SMB2&quot;</span><span class="p">)</span>
94 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
95 <span class="n">ProtocolError</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;Packet header belongs to SMB2&quot;</span><span class="p">)</span>
12096
12197 <div class="viewcode-block" id="OperationFailure"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.smb_structs.OperationFailure">[docs]</a><span class="k">class</span> <span class="nc">OperationFailure</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
12298
123 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">smb_messages</span><span class="p">):</span>
124 <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span> <span class="n">message</span> <span class="p">]</span>
99 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">smb_messages</span><span class="p">):</span>
125100 <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
126101 <span class="bp">self</span><span class="o">.</span><span class="n">smb_messages</span> <span class="o">=</span> <span class="n">smb_messages</span>
127102
128 <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
103 <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
129104 <span class="n">b</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>
130105 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span>
131106
136111 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">m</span><span class="p">))</span>
137112 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;SMB Data Packet (hex):&#39;</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span>
138113 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;----------------------&#39;</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span>
139 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">raw_data</span><span class="p">))</span>
114 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">raw_data</span><span class="p">)))</span>
140115 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span>
141116
142117 <span class="k">return</span> <span class="n">b</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span></div>
144119
145120 <span class="k">class</span> <span class="nc">SMBError</span><span class="p">:</span>
146121
147 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
122 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
148123 <span class="bp">self</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span>
149124
150125 <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
151 <span class="bp">self</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">=</span> <span class="il">0L</span>
152 <span class="bp">self</span><span class="o">.</span><span class="n">is_ntstatus</span> <span class="o">=</span> <span class="bp">True</span>
153
154 <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
126 <span class="bp">self</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">=</span> <span class="mi">0</span>
127 <span class="bp">self</span><span class="o">.</span><span class="n">is_ntstatus</span> <span class="o">=</span> <span class="kc">True</span>
128
129 <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
155130 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_ntstatus</span><span class="p">:</span>
156131 <span class="k">return</span> <span class="s1">&#39;NTSTATUS=0x</span><span class="si">%08X</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">internal_value</span>
157132 <span class="k">else</span><span class="p">:</span>
170145 <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s1">&#39;SMB.SMBMessage&#39;</span><span class="p">)</span>
171146 <span class="n">protocol</span> <span class="o">=</span> <span class="mi">1</span>
172147
173 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">payload</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
148 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">payload</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
174149 <span class="bp">self</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span>
175150 <span class="k">if</span> <span class="n">payload</span><span class="p">:</span>
176151 <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">payload</span>
177152 <span class="bp">self</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
178153
179 <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
154 <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
180155 <span class="n">b</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>
181156 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Command: 0x</span><span class="si">%02X</span><span class="s1"> (</span><span class="si">%s</span><span class="s1">) </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="n">SMB_COMMAND_NAMES</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="s1">&#39;&lt;unknown&gt;&#39;</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span>
182157 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Status: </span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">status</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span>
187162 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;MID: </span><span class="si">%d</span><span class="s1"> </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span>
188163 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;TID: </span><span class="si">%d</span><span class="s1"> </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span>
189164 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Security: 0x</span><span class="si">%016X</span><span class="s1"> </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">security</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span>
190 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Parameters: </span><span class="si">%d</span><span class="s1"> bytes </span><span class="si">%s%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span>
191 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Data: </span><span class="si">%d</span><span class="s1"> bytes </span><span class="si">%s%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span>
165 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Parameters: </span><span class="si">%d</span><span class="s1"> bytes </span><span class="si">%s%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span>
166 <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Data: </span><span class="si">%d</span><span class="s1"> bytes </span><span class="si">%s%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span>
192167 <span class="k">return</span> <span class="n">b</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
193168
194169 <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
195 <span class="bp">self</span><span class="o">.</span><span class="n">raw_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
170 <span class="bp">self</span><span class="o">.</span><span class="n">raw_data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
196171 <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="mi">0</span>
197172 <span class="bp">self</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">SMBError</span><span class="p">()</span>
198173 <span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span>
201176 <span class="bp">self</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="mi">0</span>
202177 <span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="mi">0</span>
203178 <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="mi">0</span>
204 <span class="bp">self</span><span class="o">.</span><span class="n">security</span> <span class="o">=</span> <span class="il">0L</span>
205 <span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
206 <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
207 <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="bp">None</span>
179 <span class="bp">self</span><span class="o">.</span><span class="n">security</span> <span class="o">=</span> <span class="mi">0</span>
180 <span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
181 <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
182 <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="kc">None</span>
183
184 <span class="nd">@property</span>
185 <span class="k">def</span> <span class="nf">isAsync</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
186 <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">&amp;</span> <span class="n">SMB2_FLAGS_ASYNC_COMMAND</span><span class="p">)</span>
208187
209188 <span class="nd">@property</span>
210189 <span class="k">def</span> <span class="nf">isReply</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
230209 <span class="k">assert</span> <span class="n">parameters_len</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span>
231210
232211 <span class="n">headers_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">HEADER_STRUCT_FORMAT</span><span class="p">,</span>
233 <span class="s1">&#39;</span><span class="se">\xFF</span><span class="s1">SMB&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span>
212 <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\xFF</span><span class="s1">SMB&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span>
234213 <span class="bp">self</span><span class="o">.</span><span class="n">flags2</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pid</span> <span class="o">&gt;&gt;</span> <span class="mi">16</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xFFFF</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">security</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span>
235214 <span class="bp">self</span><span class="o">.</span><span class="n">pid</span> <span class="o">&amp;</span> <span class="mh">0xFFFF</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">uid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">parameters_len</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span>
236215 <span class="k">return</span> <span class="n">headers_data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;H&#39;</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">))</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
258237 <span class="bp">self</span><span class="o">.</span><span class="n">flags2</span><span class="p">,</span> <span class="n">pid_high</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">security</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> \
259238 <span class="n">pid_low</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">uid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">params_count</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">HEADER_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">buf</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span><span class="p">])</span>
260239
261 <span class="k">if</span> <span class="n">protocol</span> <span class="o">==</span> <span class="s1">&#39;</span><span class="se">\xFE</span><span class="s1">SMB&#39;</span><span class="p">:</span>
240 <span class="k">if</span> <span class="n">protocol</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\xFE</span><span class="s1">SMB&#39;</span><span class="p">:</span>
262241 <span class="k">raise</span> <span class="n">SMB2ProtocolHeaderError</span><span class="p">()</span>
263 <span class="k">if</span> <span class="n">protocol</span> <span class="o">!=</span> <span class="s1">&#39;</span><span class="se">\xFF</span><span class="s1">SMB&#39;</span><span class="p">:</span>
242 <span class="k">if</span> <span class="n">protocol</span> <span class="o">!=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\xFF</span><span class="s1">SMB&#39;</span><span class="p">:</span>
264243 <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s1">&#39;Invalid 4-byte protocol field&#39;</span><span class="p">,</span> <span class="n">buf</span><span class="p">)</span>
265244
266245 <span class="bp">self</span><span class="o">.</span><span class="n">pid</span> <span class="o">=</span> <span class="p">(</span><span class="n">pid_high</span> <span class="o">&lt;&lt;</span> <span class="mi">16</span><span class="p">)</span> <span class="o">|</span> <span class="n">pid_low</span>
316295
317296 <span class="k">class</span> <span class="nc">Payload</span><span class="p">:</span>
318297
319 <span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\xFF\x00\x00\x00</span><span class="s1">&#39;</span>
298 <span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\xFF\x00\x00\x00</span><span class="s1">&#39;</span>
320299 <span class="n">DEFAULT_ANDX_PARAM_SIZE</span> <span class="o">=</span> <span class="mi">4</span>
321300
322301 <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
325304 <span class="c1"># support SMB_FLAGS2_UNICODE by default.</span>
326305 <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">payload</span> <span class="o">==</span> <span class="bp">self</span>
327306 <span class="n">message</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">SMB_FLAGS_CASE_INSENSITIVE</span> <span class="o">|</span> <span class="n">SMB_FLAGS_CANONICALIZED_PATHS</span>
328 <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">=</span> <span class="n">SMB_FLAGS2_UNICODE</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_NT_STATUS</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_LONG_NAMES</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_EAS</span>
307 <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">=</span> <span class="n">SMB_FLAGS2_UNICODE</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_NT_STATUS</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_IS_LONG_NAME</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_LONG_NAMES</span>
329308
330309 <span class="k">if</span> <span class="n">SUPPORT_EXTENDED_SECURITY</span><span class="p">:</span>
331 <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">|=</span> <span class="n">SMB_FLAGS2_EXTENDED_SECURITY</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_SMB_SECURITY_SIGNATURE</span>
310 <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">|=</span> <span class="n">SMB_FLAGS2_EXTENDED_SECURITY</span>
332311
333312 <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
334313 <span class="k">raise</span> <span class="ne">NotImplementedError</span>
351330
352331 <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
353332 <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">payload</span> <span class="o">==</span> <span class="bp">self</span>
354 <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
333 <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
355334 <span class="k">if</span> <span class="n">SUPPORT_SMB2</span><span class="p">:</span>
356 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="s1">&#39;</span><span class="se">\x02</span><span class="s1">&#39;</span><span class="o">+</span><span class="n">s</span><span class="o">+</span><span class="s1">&#39;</span><span class="se">\x00</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">DIALECTS</span> <span class="o">+</span> <span class="n">DIALECTS2</span><span class="p">))</span>
335 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x02</span><span class="s1">&#39;</span><span class="o">+</span><span class="n">s</span><span class="o">+</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x00</span><span class="s1">&#39;</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">DIALECTS</span> <span class="o">+</span> <span class="n">DIALECTS2</span><span class="p">])</span>
357336 <span class="k">else</span><span class="p">:</span>
358 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="s1">&#39;</span><span class="se">\x02</span><span class="s1">&#39;</span><span class="o">+</span><span class="n">s</span><span class="o">+</span><span class="s1">&#39;</span><span class="se">\x00</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">DIALECTS</span><span class="p">))</span>
337 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x02</span><span class="s1">&#39;</span><span class="o">+</span><span class="n">s</span><span class="o">+</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x00</span><span class="s1">&#39;</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">DIALECTS</span><span class="p">])</span>
359338
360339
361340 <span class="k">class</span> <span class="nc">ComNegotiateResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
429408 <span class="k">if</span> <span class="n">data_len</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">challenge_length</span><span class="p">:</span>
430409 <span class="bp">self</span><span class="o">.</span><span class="n">challenge</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">challenge_length</span><span class="p">]</span>
431410
432 <span class="n">s</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
411 <span class="n">s</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
433412 <span class="n">offset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">challenge_length</span>
434413 <span class="k">while</span> <span class="n">offset</span> <span class="o">&lt;</span> <span class="n">data_len</span><span class="p">:</span>
435414 <span class="n">_s</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">2</span><span class="p">]</span>
436 <span class="k">if</span> <span class="n">_s</span> <span class="o">==</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span><span class="p">:</span>
437 <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
415 <span class="k">if</span> <span class="n">_s</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span><span class="p">:</span>
416 <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="n">DataFaultToleranceStrategy</span><span class="o">.</span><span class="n">data_bytes_decode</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="c1">#.decode(&#39;UTF-16LE&#39;)</span>
438417 <span class="k">break</span>
439418 <span class="k">else</span><span class="p">:</span>
440419 <span class="n">s</span> <span class="o">+=</span> <span class="n">_s</span>
462441
463442 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;HHHIHII&#39;</span>
464443
465 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session_key</span><span class="p">,</span> <span class="n">security_blob</span><span class="p">):</span>
444 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session_key</span><span class="p">,</span> <span class="n">security_blob</span><span class="p">):</span>
466445 <span class="bp">self</span><span class="o">.</span><span class="n">session_key</span> <span class="o">=</span> <span class="n">session_key</span>
467446 <span class="bp">self</span><span class="o">.</span><span class="n">security_blob</span> <span class="o">=</span> <span class="n">security_blob</span>
468447
484463
485464 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">security_blob</span>
486465 <span class="k">if</span> <span class="p">(</span><span class="n">SMBMessage</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">))</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
487 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
488 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span> <span class="o">*</span> <span class="mi">4</span>
466 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
467 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span> <span class="o">*</span> <span class="mi">4</span>
489468
490469
491470 <span class="k">class</span> <span class="nc">ComSessionSetupAndxRequest__NoSecurityExtension</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
497476
498477 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;HHHIHHII&#39;</span>
499478
500 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session_key</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">is_unicode</span><span class="p">,</span> <span class="n">domain</span><span class="p">):</span>
479 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session_key</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">is_unicode</span><span class="p">,</span> <span class="n">domain</span><span class="p">):</span>
501480 <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">username</span>
502481 <span class="bp">self</span><span class="o">.</span><span class="n">session_key</span> <span class="o">=</span> <span class="n">session_key</span>
503482 <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">password</span>
528507
529508 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">password</span>
530509 <span class="k">if</span> <span class="p">(</span><span class="n">est_offset</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">))</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&amp;</span> <span class="n">SMB_FLAGS2_UNICODE</span><span class="p">:</span>
531 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
510 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
532511
533512 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&amp;</span> <span class="n">SMB_FLAGS2_UNICODE</span><span class="p">:</span>
534 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
513 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
535514 <span class="k">else</span><span class="p">:</span>
536 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
515 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-8&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
537516
538517 <span class="k">if</span> <span class="p">(</span><span class="n">est_offset</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">))</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&amp;</span> <span class="n">SMB_FLAGS2_UNICODE</span><span class="p">:</span>
539 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
518 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
540519
541520 <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&amp;</span> <span class="n">SMB_FLAGS2_UNICODE</span><span class="p">:</span>
542 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="s1">&#39;pysmb&#39;</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
521 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="s1">&#39;pysmb&#39;</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
543522 <span class="k">else</span><span class="p">:</span>
544 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">pysmb</span><span class="se">\0</span><span class="s1">&#39;</span>
523 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-8&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">pysmb</span><span class="se">\0</span><span class="s1">&#39;</span>
545524
546525
547526 <span class="k">class</span> <span class="nc">ComSessionSetupAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
604583 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;HH&#39;</span>
605584 <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span>
606585
607 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">service</span><span class="p">,</span> <span class="n">password</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">):</span>
586 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">service</span><span class="p">,</span> <span class="n">password</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">):</span>
608587 <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span>
609588 <span class="bp">self</span><span class="o">.</span><span class="n">service</span> <span class="o">=</span> <span class="n">service</span>
610589 <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">password</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
620599 <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span>
621600 <span class="mh">0x08</span> <span class="o">|</span> \
622601 <span class="p">((</span><span class="n">message</span><span class="o">.</span><span class="n">hasExtendedSecurity</span> <span class="ow">and</span> <span class="mh">0x0004</span><span class="p">)</span> <span class="ow">or</span> <span class="mh">0x00</span><span class="p">)</span> <span class="o">|</span> \
623 <span class="p">((</span><span class="n">message</span><span class="o">.</span><span class="n">tid</span> <span class="ow">and</span> <span class="n">message</span><span class="o">.</span><span class="n">tid</span> <span class="o">!=</span> <span class="mh">0xFFFF</span> <span class="ow">and</span> <span class="mh">0x0001</span><span class="p">)</span> <span class="ow">or</span> <span class="mh">0x00</span><span class="p">),</span> <span class="c1"># Disconnect tid, if message.tid must be non-zero</span>
602 <span class="p">((</span><span class="n">message</span><span class="o">.</span><span class="n">tid</span> <span class="ow">and</span> <span class="n">message</span><span class="o">.</span><span class="n">tid</span> <span class="o">!=</span> <span class="mh">0xffff</span> <span class="ow">and</span> <span class="mh">0x0001</span><span class="p">)</span> <span class="ow">or</span> <span class="mh">0x00</span><span class="p">),</span> <span class="c1"># Disconnect tid, if message.tid must be non-zero</span>
624603 <span class="n">password_len</span><span class="p">)</span>
625604
626 <span class="n">padding</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
605 <span class="n">padding</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
627606 <span class="k">if</span> <span class="n">password_len</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
628 <span class="n">padding</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
607 <span class="n">padding</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
629608
630609 <span class="c1"># Note that service field is never encoded in UTF-16LE. [MS-CIFS]: 2.2.1.1</span>
631 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">+</span> <span class="n">padding</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">service</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
610 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-8&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="n">padding</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">service</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-8&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
632611
633612
634613 <span class="k">class</span> <span class="nc">ComTreeConnectAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
667646 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;BHIIIQIIIIIB&#39;</span>
668647 <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span>
669648
670 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">root_fid</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">access_mask</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">allocation_size</span> <span class="o">=</span> <span class="il">0L</span><span class="p">,</span> <span class="n">ext_attr</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
649 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">root_fid</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">access_mask</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">allocation_size</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ext_attr</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
671650 <span class="n">share_access</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">create_disp</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">create_options</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">impersonation</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">security_flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
672651 <span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="p">(</span><span class="n">filename</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span>
673652 <span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">flags</span>
704683 <span class="bp">self</span><span class="o">.</span><span class="n">impersonation</span><span class="p">,</span> <span class="c1"># ImpersonationLevel</span>
705684 <span class="bp">self</span><span class="o">.</span><span class="n">security_flags</span><span class="p">)</span> <span class="c1"># SecurityFlags</span>
706685
707 <span class="n">padding</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
686 <span class="n">padding</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
708687 <span class="k">if</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">))</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
709 <span class="n">padding</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
688 <span class="n">padding</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
710689
711690 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">padding</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename</span>
712691
746725 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;HHHHBBHIHHHHHH&#39;</span>
747726 <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span>
748727
749 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">max_params_count</span><span class="p">,</span> <span class="n">max_data_count</span><span class="p">,</span> <span class="n">max_setup_count</span><span class="p">,</span>
728 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">max_params_count</span><span class="p">,</span> <span class="n">max_data_count</span><span class="p">,</span> <span class="n">max_setup_count</span><span class="p">,</span>
750729 <span class="n">total_params_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">total_data_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
751 <span class="n">params_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">setup_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
730 <span class="n">params_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">setup_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span>
752731 <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\\</span><span class="s2">PIPE</span><span class="se">\\</span><span class="s2">&quot;</span><span class="p">):</span>
753732 <span class="bp">self</span><span class="o">.</span><span class="n">total_params_count</span> <span class="o">=</span> <span class="n">total_params_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">params_bytes</span><span class="p">)</span>
754733 <span class="bp">self</span><span class="o">.</span><span class="n">total_data_count</span> <span class="o">=</span> <span class="n">total_data_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">)</span>
773752 <span class="n">params_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span><span class="p">)</span>
774753 <span class="n">data_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span>
775754
776 <span class="n">padding0</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
755 <span class="n">padding0</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
777756 <span class="n">offset</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_bytes_len</span> <span class="o">+</span> <span class="mi">2</span> <span class="c1"># constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters)</span>
778757 <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
779 <span class="n">padding0</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
758 <span class="n">padding0</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
780759 <span class="n">offset</span> <span class="o">+=</span> <span class="mi">1</span>
781760
782761 <span class="n">offset</span> <span class="o">+=</span> <span class="n">name_len</span> <span class="c1"># For the name field</span>
783 <span class="n">padding1</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
762 <span class="n">padding1</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
784763 <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
785 <span class="n">padding1</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
764 <span class="n">padding1</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
786765 <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
787766
788767 <span class="k">if</span> <span class="n">params_bytes_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
791770 <span class="k">else</span><span class="p">:</span>
792771 <span class="n">params_bytes_offset</span> <span class="o">=</span> <span class="mi">0</span>
793772
794 <span class="n">padding2</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
773 <span class="n">padding2</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
795774 <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
796 <span class="n">padding2</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
775 <span class="n">padding2</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
797776 <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
798777
799778 <span class="k">if</span> <span class="n">data_bytes_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
886865 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;HHHHBBHIHHHHHH&#39;</span>
887866 <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span>
888867
889 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">max_params_count</span><span class="p">,</span> <span class="n">max_data_count</span><span class="p">,</span> <span class="n">max_setup_count</span><span class="p">,</span>
868 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">max_params_count</span><span class="p">,</span> <span class="n">max_data_count</span><span class="p">,</span> <span class="n">max_setup_count</span><span class="p">,</span>
890869 <span class="n">total_params_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">total_data_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
891 <span class="n">params_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">setup_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
870 <span class="n">params_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">setup_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span>
892871 <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
893872 <span class="bp">self</span><span class="o">.</span><span class="n">total_params_count</span> <span class="o">=</span> <span class="n">total_params_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">params_bytes</span><span class="p">)</span>
894873 <span class="bp">self</span><span class="o">.</span><span class="n">total_data_count</span> <span class="o">=</span> <span class="n">total_data_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">)</span>
909888 <span class="n">setup_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span><span class="p">)</span>
910889 <span class="n">params_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span><span class="p">)</span>
911890 <span class="n">data_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span>
912 <span class="n">name</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
913
914 <span class="n">padding0</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
891 <span class="n">name</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
892
893 <span class="n">padding0</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
915894 <span class="n">offset</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_bytes_len</span> <span class="o">+</span> <span class="mi">2</span> <span class="c1"># constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters)</span>
916895 <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
917 <span class="n">padding0</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
896 <span class="n">padding0</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span>
918897 <span class="n">offset</span> <span class="o">+=</span> <span class="mi">1</span>
919898
920899 <span class="n">offset</span> <span class="o">+=</span> <span class="mi">2</span> <span class="c1"># For the name field</span>
921 <span class="n">padding1</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
900 <span class="n">padding1</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
922901 <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
923 <span class="n">padding1</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
902 <span class="n">padding1</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
924903
925904 <span class="k">if</span> <span class="n">params_bytes_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
926905 <span class="n">params_bytes_offset</span> <span class="o">=</span> <span class="n">offset</span>
928907 <span class="k">else</span><span class="p">:</span>
929908 <span class="n">params_bytes_offset</span> <span class="o">=</span> <span class="mi">0</span>
930909
931 <span class="n">padding2</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
910 <span class="n">padding2</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
932911 <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
933 <span class="n">padding2</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
912 <span class="n">padding2</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
934913
935914 <span class="k">if</span> <span class="n">data_bytes_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
936915 <span class="n">data_bytes_offset</span> <span class="o">=</span> <span class="n">offset</span>
10221001 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;HI&#39;</span>
10231002 <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span>
10241003
1025 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">last_modified_time</span> <span class="o">=</span> <span class="mh">0xFFFFFFFF</span><span class="p">):</span>
1004 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">last_modified_time</span> <span class="o">=</span> <span class="mh">0xFFFFFFFF</span><span class="p">):</span>
10261005 <span class="bp">self</span><span class="o">.</span><span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span>
10271006 <span class="bp">self</span><span class="o">.</span><span class="n">last_modified_time</span> <span class="o">=</span> <span class="n">last_modified_time</span>
10281007
10321011
10331012 <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
10341013 <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_modified_time</span><span class="p">)</span>
1035 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
1014 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
10361015
10371016
10381017 <span class="k">class</span> <span class="nc">ComOpenAndxRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
10451024 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;HHHHIHIII&#39;</span>
10461025 <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span>
10471026
1048 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">access_mode</span><span class="p">,</span> <span class="n">open_mode</span><span class="p">,</span> <span class="n">flags</span> <span class="o">=</span> <span class="mh">0x0000</span><span class="p">,</span> <span class="n">search_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">create_time</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
1027 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">access_mode</span><span class="p">,</span> <span class="n">open_mode</span><span class="p">,</span> <span class="n">flags</span> <span class="o">=</span> <span class="mh">0x0000</span><span class="p">,</span> <span class="n">search_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">create_time</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
10491028 <span class="sd">&quot;&quot;&quot;</span>
10501029 <span class="sd"> @param create_time: Epoch time value to indicate the time of creation for this file. If zero, we will automatically assign the current time</span>
10511030 <span class="sd"> @type create_time: int</span>
10791058 <span class="mi">0</span><span class="p">,</span> <span class="c1"># Timeout (in milli-secs)</span>
10801059 <span class="mi">0</span><span class="p">)</span> <span class="c1"># Reserved</span>
10811060
1082 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
1061 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
10831062
10841063
10851064 <span class="k">class</span> <span class="nc">ComOpenAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
11261105 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;HIIHHHHHI&#39;</span>
11271106 <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span>
11281107
1129 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">write_mode</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
1108 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">write_mode</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
11301109 <span class="sd">&quot;&quot;&quot;</span>
11311110 <span class="sd"> @param timeout: Number of milliseconds to wait for blocked write request before failing. Must be zero for writing to regular file</span>
11321111 <span class="sd"> @type timeout: int</span>
11601139 <span class="n">data_offset</span><span class="p">,</span> <span class="c1"># DataOffset</span>
11611140 <span class="bp">self</span><span class="o">.</span><span class="n">offset</span> <span class="o">&gt;&gt;</span> <span class="mi">32</span><span class="p">)</span> <span class="c1"># OffsetHigh field defined in [MS-SMB]: 2.2.4.3.1</span>
11621141
1163 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span>
1142 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span>
11641143
11651144
11661145 <span class="k">class</span> <span class="nc">ComWriteAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
11961175 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;HIHHIHI&#39;</span>
11971176 <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span>
11981177
1199 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">max_return_bytes_count</span><span class="p">,</span> <span class="n">min_return_bytes_count</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">remaining</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
1178 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">max_return_bytes_count</span><span class="p">,</span> <span class="n">min_return_bytes_count</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">remaining</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
12001179 <span class="sd">&quot;&quot;&quot;</span>
12011180 <span class="sd"> @param timeout: If reading from a regular file, this parameter must be 0.</span>
12021181 <span class="sd"> @type timeout: int</span>
12241203 <span class="bp">self</span><span class="o">.</span><span class="n">remaining</span><span class="p">,</span> <span class="c1"># In [MS-CIFS]: 2.2.4.42.1, this field must be set to 0x0000</span>
12251204 <span class="bp">self</span><span class="o">.</span><span class="n">offset</span> <span class="o">&gt;&gt;</span> <span class="mi">32</span><span class="p">)</span>
12261205
1227 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
1206 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
12281207
12291208
12301209 <span class="k">class</span> <span class="nc">ComReadAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
12601239 <span class="sd"> - [MS-CIFS]: 2.2.4.7.1</span>
12611240 <span class="sd"> &quot;&quot;&quot;</span>
12621241
1263 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename_pattern</span><span class="p">,</span> <span class="n">search_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
1242 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename_pattern</span><span class="p">,</span> <span class="n">search_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
12641243 <span class="bp">self</span><span class="o">.</span><span class="n">filename_pattern</span> <span class="o">=</span> <span class="n">filename_pattern</span>
12651244 <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span> <span class="o">=</span> <span class="n">search_attributes</span>
12661245
12701249
12711250 <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
12721251 <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;H&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span><span class="p">)</span>
1273 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\x04</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename_pattern</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
1252 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x04</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename_pattern</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
12741253
12751254
12761255 <span class="k">class</span> <span class="nc">ComCreateDirectoryRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
12831262 <span class="sd"> - [MS-CIFS]: 2.2.4.1.1</span>
12841263 <span class="sd"> &quot;&quot;&quot;</span>
12851264
1286 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
1265 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
12871266 <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span>
12881267
12891268 <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
12911270 <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_CREATE_DIRECTORY</span>
12921271
12931272 <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
1294 <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
1295 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\x04</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
1273 <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
1274 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x04</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
12961275
12971276
12981277 <span class="k">class</span> <span class="nc">ComDeleteDirectoryRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
13021281 <span class="sd"> - [MS-CIFS]: 2.2.4.2.1</span>
13031282 <span class="sd"> &quot;&quot;&quot;</span>
13041283
1305 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
1284 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
13061285 <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span>
13071286
13081287 <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
13101289 <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_DELETE_DIRECTORY</span>
13111290
13121291 <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
1313 <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
1314 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\x04</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
1292 <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
1293 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x04</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0\0</span><span class="s1">&#39;</span>
13151294
13161295
13171296 <span class="k">class</span> <span class="nc">ComRenameRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
13211300 <span class="sd"> - [MS-CIFS]: 2.2.4.8.1</span>
13221301 <span class="sd"> &quot;&quot;&quot;</span>
13231302
1324 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">,</span> <span class="n">search_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
1303 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">,</span> <span class="n">search_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
13251304 <span class="bp">self</span><span class="o">.</span><span class="n">old_path</span> <span class="o">=</span> <span class="n">old_path</span>
13261305 <span class="bp">self</span><span class="o">.</span><span class="n">new_path</span> <span class="o">=</span> <span class="n">new_path</span>
13271306 <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span> <span class="o">=</span> <span class="n">search_attributes</span>
13321311
13331312 <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
13341313 <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;&lt;H&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span><span class="p">)</span>
1335 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\x04</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">old_path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\x00\x00\x04\x00</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">new_path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\x00\x00</span><span class="s1">&#39;</span>
1314 <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x04</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">old_path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x00\x00\x04\x00</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">new_path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;UTF-16LE&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x00\x00</span><span class="s1">&#39;</span>
13361315
13371316
13381317 <span class="k">class</span> <span class="nc">ComEchoRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span>
13421321 <span class="sd"> - [MS-CIFS]: 2.2.4.39.1</span>
13431322 <span class="sd"> &quot;&quot;&quot;</span>
13441323
1345 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">echo_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">echo_count</span> <span class="o">=</span> <span class="mi">1</span><span class="p">):</span>
1324 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">echo_data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">echo_count</span> <span class="o">=</span> <span class="mi">1</span><span class="p">):</span>
13461325 <span class="bp">self</span><span class="o">.</span><span class="n">echo_count</span> <span class="o">=</span> <span class="n">echo_count</span>
13471326 <span class="bp">self</span><span class="o">.</span><span class="n">echo_data</span> <span class="o">=</span> <span class="n">echo_data</span>
13481327
13771356 <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;&lt;BHIIIIIIIIBH&#39;</span>
13781357 <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span>
13791358
1380 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">function</span><span class="p">,</span> <span class="n">max_params_count</span><span class="p">,</span> <span class="n">max_data_count</span><span class="p">,</span> <span class="n">max_setup_count</span><span class="p">,</span>
1359 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">function</span><span class="p">,</span> <span class="n">max_params_count</span><span class="p">,</span> <span class="n">max_data_count</span><span class="p">,</span> <span class="n">max_setup_count</span><span class="p">,</span>
13811360 <span class="n">total_params_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">total_data_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
1382 <span class="n">params_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">setup_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">):</span>
1361 <span class="n">params_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">setup_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">):</span>
13831362 <span class="bp">self</span><span class="o">.</span><span class="n">function</span> <span class="o">=</span> <span class="n">function</span>
13841363 <span class="bp">self</span><span class="o">.</span><span class="n">total_params_count</span> <span class="o">=</span> <span class="n">total_params_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">params_bytes</span><span class="p">)</span>
13851364 <span class="bp">self</span><span class="o">.</span><span class="n">total_data_count</span> <span class="o">=</span> <span class="n">total_data_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">)</span>
13991378 <span class="n">params_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span><span class="p">)</span>
14001379 <span class="n">data_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span>
14011380
1402 <span class="n">padding0</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
1381 <span class="n">padding0</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
14031382 <span class="n">offset</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_bytes_len</span> <span class="o">+</span> <span class="mi">2</span> <span class="c1"># constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters)</span>
14041383 <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
1405 <span class="n">padding0</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
1384 <span class="n">padding0</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
14061385 <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
14071386
14081387 <span class="k">if</span> <span class="n">params_bytes_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
14111390 <span class="n">params_bytes_offset</span> <span class="o">=</span> <span class="mi">0</span>
14121391
14131392 <span class="n">offset</span> <span class="o">+=</span> <span class="n">params_bytes_len</span>
1414 <span class="n">padding1</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
1393 <span class="n">padding1</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
14151394 <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
1416 <span class="n">padding1</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
1395 <span class="n">padding1</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\0</span><span class="s1">&#39;</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
14171396 <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span>
14181397
14191398 <span class="k">if</span> <span class="n">data_bytes_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
14731452 <span class="n">params_offset</span> <span class="o">-=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_count</span><span class="o">*</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span>
14741453 <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">params_offset</span><span class="p">:</span><span class="n">params_offset</span><span class="o">+</span><span class="n">params_count</span><span class="p">]</span>
14751454 <span class="k">else</span><span class="p">:</span>
1476 <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
1455 <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
14771456
14781457 <span class="k">if</span> <span class="n">data_count</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
14791458 <span class="n">data_offset</span> <span class="o">-=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_count</span><span class="o">*</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span>
14801459 <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">data_offset</span><span class="p">:</span><span class="n">data_offset</span><span class="o">+</span><span class="n">data_count</span><span class="p">]</span>
14811460 <span class="k">else</span><span class="p">:</span>
1482 <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
1461 <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
14831462 </pre></div>
14841463
1464 <div class="clearer"></div>
14851465 </div>
1466 </div>
1467 </div>
1468 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
1469 <div class="sphinxsidebarwrapper">
1470 <div id="searchbox" style="display: none" role="search">
1471 <h3 id="searchlabel">Quick search</h3>
1472 <div class="searchformwrapper">
1473 <form class="search" action="../../search.html" method="get">
1474 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
1475 <input type="submit" value="Go" />
1476 </form>
1477 </div>
1478 </div>
1479 <script>document.getElementById('searchbox').style.display = "block"</script>
14861480 </div>
14871481 </div>
14881482 <div class="clearer"></div>
14931487 <li class="right" style="margin-right: 10px">
14941488 <a href="../../genindex.html" title="General Index"
14951489 >index</a></li>
1496 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
1497 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &raquo;</li>
1490 <li class="right" >
1491 <a href="../../py-modindex.html" title="Python Module Index"
1492 >modules</a> |</li>
1493 <li class="nav-item nav-item-0"><a href="../../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
1494 <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &#187;</li>
1495 <li class="nav-item nav-item-this"><a href="">smb.smb_structs</a></li>
14981496 </ul>
14991497 </div>
15001498 <div class="footer" role="contentinfo">
1501 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
1502 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
1499 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
1500 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
15031501 </div>
15041502 </body>
15051503 </html>
0
1 NBNSProtocol Class
2 ==================
3
4 pysmb has a *NBNSProtocol* implementation for Twisted framework.
5 This allows you to perform name query asynchronously without having your application to block and wait for the results.
6
7 In your project,
8 1. Create a NBNSProtocol instance.
9 2. Just call *queryName* method which will return a *Deferred* instance. Add your callback function to the *Deferred* instance via *addCallback* method to receive the results of the name query.
10 3. When you are done with the NBNSProtocol instance, call its <NBNSProtocol instance>.transport.stopListening method to remove this instance from the reactor.
11
12 .. autoclass:: nmb.NetBIOSProtocol.NBNSProtocol
13 :members:
14 :special-members:
15
16 .. autoclass:: nmb.NetBIOSProtocol.NetBIOSTimeout
17 :members:
0
1 NetBIOS class
2 =============
3
4 To use the NetBIOS class in your application,
5 1. Create a new NetBIOS instance
6 2. Call *queryName* method for each name you wish to query. The method will block until a reply is received from the remote SMB/CIFS service, or until timeout.
7 3. When you are done, call *close* method to release the underlying resources.
8
9 .. autoclass:: nmb.NetBIOS.NetBIOS
10 :members:
11 :special-members:
0
1 SMBConnection Class
2 ===================
3
4 The SMBConnection is suitable for developers who wish to use pysmb to perform file operations with a remote SMB/CIFS server sequentially.
5
6 Each file operation method, when invoked, will block and return after it has completed or has encountered an error.
7
8 Example
9 -------
10
11 The following illustrates a simple file retrieving implementation.::
12
13 import tempfile
14 from smb.SMBConnection import SMBConnection
15
16 # There will be some mechanism to capture userID, password, client_machine_name, server_name and server_ip
17 # client_machine_name can be an arbitary ASCII string
18 # server_name should match the remote machine name, or else the connection will be rejected
19 conn = SMBConnection(userID, password, client_machine_name, server_name, use_ntlm_v2 = True)
20 assert conn.connect(server_ip, 139)
21
22 file_obj = tempfile.NamedTemporaryFile()
23 file_attributes, filesize = conn.retrieveFile('smbtest', '/rfc1001.txt', file_obj)
24
25 # Retrieved file contents are inside file_obj
26 # Do what you need with the file_obj and then close it
27 # Note that the file obj is positioned at the end-of-file,
28 # so you might need to perform a file_obj.seek() if you need
29 # to read from the beginning
30 file_obj.close()
31
32 SMB2 Support
33 -------------
34
35 Starting from pysmb 1.1.0, pysmb will utilize SMB2 protocol for communication if the remote SMB/CIFS service supports SMB2.
36 Otherwise, it will fallback automatically back to using SMB1 protocol.
37
38 To disable SMB2 protocol in pysmb, set the *SUPPORT_SMB2* flag in the *smb_structs* module to *False* before creating the *SMBConnection* instance.::
39
40 from smb import smb_structs
41 smb_structs.SUPPORT_SMB2 = False
42
43 Caveats
44 -------
45
46 * It is not meant to be used asynchronously.
47 * A single *SMBConnection* instance should not be used to perform more than one operation concurrently at the same time.
48 * Do not keep a *SMBConnection* instance "idle" for too long, i.e. keeping a *SMBConnection* instance but not using it.
49 Most SMB/CIFS servers have some sort of keepalive mechanism and impose a timeout limit.
50 If the clients fail to respond within the timeout limit, the SMB/CIFS server may disconnect the client.
51
52 .. autoclass:: smb.SMBConnection.SMBConnection
53 :members:
54 :special-members:
0
1 SMbHandler Class
2 ================
3
4 The SMBHandler class provides support for "smb://" URLs in the `urllib2 <http://docs.python.org/library/urllib2.html>`_ python package.
5
6 Notes
7 -----
8 * The host component of the URL must be one of the following:
9
10 * A fully-qualified hostname that can be resolved by your local DNS service. Example: myserver.test.com
11 * An IP address. Example: 192.168.1.1
12 * A comma-separated string "<NBName>,<IP>" where *<NBName>* is the Windows/NetBIOS machine name for remote SMB service, and *<IP>* is the service's IP address. Example: MYSERVER,192.168.1.1
13
14 * The first component of the path in the URL points to the name of the shared folder.
15 Subsequent path components will point to the directory/folder of the file.
16 * You can retrieve and upload files, but you cannot delete files/folders or create folders.
17 In uploads, if the parent folders do not exist, an *urllib2.URLError* will be raised.
18
19 Example
20 -------
21
22 The following code snippet illustrates file retrieval with Python 2.::
23
24 # -*- coding: utf-8 -*-
25 import urllib2
26 from smb.SMBHandler import SMBHandler
27
28 director = urllib2.build_opener(SMBHandler)
29 fh = director.open('smb://myuserID:[email protected]/sharedfolder/rfc1001.txt')
30
31 # Process fh like a file-like object and then close it.
32 fh.close()
33
34 # For paths/files with unicode characters, simply pass in the URL as an unicode string
35 fh2 = director.open(u'smb://myuserID:[email protected]/sharedfolder/测试文件夹/垃圾文件.dat')
36
37 # Process fh2 like a file-like object and then close it.
38 fh2.close()
39
40 The following code snippet illustrates file upload with Python 2. You need to provide a file-like object for the *data* parameter in the *open()* method::
41
42 import urllib2
43 from smb.SMBHandler import SMBHandler
44
45 file_fh = open('local_file.dat', 'rb')
46
47 director = urllib2.build_opener(SMBHandler)
48 fh = director.open('smb://myuserID:[email protected]/sharedfolder/upload_file.dat', data = file_fh)
49
50 # Reading from fh will only return an empty string
51 fh.close()
52
53
54 The following code snippet illustrates file retrieval with Python 3.::
55
56 import urllib
57 from smb.SMBHandler import SMBHandler
58
59 director = urllib.request.build_opener(SMBHandler)
60 fh = director.open('smb://myuserID:[email protected]/sharedfolder/rfc1001.txt')
61
62 # Process fh like a file-like object and then close it.
63 fh.close()
64
65 # For paths/files with unicode characters, simply pass in the URL as an unicode string
66 fh2 = director.open(u'smb://myuserID:[email protected]/sharedfolder/测试文件夹/垃圾文件.dat')
67
68 # Process fh2 like a file-like object and then close it.
69 fh2.close()
70
71 The following code snippet illustrates file upload with Python 3. You need to provide a file-like object for the *data* parameter in the *open()* method::
72
73 import urllib
74 from smb.SMBHandler import SMBHandler
75
76 file_fh = open('local_file.dat', 'rb')
77
78 director = urllib.request.build_opener(SMBHandler)
79 fh = director.open('smb://myuserID:[email protected]/sharedfolder/upload_file.dat', data = file_fh)
80
81 # Reading from fh will only return an empty string
82 fh.close()
55
66 Notes
77 -----
8 * Note that you need to pass in a valid hostname or IP address for the host component of the URL.
9 Do not use the Windows/NetBIOS machine name for the host component.
8 * The host component of the URL must be one of the following:
9
10 * A fully-qualified hostname that can be resolved by your local DNS service. Example: myserver.test.com
11 * An IP address. Example: 192.168.1.1
12 * A comma-separated string "<NBName>,<IP>" where *<NBName>* is the Windows/NetBIOS machine name for remote SMB service, and *<IP>* is the service's IP address. Example: MYSERVER,192.168.1.1
13
1014 * The first component of the path in the URL points to the name of the shared folder.
1115 Subsequent path components will point to the directory/folder of the file.
1216 * You can retrieve and upload files, but you cannot delete files/folders or create folders.
1519 Example
1620 -------
1721
18 The following code snippet illustrates file retrieval.::
22 The following code snippet illustrates file retrieval with Python 2.::
1923
2024 # -*- coding: utf-8 -*-
2125 import urllib2
3337 # Process fh2 like a file-like object and then close it.
3438 fh2.close()
3539
36 The following code snippet illustrates file upload. You need to provide a file-like object for the *data* parameter in the *open()* method::
40 The following code snippet illustrates file upload with Python 2. You need to provide a file-like object for the *data* parameter in the *open()* method::
3741
3842 import urllib2
3943 from smb.SMBHandler import SMBHandler
4549
4650 # Reading from fh will only return an empty string
4751 fh.close()
52
53
54 The following code snippet illustrates file retrieval with Python 3.::
55
56 import urllib
57 from smb.SMBHandler import SMBHandler
58
59 director = urllib.request.build_opener(SMBHandler)
60 fh = director.open('smb://myuserID:[email protected]/sharedfolder/rfc1001.txt')
61
62 # Process fh like a file-like object and then close it.
63 fh.close()
64
65 # For paths/files with unicode characters, simply pass in the URL as an unicode string
66 fh2 = director.open(u'smb://myuserID:[email protected]/sharedfolder/测试文件夹/垃圾文件.dat')
67
68 # Process fh2 like a file-like object and then close it.
69 fh2.close()
70
71 The following code snippet illustrates file upload with Python 3. You need to provide a file-like object for the *data* parameter in the *open()* method::
72
73 import urllib
74 from smb.SMBHandler import SMBHandler
75
76 file_fh = open('local_file.dat', 'rb')
77
78 director = urllib.request.build_opener(SMBHandler)
79 fh = director.open('smb://myuserID:[email protected]/sharedfolder/upload_file.dat', data = file_fh)
80
81 # Reading from fh will only return an empty string
82 fh.close()
0
1 SMBProtocolFactory Class
2 ========================
3
4 For those who want to utilize pysmb in Twisted framework, pysmb has a *smb.SMBProtocol.SMBProtocol* implementation.
5 In most cases, you do not need to touch or import the *SMBProtocol* directly. All the SMB functionalities are exposed in the *SMBProtocolFactory*.
6
7 In your project,
8 1. Create a new class and subclass *SMBProtocolFactory*.
9 2. Override the *SMBProtocolFactory.onAuthOK* and *SMBProtocolFactory.onAuthFailed* instance methods to provide your own post-authenthentication handling.
10 Once *SMBProtocolFactory.onAuthOK* has been called by pymsb internals, your application is ready to communicate with the remote SMB/CIFS service through
11 the *SMBProtocolFactory* public methods such as *SMBProtocolFactory.storeFile*, *SMBProtocolFactory.retrieveFile*, etc.
12 3. When you want to disconnect from the remote SMB/CIFS server, just call *SMBProtocolFactory.closeConnection* method.
13
14 All the *SMBProtocolFactory* public methods that provide file functionlities will return a *twisted.internet.defer.Deferred* instance.
15 A :doc:`NotReadyError<smb_exceptions>` exception is raised when the underlying SMB is not authenticated.
16 If the underlying SMB connection has been terminated, a :doc:`NotConnectedError<smb_exceptions>` exception is raised.
17
18 All the file operation methods in *SMBProtocolFactory* class accept a *timeout* parameter. This parameter specifies the time limit where pysmb will wait for the
19 entire file operation (except *storeFile* and *retrieveFile* methods) to complete. If the file operation fails to complete within the timeout period, the returned
20 *Deferred* instance's *errback* method will be called with a *SMBTimeout* exception.
21
22 If you are interested in learning the results of the operation or to know when the operation has completed, you should
23 add a handling method to the returned *Deferred* instance via *Deferred.addCallback*. If the file operation fails, the *Deferred.errback* function will be called
24 with an :doc:`OperationFailure<smb_exceptions>`; on timeout, it will be called with a :doc:`SMBTimeout<smb_exceptions>`.
25
26 Example
27 -------
28
29 The following illustrates a simple file retrieving implementation.::
30
31 import tempfile
32 from twisted.internet import reactor
33 from smb.SMBProtocol import SMBProtocolFactory
34
35 class RetrieveFileFactory(SMBProtocolFactory):
36
37 def __init__(self, *args, **kwargs):
38 SMBProtocolFactory.__init__(self, *args, **kwargs)
39
40 def fileRetrieved(self, write_result):
41 file_obj, file_attributes, file_size = write_result
42
43 # Retrieved file contents are inside file_obj
44 # Do what you need with the file_obj and then close it
45 # Note that the file obj is positioned at the end-of-file,
46 # so you might need to perform a file_obj.seek() to if you
47 # need to read from the beginning
48 file_obj.close()
49
50 self.transport.loseConnection()
51
52 def onAuthOK(self):
53 d = self.retrieveFile(self.service, self.path, tempfile.NamedTemporaryFile())
54 d.addCallback(self.fileRetrieved)
55 d.addErrback(self.d.errback)
56
57 def onAuthFailed(self):
58 print 'Auth failed'
59
60 # There will be some mechanism to capture userID, password, client_machine_name, server_name and server_ip
61 # client_machine_name can be an arbitary ASCII string
62 # server_name should match the remote machine name, or else the connection will be rejected
63 factory = RetrieveFileFactory(userID, password, client_machine_name, server_name, use_ntlm_v2 = True)
64 factory.service = 'smbtest'
65 factory.path = '/rfc1001.txt'
66 reactor.connectTCP(server_ip, 139, factory)
67
68
69
70
71 SMB2 Support
72 -------------
73
74 Starting from pysmb 1.1.0, pysmb will utilize SMB2 protocol for communication if the remote SMB/CIFS service supports SMB2.
75 Otherwise, it will fallback automatically back to using SMB1 protocol.
76
77 To disable SMB2 protocol in pysmb, set the *SUPPORT_SMB2* flag in the *smb_structs* module to *False* before creating the *SMBProtocolFactory* instance.::
78
79 from smb import smb_structs
80 smb_structs.SUPPORT_SMB2 = False
81
82 Caveats
83 -------
84
85 * A new factory instance must be created for each SMB connection to the remote SMB/CIFS service. Avoid reusing the same factory instance for more than one SMB connection.
86 * The remote SMB/CIFS server usually imposes a limit of the number of concurrent file operations for each client. For example, to transfer a thousand files, you may need to setup a queue in your application and call *storeFile* or *retrieveFile* in batches.
87 * The *timeout* parameter in the file operation methods are not precise; it is accurate to within 1 second interval, i.e. with a timeout of 0.5 sec, pysmb might raise
88 *SMBTimeout* exception after 1.5 sec.
89
90 .. autoclass:: smb.SMBProtocol.SMBProtocolFactory
91 :members:
92 :special-members:
0
1 SharedDevice Class
2 ==================
3
4 .. autoclass:: smb.base.SharedDevice
5 :members:
0
1 SharedFile Class
2 ================
3
4 .. autoclass:: smb.base.SharedFile
5 :members:
0
1 SMB Exceptions
2 ==============
3
4 .. autoclass:: smb.base.SMBTimeout
5 :members:
6
7 .. autoclass:: smb.base.NotReadyError
8 :members:
9
10 .. autoclass:: smb.base.NotConnectedError
11 :members:
12
13 .. autoclass:: smb.smb_structs.UnsupportedFeature
14 :members:
15
16 .. autoclass:: smb.smb_structs.ProtocolError
17 :members:
18
19 .. autoclass:: smb.smb_structs.OperationFailure
20 :members:
0
1 Security Descriptors
2 ====================
3
4 .. module:: smb.security_descriptors
5 :synopsis: Data structures used in Windows security descriptors.
6
7 This module implements security descriptors, and associated data
8 structures, as specified in `[MS-DTYP]`_.
9
10 .. autoclass:: SID
11 :members:
12
13 .. autoclass:: ACE
14 :members:
15
16 .. autoclass:: ACL
17 :members:
18
19 .. autoclass:: SecurityDescriptor
20 :members:
21
22 .. _[MS-DTYP]: https://msdn.microsoft.com/en-us/library/cc230273.aspx
0
1 Security Descriptors
2 ====================
3
4 .. module:: smb.security_descriptors
5 :synopsis: Data structures used in Windows security descriptors.
6
7 This module implements security descriptors, and associated data
8 structures, as specified in `[MS-DTYP]`_.
9
10 .. autoclass:: SID
11 :members:
12
13 .. autoclass:: ACE
14 :members:
15
16 .. autoclass:: ACL
17 :members:
18
19 .. autoclass:: SecurityDescriptor
20 :members:
21
22 .. _[MS-DTYP]: https://msdn.microsoft.com/en-us/library/cc230273.aspx
0
1 Extending pysmb For Other Frameworks
2 ====================================
3
4 This page briefly describes the steps involved in extending pysmb for other frameworks.
5
6 In general, you need to take care of the SMB TCP connection setup, i.e. finding the IP address of the remote server and connect to the SMB/CIFS service.
7 Then you need to read/write synchronously or asynchronously from and to the SMB socket. And you need to handle post-authentication callback methods, and from these methods,
8 initiate file operations with the remote SMB/CIFS server.
9
10 Now the above steps in more technical details:
11 1. Create a new class which subclasses the *smb.base.SMB* class. Most often, the connection setup will be part of the *__init__* method.
12 2. Override the *write(self, data)* method to provide an implementation which will write *data* to the socket.
13 3. Write your own loop handling method to read data from the socket. Once data have been read, call *feedData* method with the parameter.
14 The *feedData* method has its own internal buffer, so it can accept incomplete NetBIOS session packet data.
15 4. Override
16
17 * *onAuthOK* method to include your own operations to perform when authentication is successful. You can initiate file operations in this method.
18 * *onAuthFailed* method to include your own processing on what to do when authentication fails. You can report this as an error, or to try a different NTLM authentication algorithm (*use_ntlm_v2* parameter in the constructor).
19 * *onNMBSessionFailed* method to include your own processing on what to do when pysmb fails to setup the NetBIOS session with the remote server. Usually, this is due to a wrong *remote_name* parameter in the constructor.
0 Welcome to pysmb's documentation!
1 =================================
2
3 pysmb is a pure Python implementation of the client-side SMB/CIFS protocol (SMB1 and SMB2) which is the underlying protocol
4 that facilitates file sharing and printing between Windows machines, as well as with Linux machines via the Samba server application.
5 pysmb is developed in Python 2.7.x and Python 3.8.x and has been tested against shared folders on Windows 7, Windows 10 and Samba 4.x.
6
7 The latest version of pysmb is always available at the pysmb project page at `miketeo.net <http://miketeo.net/projects/pysmb>`_.
8
9 License
10 -------
11 pysmb itself is licensed under an opensource license.
12 You are free to use pysmb in any applications, including for commercial purposes.
13 For more details on the terms of use, please read the LICENSE file that comes with your pysmb source.
14
15 pysmb depends on other 3rd-party modules whose terms of use are not covered by pysmb.
16 Use of these modules could possibly conflict with your licensing needs. Please exercise your own discretion to determine their suitabilities.
17 I have listed these modules in the following section.
18
19 Credits
20 -------
21 pysmb is not alone. It is made possible with support from other modules.
22
23 * **pyasn1** : Pure Python implementation of ASN.1 parsing and encoding (not included together with pysmb; needs to be installed separately)
24 * **md4** and **U32** : Pure Python implementation of MD4 hashing algorithm and 32-bit unsigned integer by Dmitry Rozmanov. Licensed under LGPL and included together with pysmb.
25 * **pyDes** : Pure Python implementation of the DES encryption algorithm by Todd Whiteman. Free domain and included together with pysmb.
26 * **sha256** : Pure Python implementation of SHA-256 message digest by Thomas Dixon. Licensed under MIT and included together with pysmb. This module is imported only when
27 the Python standard library (usually Python 2.4) does not provide the SHA-256 hash algorithm.
28
29 In various places, there are references to different specifications. Most of these referenced specifications
30 can be downloaded from Microsoft web site under Microsoft's "Open Specification Promise". If you need to download
31 a copy of these specifications, please google for it. For example, google for "MS-CIFS" to download the CIFS specification for NT LM dialect.
32
33 Package Contents and Description
34 ================================
35
36 pysmb is organized into 2 main packages: smb and nmb.
37 The smb package contains all the functionalities related to Server Message Block (SMB) implementation.
38 As an application developer, you will be importing this module into your application.
39 Hence, please take some time to familiarize yourself with the smb package contents.
40
41 * **nmb/base.py** :
42 Contains the NetBIOSSession and NBNS abstract class which implements NetBIOS session and NetBIOS Name Service communication
43 without any network transport specifics.
44 * **nmb/NetBIOS.py**:
45 Provides a NBNS implementation to query IP addresses for machine names. All operations are blocking I/O.
46 * **nmb/NetBIOSProtocol.py** :
47 Provides the NBNS protocol implementation for use in Twisted framework.
48
49 * **smb/base.py** :
50 Contains the SMB abstract class which implements the SMB communication without any network transport specifics.
51 * **smb/ntlm.py** :
52 Contains the NTLMv1 and NTLMv2 authentication routines and the decoding/encoding of NTLM authentication messages within SMB messages.
53 * **smb/securityblob.py** :
54 Provides routines to encode/decode the NTLMSSP security blob in the SMB messages.
55 * **smb/smb_constants.py** :
56 All the constants used in the smb package for SMB1 protocol
57 * **smb/smb_structs.py** :
58 Contains the internal classes used in the SMB package for SMB1 protocol. These classes are usually used to encode/decode the parameter and data blocks of specific SMB1 message.
59 * **smb/smb2_constants.py** :
60 All the constants used in the smb package for SMB2 protocol
61 * **smb/smb2_structs.py** :
62 Contains the internal classes used in the SMB package for SMB2 protocol. These classes are usually used to encode/decode the parameter and data blocks of specific SMB2 message.
63 * **smb/SMBConnection.py** :
64 Contains a SMB protocol implementation. All operations are blocking I/O.
65 * **smb/SMBProtocol.py** :
66 Contains the SMB protocol implementation for use in the Twisted framework.
67 * **smb/SMBHandler.py** :
68 Provides support for "smb://" URL in the urllib2 python package.
69
70 Using pysmb
71 ===========
72
73 As an application developer who is looking to use pysmb to translate NetBIOS names to IP addresses,
74 * To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read
75 :doc:`nmb.NetBIOS.NetBIOS<api/nmb_NetBIOS>` documentation.
76 * To use pysmb in Twisted, please read :doc:`nmb.NetBIOSProtocol.NBNSProtocol<api/nmb_NBNSProtocol>` documentation.
77
78 As an application developer who is looking to use pysmb to implement file transfer or authentication over SMB:
79 * To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read
80 :doc:`smb.SMBConnection.SMBConnection<api/smb_SMBConnection>` documentation.
81 * To use pysmb in Twisted, please read :doc:`smb.SMBProtocol.SMBProtocolFactory<api/smb_SMBProtocolFactory>` documentation.
82 * To support "smb://" URL in urllib2 python package, read :doc:`smb.SMBHandler.SMBHandler<api/smb_SMBHandler>` documentation.
83
84 As a software developer who is looking to modify pysmb so that you can integrate it to other network frameworks:
85 * Read :doc:`extending`
86
87 If you are upgrading from older pysmb versions:
88 * Read :doc:`upgrading`
89
90
91 Indices and tables
92 ==================
93
94 .. toctree::
95 :glob:
96 :maxdepth: 1
97
98 api/*
99 extending
100 upgrading
101
102 * :ref:`genindex`
103 * :ref:`search`
77
88 pysmb is a pure Python implementation of the client-side SMB/CIFS protocol (SMB1 and SMB2) which is the underlying protocol
99 that facilitates file sharing and printing between Windows machines, as well as with Linux machines via the Samba server application.
10 pysmb is developed in Python 2.4.6, Python 2.7.1 and Python 3.2.3 and has been tested against shared folders on Windows XP SP3, Windows Vista, Windows 7 and Samba 3.x.
10 pysmb is developed in Python 2.7.x and Python 3.5.x and has been tested against shared folders on Windows XP SP3, Windows Vista, Windows 7 and Samba 3.x.
1111
12 The latest version of pysmb is always available at the pysmb project page at `miketeo.net <http://miketeo.net/wp/index.php/projects/pysmb>`_.
12 The latest version of pysmb is always available at the pysmb project page at `miketeo.net <http://miketeo.net/projects/pysmb>`_.
1313
1414 License
1515 -------
8989 As a software developer who is looking to modify pysmb so that you can integrate it to other network frameworks:
9090 * Read :doc:`extending`
9191
92 If you are upgrading from older pysmb versions:
93 * Read :doc:`upgrading`
9294
9395
9496 Indices and tables
100102
101103 api/*
102104 extending
105 upgrading
103106
104107 * :ref:`genindex`
105108 * :ref:`search`
0 Upgrading from older pysmb versions
1 ====================================
2
3 This page documents the improvements and changes to the API that could be incompatible with previous releases.
4
5 pysmb 1.2.0
6 -----------
7 - Add new `delete_matching_folders` parameter to `deleteFiles()` method in SMBProtocolFactory and SMBConnection
8 class to support deletion of sub-folders. If you are passing timeout parameter to the `deleteFiles()` method
9 in your application, please switch to using named parameter for timeout.
10
11 pysmb 1.1.28
12 ------------
13 - SharedFile instances returned from the `listPath()` method now has a new property
14 `file_id` attribute which represents the file reference number given by the remote SMB server.
15
16 pysmb 1.1.26
17 ------------
18 - SMBConnection class can now be used as a context manager
19
20 pysmb 1.1.25
21 ------------
22 - SharedFile class has a new property `isNormal` which will be True if the file is a
23 'normal' file. pysmb defines a 'normal' file as a file entry that is not
24 read-only, not hidden, not system, not archive and not a directory;
25 it ignores other attributes like compression, indexed, sparse, temporary and encryption.
26 - `listPath()` method in SMBProtocolFactory and SMBConnection class will now include
27 'normal' files by default if you do not specify the `search` parameter.
28
29 pysmb 1.1.20
30 ------------
31 - A new method `getSecurity()` was added to SMBConnection and SMBProtocolFactory class.
32
33 pysmb 1.1.15
34 ------------
35 - Add new `truncate` parameter to `storeFileFromOffset()` in SMBProtocolFactory and SMBConnection
36 class to support truncation of the file before writing. If you are passing timeout parameter
37 to the `storeFileFromOffset()` method in your application, please switch to using named parameter for timeout.
38
39 pysmb 1.1.11
40 ------------
41 - A new method `storeFileFromOffset()` was added to SMBConnection and SMBProtocolFactory class.
42
43 pysmb 1.1.10
44 ------------
45 - A new method `getAttributes()` was added to SMBConnection and SMBProtocolFactory class
46 - SharedFile class has a new property `isReadOnly` to indicate the file is read-only on the remote filesystem.
47
48 pysmb 1.1.2
49 -----------
50 - `queryIPForName()` method in nmb.NetBIOS and nmb.NBNSProtocol class will now return only the server machine name and ignore workgroup names.
51
52 pysmb 1.0.3
53 -----------
54 - Two new methods were added to NBNSProtocol class: `queryIPForName()` and `NetBIOS.queryIPForName()`
55 to support querying for a machine's NetBIOS name at the given IP address.
56 - A new method `retrieveFileFromOffset()` was added to SMBProtocolFactory and SMBConnection
57 to support finer control of file retrieval operation.
58
59 pysmb 1.0.0
60 -----------
61 pysmb was completely rewritten in version 1.0.0.
62 If you are upgrading from pysmb 0.x, you most likely have to rewrite your application for the new 1.x API.
0 Upgrading from older pysmb versions
1 ====================================
2
3 This page documents the improvements and changes to the API that could be incompatible with previous releases.
4
5 pysmb 1.2.0
6 -----------
7 - Add new `delete_matching_folders` parameter to `deleteFiles()` method in SMBProtocolFactory and SMBConnection
8 class to support deletion of sub-folders. If you are passing timeout parameter to the `deleteFiles()` method
9 in your application, please switch to using named parameter for timeout.
10
11 pysmb 1.1.28
12 ------------
13 - SharedFile instances returned from the `listPath()` method now has a new property
14 `file_id` attribute which represents the file reference number given by the remote SMB server.
15
16 pysmb 1.1.26
17 ------------
18 - SMBConnection class can now be used as a context manager
19
20 pysmb 1.1.25
21 ------------
22 - SharedFile class has a new property `isNormal` which will be True if the file is a
23 'normal' file. pysmb defines a 'normal' file as a file entry that is not
24 read-only, not hidden, not system, not archive and not a directory;
25 it ignores other attributes like compression, indexed, sparse, temporary and encryption.
26 - `listPath()` method in SMBProtocolFactory and SMBConnection class will now include
27 'normal' files by default if you do not specify the `search` parameter.
28
29 pysmb 1.1.20
30 ------------
31 - A new method `getSecurity()` was added to SMBConnection and SMBProtocolFactory class.
32
33 pysmb 1.1.15
34 ------------
35 - Add new `truncate` parameter to `storeFileFromOffset()` in SMBProtocolFactory and SMBConnection
36 class to support truncation of the file before writing. If you are passing timeout parameter
37 to the `storeFileFromOffset()` method in your application, please switch to using named parameter for timeout.
38
39 pysmb 1.1.11
40 ------------
41 - A new method `storeFileFromOffset()` was added to SMBConnection and SMBProtocolFactory class.
42
43 pysmb 1.1.10
44 ------------
45 - A new method `getAttributes()` was added to SMBConnection and SMBProtocolFactory class
46 - SharedFile class has a new property `isReadOnly` to indicate the file is read-only on the remote filesystem.
47
48 pysmb 1.1.2
49 -----------
50 - `queryIPForName()` method in nmb.NetBIOS and nmb.NBNSProtocol class will now return only the server machine name and ignore workgroup names.
51
52 pysmb 1.0.3
53 -----------
54 - Two new methods were added to NBNSProtocol class: `queryIPForName()` and `NetBIOS.queryIPForName()`
55 to support querying for a machine's NetBIOS name at the given IP address.
56 - A new method `retrieveFileFromOffset()` was added to SMBProtocolFactory and SMBConnection
57 to support finer control of file retrieval operation.
58
59 pysmb 1.0.0
60 -----------
61 pysmb was completely rewritten in version 1.0.0.
62 If you are upgrading from pysmb 0.x, you most likely have to rewrite your application for the new 1.x API.
0 /*
1 * _sphinx_javascript_frameworks_compat.js
2 * ~~~~~~~~~~
3 *
4 * Compatability shim for jQuery and underscores.js.
5 *
6 * WILL BE REMOVED IN Sphinx 6.0
7 * xref RemovedInSphinx60Warning
8 *
9 */
10
11 /**
12 * select a different prefix for underscore
13 */
14 $u = _.noConflict();
15
16
17 /**
18 * small helper function to urldecode strings
19 *
20 * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
21 */
22 jQuery.urldecode = function(x) {
23 if (!x) {
24 return x
25 }
26 return decodeURIComponent(x.replace(/\+/g, ' '));
27 };
28
29 /**
30 * small helper function to urlencode strings
31 */
32 jQuery.urlencode = encodeURIComponent;
33
34 /**
35 * This function returns the parsed url parameters of the
36 * current request. Multiple values per key are supported,
37 * it will always return arrays of strings for the value parts.
38 */
39 jQuery.getQueryParameters = function(s) {
40 if (typeof s === 'undefined')
41 s = document.location.search;
42 var parts = s.substr(s.indexOf('?') + 1).split('&');
43 var result = {};
44 for (var i = 0; i < parts.length; i++) {
45 var tmp = parts[i].split('=', 2);
46 var key = jQuery.urldecode(tmp[0]);
47 var value = jQuery.urldecode(tmp[1]);
48 if (key in result)
49 result[key].push(value);
50 else
51 result[key] = [value];
52 }
53 return result;
54 };
55
56 /**
57 * highlight a given string on a jquery object by wrapping it in
58 * span elements with the given class name.
59 */
60 jQuery.fn.highlightText = function(text, className) {
61 function highlight(node, addItems) {
62 if (node.nodeType === 3) {
63 var val = node.nodeValue;
64 var pos = val.toLowerCase().indexOf(text);
65 if (pos >= 0 &&
66 !jQuery(node.parentNode).hasClass(className) &&
67 !jQuery(node.parentNode).hasClass("nohighlight")) {
68 var span;
69 var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
70 if (isInSVG) {
71 span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
72 } else {
73 span = document.createElement("span");
74 span.className = className;
75 }
76 span.appendChild(document.createTextNode(val.substr(pos, text.length)));
77 node.parentNode.insertBefore(span, node.parentNode.insertBefore(
78 document.createTextNode(val.substr(pos + text.length)),
79 node.nextSibling));
80 node.nodeValue = val.substr(0, pos);
81 if (isInSVG) {
82 var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
83 var bbox = node.parentElement.getBBox();
84 rect.x.baseVal.value = bbox.x;
85 rect.y.baseVal.value = bbox.y;
86 rect.width.baseVal.value = bbox.width;
87 rect.height.baseVal.value = bbox.height;
88 rect.setAttribute('class', className);
89 addItems.push({
90 "parent": node.parentNode,
91 "target": rect});
92 }
93 }
94 }
95 else if (!jQuery(node).is("button, select, textarea")) {
96 jQuery.each(node.childNodes, function() {
97 highlight(this, addItems);
98 });
99 }
100 }
101 var addItems = [];
102 var result = this.each(function() {
103 highlight(this, addItems);
104 });
105 for (var i = 0; i < addItems.length; ++i) {
106 jQuery(addItems[i].parent).before(addItems[i].target);
107 }
108 return result;
109 };
110
111 /*
112 * backward compatibility for jQuery.browser
113 * This will be supported until firefox bug is fixed.
114 */
115 if (!jQuery.browser) {
116 jQuery.uaMatch = function(ua) {
117 ua = ua.toLowerCase();
118
119 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
120 /(webkit)[ \/]([\w.]+)/.exec(ua) ||
121 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
122 /(msie) ([\w.]+)/.exec(ua) ||
123 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
124 [];
125
126 return {
127 browser: match[ 1 ] || "",
128 version: match[ 2 ] || "0"
129 };
130 };
131 jQuery.browser = {};
132 jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
133 }
33 *
44 * Sphinx stylesheet -- basic theme.
55 *
6 * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
6 * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
77 * :license: BSD, see LICENSE for details.
88 *
99 */
1212
1313 div.clearer {
1414 clear: both;
15 }
16
17 div.section::after {
18 display: block;
19 content: '';
20 clear: left;
1521 }
1622
1723 /* -- relbar ---------------------------------------------------------------- */
5157 width: 230px;
5258 margin-left: -100%;
5359 font-size: 90%;
60 word-wrap: break-word;
61 overflow-wrap : break-word;
5462 }
5563
5664 div.sphinxsidebar ul {
7886 font-size: 1em;
7987 }
8088
89 div.sphinxsidebar #searchbox form.search {
90 overflow: hidden;
91 }
92
8193 div.sphinxsidebar #searchbox input[type="text"] {
82 width: 170px;
94 float: left;
95 width: 80%;
96 padding: 0.25em;
97 box-sizing: border-box;
8398 }
8499
85100 div.sphinxsidebar #searchbox input[type="submit"] {
86 width: 30px;
87 }
101 float: left;
102 width: 20%;
103 border-left: none;
104 padding: 0.25em;
105 box-sizing: border-box;
106 }
107
88108
89109 img {
90110 border: 0;
109129 font-weight: bold;
110130 }
111131
112 ul.search li div.context {
132 ul.search li p.context {
113133 color: #888;
114134 margin: 2px 0 0 30px;
115135 text-align: left;
123143
124144 table.contentstable {
125145 width: 90%;
146 margin-left: auto;
147 margin-right: auto;
126148 }
127149
128150 table.contentstable p.biglink {
150172 vertical-align: top;
151173 }
152174
153 table.indextable dl, table.indextable dd {
175 table.indextable ul {
154176 margin-top: 0;
155177 margin-bottom: 0;
178 list-style-type: none;
179 }
180
181 table.indextable > tbody > tr > td > ul {
182 padding-left: 0em;
156183 }
157184
158185 table.indextable tr.pcap {
184211 padding: 0.4em;
185212 }
186213
214 /* -- domain module index --------------------------------------------------- */
215
216 table.modindextable td {
217 padding: 2px;
218 border-collapse: collapse;
219 }
220
187221 /* -- general body styles --------------------------------------------------- */
222
223 div.body {
224 min-width: 360px;
225 max-width: 800px;
226 }
227
228 div.body p, div.body dd, div.body li, div.body blockquote {
229 -moz-hyphens: auto;
230 -ms-hyphens: auto;
231 -webkit-hyphens: auto;
232 hyphens: auto;
233 }
188234
189235 a.headerlink {
190236 visibility: hidden;
237 }
238
239 a.brackets:before,
240 span.brackets > a:before{
241 content: "[";
242 }
243
244 a.brackets:after,
245 span.brackets > a:after {
246 content: "]";
191247 }
192248
193249 h1:hover > a.headerlink,
211267 text-align: left;
212268 }
213269
214 .field-list ul {
215 padding-left: 1em;
216 }
217
218270 .first {
219271 margin-top: 0 !important;
220272 }
224276 font-weight: bold;
225277 }
226278
227 img.align-left, .figure.align-left, object.align-left {
279 img.align-left, figure.align-left, .figure.align-left, object.align-left {
228280 clear: left;
229281 float: left;
230282 margin-right: 1em;
231283 }
232284
233 img.align-right, .figure.align-right, object.align-right {
285 img.align-right, figure.align-right, .figure.align-right, object.align-right {
234286 clear: right;
235287 float: right;
236288 margin-left: 1em;
237289 }
238290
239 img.align-center, .figure.align-center, object.align-center {
291 img.align-center, figure.align-center, .figure.align-center, object.align-center {
240292 display: block;
241293 margin-left: auto;
242294 margin-right: auto;
243295 }
244296
297 img.align-default, figure.align-default, .figure.align-default {
298 display: block;
299 margin-left: auto;
300 margin-right: auto;
301 }
302
245303 .align-left {
246304 text-align: left;
247305 }
250308 text-align: center;
251309 }
252310
311 .align-default {
312 text-align: center;
313 }
314
253315 .align-right {
254316 text-align: right;
255317 }
256318
257319 /* -- sidebars -------------------------------------------------------------- */
258320
259 div.sidebar {
321 div.sidebar,
322 aside.sidebar {
260323 margin: 0 0 0.5em 1em;
261324 border: 1px solid #ddb;
262 padding: 7px 7px 0 7px;
325 padding: 7px;
263326 background-color: #ffe;
264327 width: 40%;
265328 float: right;
329 clear: right;
330 overflow-x: auto;
266331 }
267332
268333 p.sidebar-title {
269334 font-weight: bold;
270335 }
271336
337 div.admonition, div.topic, aside.topic, blockquote {
338 clear: left;
339 }
340
272341 /* -- topics ---------------------------------------------------------------- */
273342
274 div.topic {
343 div.topic, aside.topic {
275344 border: 1px solid #ccc;
276 padding: 7px 7px 0 7px;
345 padding: 7px;
277346 margin: 10px 0 10px 0;
278347 }
279348
295364 font-weight: bold;
296365 }
297366
298 div.admonition dl {
299 margin-bottom: 0;
300 }
301
302367 p.admonition-title {
303368 margin: 0px 10px 5px 0px;
304369 font-weight: bold;
309374 margin-top: 25px;
310375 }
311376
377 /* -- content of sidebars/topics/admonitions -------------------------------- */
378
379 div.sidebar > :last-child,
380 aside.sidebar > :last-child,
381 div.topic > :last-child,
382 aside.topic > :last-child,
383 div.admonition > :last-child {
384 margin-bottom: 0;
385 }
386
387 div.sidebar::after,
388 aside.sidebar::after,
389 div.topic::after,
390 aside.topic::after,
391 div.admonition::after,
392 blockquote::after {
393 display: block;
394 content: '';
395 clear: both;
396 }
397
312398 /* -- tables ---------------------------------------------------------------- */
313399
314400 table.docutils {
401 margin-top: 10px;
402 margin-bottom: 10px;
315403 border: 0;
316404 border-collapse: collapse;
405 }
406
407 table.align-center {
408 margin-left: auto;
409 margin-right: auto;
410 }
411
412 table.align-default {
413 margin-left: auto;
414 margin-right: auto;
317415 }
318416
319417 table caption span.caption-number {
331429 border-bottom: 1px solid #aaa;
332430 }
333431
334 table.field-list td, table.field-list th {
335 border: 0 !important;
336 }
337
338 table.footnote td, table.footnote th {
339 border: 0 !important;
340 }
341
342432 th {
343433 text-align: left;
344434 padding-right: 5px;
353443 border-bottom: none;
354444 }
355445
446 th > :first-child,
447 td > :first-child {
448 margin-top: 0px;
449 }
450
451 th > :last-child,
452 td > :last-child {
453 margin-bottom: 0px;
454 }
455
356456 /* -- figures --------------------------------------------------------------- */
357457
358 div.figure {
458 div.figure, figure {
359459 margin: 0.5em;
360460 padding: 0.5em;
361461 }
362462
363 div.figure p.caption {
463 div.figure p.caption, figcaption {
364464 padding: 0.3em;
365465 }
366466
367 div.figure p.caption span.caption-number {
467 div.figure p.caption span.caption-number,
468 figcaption span.caption-number {
368469 font-style: italic;
369470 }
370471
371 div.figure p.caption span.caption-text {
472 div.figure p.caption span.caption-text,
473 figcaption span.caption-text {
474 }
475
476 /* -- field list styles ----------------------------------------------------- */
477
478 table.field-list td, table.field-list th {
479 border: 0 !important;
480 }
481
482 .field-list ul {
483 margin: 0;
484 padding-left: 1em;
485 }
486
487 .field-list p {
488 margin: 0;
489 }
490
491 .field-name {
492 -moz-hyphens: manual;
493 -ms-hyphens: manual;
494 -webkit-hyphens: manual;
495 hyphens: manual;
496 }
497
498 /* -- hlist styles ---------------------------------------------------------- */
499
500 table.hlist {
501 margin: 1em 0;
502 }
503
504 table.hlist td {
505 vertical-align: top;
506 }
507
508 /* -- object description styles --------------------------------------------- */
509
510 .sig {
511 font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
512 }
513
514 .sig-name, code.descname {
515 background-color: transparent;
516 font-weight: bold;
517 }
518
519 .sig-name {
520 font-size: 1.1em;
521 }
522
523 code.descname {
524 font-size: 1.2em;
525 }
526
527 .sig-prename, code.descclassname {
528 background-color: transparent;
529 }
530
531 .optional {
532 font-size: 1.3em;
533 }
534
535 .sig-paren {
536 font-size: larger;
537 }
538
539 .sig-param.n {
540 font-style: italic;
541 }
542
543 /* C++ specific styling */
544
545 .sig-inline.c-texpr,
546 .sig-inline.cpp-texpr {
547 font-family: unset;
548 }
549
550 .sig.c .k, .sig.c .kt,
551 .sig.cpp .k, .sig.cpp .kt {
552 color: #0033B3;
553 }
554
555 .sig.c .m,
556 .sig.cpp .m {
557 color: #1750EB;
558 }
559
560 .sig.c .s, .sig.c .sc,
561 .sig.cpp .s, .sig.cpp .sc {
562 color: #067D17;
372563 }
373564
374565
394585 list-style: upper-roman;
395586 }
396587
588 :not(li) > ol > li:first-child > :first-child,
589 :not(li) > ul > li:first-child > :first-child {
590 margin-top: 0px;
591 }
592
593 :not(li) > ol > li:last-child > :last-child,
594 :not(li) > ul > li:last-child > :last-child {
595 margin-bottom: 0px;
596 }
597
598 ol.simple ol p,
599 ol.simple ul p,
600 ul.simple ol p,
601 ul.simple ul p {
602 margin-top: 0;
603 }
604
605 ol.simple > li:not(:first-child) > p,
606 ul.simple > li:not(:first-child) > p {
607 margin-top: 0;
608 }
609
610 ol.simple p,
611 ul.simple p {
612 margin-bottom: 0;
613 }
614
615 /* Docutils 0.17 and older (footnotes & citations) */
616 dl.footnote > dt,
617 dl.citation > dt {
618 float: left;
619 margin-right: 0.5em;
620 }
621
622 dl.footnote > dd,
623 dl.citation > dd {
624 margin-bottom: 0em;
625 }
626
627 dl.footnote > dd:after,
628 dl.citation > dd:after {
629 content: "";
630 clear: both;
631 }
632
633 /* Docutils 0.18+ (footnotes & citations) */
634 aside.footnote > span,
635 div.citation > span {
636 float: left;
637 }
638 aside.footnote > span:last-of-type,
639 div.citation > span:last-of-type {
640 padding-right: 0.5em;
641 }
642 aside.footnote > p {
643 margin-left: 2em;
644 }
645 div.citation > p {
646 margin-left: 4em;
647 }
648 aside.footnote > p:last-of-type,
649 div.citation > p:last-of-type {
650 margin-bottom: 0em;
651 }
652 aside.footnote > p:last-of-type:after,
653 div.citation > p:last-of-type:after {
654 content: "";
655 clear: both;
656 }
657
658 /* Footnotes & citations ends */
659
660 dl.field-list {
661 display: grid;
662 grid-template-columns: fit-content(30%) auto;
663 }
664
665 dl.field-list > dt {
666 font-weight: bold;
667 word-break: break-word;
668 padding-left: 0.5em;
669 padding-right: 5px;
670 }
671
672 dl.field-list > dt:after {
673 content: ":";
674 }
675
676 dl.field-list > dd {
677 padding-left: 0.5em;
678 margin-top: 0em;
679 margin-left: 0em;
680 margin-bottom: 0em;
681 }
682
397683 dl {
398684 margin-bottom: 15px;
399685 }
400686
401 dd p {
687 dd > :first-child {
402688 margin-top: 0px;
403689 }
404690
412698 margin-left: 30px;
413699 }
414700
415 dt:target, .highlighted {
701 dl > dd:last-child,
702 dl > dd:last-child > :last-child {
703 margin-bottom: 0;
704 }
705
706 dt:target, span.highlighted {
416707 background-color: #fbe54e;
417708 }
418709
710 rect.highlighted {
711 fill: #fbe54e;
712 }
713
419714 dl.glossary dt {
420715 font-weight: bold;
421716 font-size: 1.1em;
422 }
423
424 .field-list ul {
425 margin: 0;
426 padding-left: 1em;
427 }
428
429 .field-list p {
430 margin: 0;
431 }
432
433 .optional {
434 font-size: 1.3em;
435 }
436
437 .sig-paren {
438 font-size: larger;
439717 }
440718
441719 .versionmodified {
476754 font-style: oblique;
477755 }
478756
757 .classifier:before {
758 font-style: normal;
759 margin: 0 0.5em;
760 content: ":";
761 display: inline-block;
762 }
763
479764 abbr, acronym {
480765 border-bottom: dotted 1px;
481766 cursor: help;
488773 overflow-y: hidden; /* fixes display issues on Chrome browsers */
489774 }
490775
776 pre, div[class*="highlight-"] {
777 clear: both;
778 }
779
780 span.pre {
781 -moz-hyphens: none;
782 -ms-hyphens: none;
783 -webkit-hyphens: none;
784 hyphens: none;
785 white-space: nowrap;
786 }
787
788 div[class*="highlight-"] {
789 margin: 1em 0;
790 }
791
491792 td.linenos pre {
492 padding: 5px 0px;
493793 border: 0;
494794 background-color: transparent;
495795 color: #aaa;
496796 }
497797
498798 table.highlighttable {
499 margin-left: 0.5em;
799 display: block;
800 }
801
802 table.highlighttable tbody {
803 display: block;
804 }
805
806 table.highlighttable tr {
807 display: flex;
500808 }
501809
502810 table.highlighttable td {
503 padding: 0 0.5em 0 0.5em;
811 margin: 0;
812 padding: 0;
813 }
814
815 table.highlighttable td.linenos {
816 padding-right: 0.5em;
817 }
818
819 table.highlighttable td.code {
820 flex: 1;
821 overflow: hidden;
822 }
823
824 .highlight .hll {
825 display: block;
826 }
827
828 div.highlight pre,
829 table.highlighttable pre {
830 margin: 0;
831 }
832
833 div.code-block-caption + div {
834 margin-top: 0;
504835 }
505836
506837 div.code-block-caption {
838 margin-top: 1em;
507839 padding: 2px 5px;
508840 font-size: small;
509841 }
512844 background-color: transparent;
513845 }
514846
515 div.code-block-caption + div > div.highlight > pre {
516 margin-top: 0;
847 table.highlighttable td.linenos,
848 span.linenos,
849 div.highlight span.gp { /* gp: Generic.Prompt */
850 user-select: none;
851 -webkit-user-select: text; /* Safari fallback only */
852 -webkit-user-select: none; /* Chrome/Safari */
853 -moz-user-select: none; /* Firefox */
854 -ms-user-select: none; /* IE10+ */
517855 }
518856
519857 div.code-block-caption span.caption-number {
525863 }
526864
527865 div.literal-block-wrapper {
528 padding: 1em 1em 0;
529 }
530
531 div.literal-block-wrapper div.highlight {
532 margin: 0;
533 }
534
535 code.descname {
536 background-color: transparent;
537 font-weight: bold;
538 font-size: 1.2em;
539 }
540
541 code.descclassname {
542 background-color: transparent;
866 margin: 1em 0;
543867 }
544868
545869 code.xref, a code {
577901
578902 span.eqno {
579903 float: right;
904 }
905
906 span.eqno a.headerlink {
907 position: absolute;
908 z-index: 1;
909 }
910
911 div.math:hover a.headerlink {
912 visibility: visible;
580913 }
581914
582915 /* -- printout stylesheet --------------------------------------------------- */
11 * doctools.js
22 * ~~~~~~~~~~~
33 *
4 * Sphinx JavaScript utilities for all documentation.
4 * Base JavaScript utilities for all Sphinx HTML documentation.
55 *
6 * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
6 * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
77 * :license: BSD, see LICENSE for details.
88 *
99 */
10 "use strict";
11
12 const _ready = (callback) => {
13 if (document.readyState !== "loading") {
14 callback();
15 } else {
16 document.addEventListener("DOMContentLoaded", callback);
17 }
18 };
1019
1120 /**
12 * select a different prefix for underscore
13 */
14 $u = _.noConflict();
15
16 /**
17 * make the code below compatible with browsers without
18 * an installed firebug like debugger
19 if (!window.console || !console.firebug) {
20 var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
21 "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
22 "profile", "profileEnd"];
23 window.console = {};
24 for (var i = 0; i < names.length; ++i)
25 window.console[names[i]] = function() {};
26 }
27 */
28
29 /**
30 * small helper function to urldecode strings
31 */
32 jQuery.urldecode = function(x) {
33 return decodeURIComponent(x).replace(/\+/g, ' ');
34 };
35
36 /**
37 * small helper function to urlencode strings
38 */
39 jQuery.urlencode = encodeURIComponent;
40
41 /**
42 * This function returns the parsed url parameters of the
43 * current request. Multiple values per key are supported,
44 * it will always return arrays of strings for the value parts.
45 */
46 jQuery.getQueryParameters = function(s) {
47 if (typeof s == 'undefined')
48 s = document.location.search;
49 var parts = s.substr(s.indexOf('?') + 1).split('&');
50 var result = {};
51 for (var i = 0; i < parts.length; i++) {
52 var tmp = parts[i].split('=', 2);
53 var key = jQuery.urldecode(tmp[0]);
54 var value = jQuery.urldecode(tmp[1]);
55 if (key in result)
56 result[key].push(value);
57 else
58 result[key] = [value];
59 }
60 return result;
61 };
62
63 /**
64 * highlight a given string on a jquery object by wrapping it in
21 * highlight a given string on a node by wrapping it in
6522 * span elements with the given class name.
6623 */
67 jQuery.fn.highlightText = function(text, className) {
68 function highlight(node) {
69 if (node.nodeType == 3) {
70 var val = node.nodeValue;
71 var pos = val.toLowerCase().indexOf(text);
72 if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
73 var span = document.createElement("span");
74 span.className = className;
75 span.appendChild(document.createTextNode(val.substr(pos, text.length)));
76 node.parentNode.insertBefore(span, node.parentNode.insertBefore(
24 const _highlight = (node, addItems, text, className) => {
25 if (node.nodeType === Node.TEXT_NODE) {
26 const val = node.nodeValue;
27 const parent = node.parentNode;
28 const pos = val.toLowerCase().indexOf(text);
29 if (
30 pos >= 0 &&
31 !parent.classList.contains(className) &&
32 !parent.classList.contains("nohighlight")
33 ) {
34 let span;
35
36 const closestNode = parent.closest("body, svg, foreignObject");
37 const isInSVG = closestNode && closestNode.matches("svg");
38 if (isInSVG) {
39 span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
40 } else {
41 span = document.createElement("span");
42 span.classList.add(className);
43 }
44
45 span.appendChild(document.createTextNode(val.substr(pos, text.length)));
46 parent.insertBefore(
47 span,
48 parent.insertBefore(
7749 document.createTextNode(val.substr(pos + text.length)),
78 node.nextSibling));
79 node.nodeValue = val.substr(0, pos);
50 node.nextSibling
51 )
52 );
53 node.nodeValue = val.substr(0, pos);
54
55 if (isInSVG) {
56 const rect = document.createElementNS(
57 "http://www.w3.org/2000/svg",
58 "rect"
59 );
60 const bbox = parent.getBBox();
61 rect.x.baseVal.value = bbox.x;
62 rect.y.baseVal.value = bbox.y;
63 rect.width.baseVal.value = bbox.width;
64 rect.height.baseVal.value = bbox.height;
65 rect.setAttribute("class", className);
66 addItems.push({ parent: parent, target: rect });
8067 }
8168 }
82 else if (!jQuery(node).is("button, select, textarea")) {
83 jQuery.each(node.childNodes, function() {
84 highlight(this);
85 });
86 }
69 } else if (node.matches && !node.matches("button, select, textarea")) {
70 node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
8771 }
88 return this.each(function() {
89 highlight(this);
90 });
91 };
92
93 /*
94 * backward compatibility for jQuery.browser
95 * This will be supported until firefox bug is fixed.
96 */
97 if (!jQuery.browser) {
98 jQuery.uaMatch = function(ua) {
99 ua = ua.toLowerCase();
100
101 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
102 /(webkit)[ \/]([\w.]+)/.exec(ua) ||
103 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
104 /(msie) ([\w.]+)/.exec(ua) ||
105 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
106 [];
107
108 return {
109 browser: match[ 1 ] || "",
110 version: match[ 2 ] || "0"
111 };
112 };
113 jQuery.browser = {};
114 jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
115 }
72 };
73 const _highlightText = (thisNode, text, className) => {
74 let addItems = [];
75 _highlight(thisNode, addItems, text, className);
76 addItems.forEach((obj) =>
77 obj.parent.insertAdjacentElement("beforebegin", obj.target)
78 );
79 };
11680
11781 /**
11882 * Small JavaScript module for the documentation.
11983 */
120 var Documentation = {
121
122 init : function() {
123 this.fixFirefoxAnchorBug();
124 this.highlightSearchWords();
125 this.initIndexTable();
84 const Documentation = {
85 init: () => {
86 Documentation.highlightSearchWords();
87 Documentation.initDomainIndexTable();
88 Documentation.initOnKeyListeners();
12689 },
12790
12891 /**
12992 * i18n support
13093 */
131 TRANSLATIONS : {},
132 PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
133 LOCALE : 'unknown',
94 TRANSLATIONS: {},
95 PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
96 LOCALE: "unknown",
13497
13598 // gettext and ngettext don't access this so that the functions
13699 // can safely bound to a different name (_ = Documentation.gettext)
137 gettext : function(string) {
138 var translated = Documentation.TRANSLATIONS[string];
139 if (typeof translated == 'undefined')
140 return string;
141 return (typeof translated == 'string') ? translated : translated[0];
142 },
143
144 ngettext : function(singular, plural, n) {
145 var translated = Documentation.TRANSLATIONS[singular];
146 if (typeof translated == 'undefined')
147 return (n == 1) ? singular : plural;
148 return translated[Documentation.PLURALEXPR(n)];
149 },
150
151 addTranslations : function(catalog) {
152 for (var key in catalog.messages)
153 this.TRANSLATIONS[key] = catalog.messages[key];
154 this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
155 this.LOCALE = catalog.locale;
156 },
157
158 /**
159 * add context elements like header anchor links
160 */
161 addContextElements : function() {
162 $('div[id] > :header:first').each(function() {
163 $('<a class="headerlink">\u00B6</a>').
164 attr('href', '#' + this.id).
165 attr('title', _('Permalink to this headline')).
166 appendTo(this);
100 gettext: (string) => {
101 const translated = Documentation.TRANSLATIONS[string];
102 switch (typeof translated) {
103 case "undefined":
104 return string; // no translation
105 case "string":
106 return translated; // translation exists
107 default:
108 return translated[0]; // (singular, plural) translation tuple exists
109 }
110 },
111
112 ngettext: (singular, plural, n) => {
113 const translated = Documentation.TRANSLATIONS[singular];
114 if (typeof translated !== "undefined")
115 return translated[Documentation.PLURAL_EXPR(n)];
116 return n === 1 ? singular : plural;
117 },
118
119 addTranslations: (catalog) => {
120 Object.assign(Documentation.TRANSLATIONS, catalog.messages);
121 Documentation.PLURAL_EXPR = new Function(
122 "n",
123 `return (${catalog.plural_expr})`
124 );
125 Documentation.LOCALE = catalog.locale;
126 },
127
128 /**
129 * highlight the search words provided in the url in the text
130 */
131 highlightSearchWords: () => {
132 const highlight =
133 new URLSearchParams(window.location.search).get("highlight") || "";
134 const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
135 if (terms.length === 0) return; // nothing to do
136
137 // There should never be more than one element matching "div.body"
138 const divBody = document.querySelectorAll("div.body");
139 const body = divBody.length ? divBody[0] : document.querySelector("body");
140 window.setTimeout(() => {
141 terms.forEach((term) => _highlightText(body, term, "highlighted"));
142 }, 10);
143
144 const searchBox = document.getElementById("searchbox");
145 if (searchBox === null) return;
146 searchBox.appendChild(
147 document
148 .createRange()
149 .createContextualFragment(
150 '<p class="highlight-link">' +
151 '<a href="javascript:Documentation.hideSearchWords()">' +
152 Documentation.gettext("Hide Search Matches") +
153 "</a></p>"
154 )
155 );
156 },
157
158 /**
159 * helper function to hide the search marks again
160 */
161 hideSearchWords: () => {
162 document
163 .querySelectorAll("#searchbox .highlight-link")
164 .forEach((el) => el.remove());
165 document
166 .querySelectorAll("span.highlighted")
167 .forEach((el) => el.classList.remove("highlighted"));
168 const url = new URL(window.location);
169 url.searchParams.delete("highlight");
170 window.history.replaceState({}, "", url);
171 },
172
173 /**
174 * helper function to focus on search bar
175 */
176 focusSearchBar: () => {
177 document.querySelectorAll("input[name=q]")[0]?.focus();
178 },
179
180 /**
181 * Initialise the domain index toggle buttons
182 */
183 initDomainIndexTable: () => {
184 const toggler = (el) => {
185 const idNumber = el.id.substr(7);
186 const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
187 if (el.src.substr(-9) === "minus.png") {
188 el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
189 toggledRows.forEach((el) => (el.style.display = "none"));
190 } else {
191 el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
192 toggledRows.forEach((el) => (el.style.display = ""));
193 }
194 };
195
196 const togglerElements = document.querySelectorAll("img.toggler");
197 togglerElements.forEach((el) =>
198 el.addEventListener("click", (event) => toggler(event.currentTarget))
199 );
200 togglerElements.forEach((el) => (el.style.display = ""));
201 if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
202 },
203
204 initOnKeyListeners: () => {
205 // only install a listener if it is really needed
206 if (
207 !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
208 !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
209 )
210 return;
211
212 const blacklistedElements = new Set([
213 "TEXTAREA",
214 "INPUT",
215 "SELECT",
216 "BUTTON",
217 ]);
218 document.addEventListener("keydown", (event) => {
219 if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements
220 if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys
221
222 if (!event.shiftKey) {
223 switch (event.key) {
224 case "ArrowLeft":
225 if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
226
227 const prevLink = document.querySelector('link[rel="prev"]');
228 if (prevLink && prevLink.href) {
229 window.location.href = prevLink.href;
230 event.preventDefault();
231 }
232 break;
233 case "ArrowRight":
234 if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
235
236 const nextLink = document.querySelector('link[rel="next"]');
237 if (nextLink && nextLink.href) {
238 window.location.href = nextLink.href;
239 event.preventDefault();
240 }
241 break;
242 case "Escape":
243 if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
244 Documentation.hideSearchWords();
245 event.preventDefault();
246 }
247 }
248
249 // some keyboard layouts may need Shift to get /
250 switch (event.key) {
251 case "/":
252 if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
253 Documentation.focusSearchBar();
254 event.preventDefault();
255 }
167256 });
168 $('dt[id]').each(function() {
169 $('<a class="headerlink">\u00B6</a>').
170 attr('href', '#' + this.id).
171 attr('title', _('Permalink to this definition')).
172 appendTo(this);
173 });
174 },
175
176 /**
177 * workaround a firefox stupidity
178 * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
179 */
180 fixFirefoxAnchorBug : function() {
181 if (document.location.hash)
182 window.setTimeout(function() {
183 document.location.href += '';
184 }, 10);
185 },
186
187 /**
188 * highlight the search words provided in the url in the text
189 */
190 highlightSearchWords : function() {
191 var params = $.getQueryParameters();
192 var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
193 if (terms.length) {
194 var body = $('div.body');
195 if (!body.length) {
196 body = $('body');
197 }
198 window.setTimeout(function() {
199 $.each(terms, function() {
200 body.highlightText(this.toLowerCase(), 'highlighted');
201 });
202 }, 10);
203 $('<p class="highlight-link"><a href="javascript:Documentation.' +
204 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
205 .appendTo($('#searchbox'));
206 }
207 },
208
209 /**
210 * init the domain index toggle buttons
211 */
212 initIndexTable : function() {
213 var togglers = $('img.toggler').click(function() {
214 var src = $(this).attr('src');
215 var idnum = $(this).attr('id').substr(7);
216 $('tr.cg-' + idnum).toggle();
217 if (src.substr(-9) == 'minus.png')
218 $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
219 else
220 $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
221 }).css('display', '');
222 if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
223 togglers.click();
224 }
225 },
226
227 /**
228 * helper function to hide the search marks again
229 */
230 hideSearchWords : function() {
231 $('#searchbox .highlight-link').fadeOut(300);
232 $('span.highlighted').removeClass('highlighted');
233 },
234
235 /**
236 * make the url absolute
237 */
238 makeURL : function(relativeURL) {
239 return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
240 },
241
242 /**
243 * get the current relative url
244 */
245 getCurrentURL : function() {
246 var path = document.location.pathname;
247 var parts = path.split(/\//);
248 $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
249 if (this == '..')
250 parts.pop();
251 });
252 var url = parts.join('/');
253 return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
254 }
257 },
255258 };
256259
257260 // quick alias for translations
258 _ = Documentation.gettext;
259
260 $(document).ready(function() {
261 Documentation.init();
262 });
261 const _ = Documentation.gettext;
262
263 _ready(Documentation.init);
0 var DOCUMENTATION_OPTIONS = {
1 URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
2 VERSION: '1.2.8',
3 LANGUAGE: 'en',
4 COLLAPSE_INDEX: false,
5 BUILDER: 'html',
6 FILE_SUFFIX: '.html',
7 LINK_SUFFIX: '.html',
8 HAS_SOURCE: true,
9 SOURCELINK_SUFFIX: '.txt',
10 NAVIGATION_WITH_KEYS: false,
11 SHOW_SEARCH_SUMMARY: true,
12 ENABLE_SEARCH_SHORTCUTS: false,
13 };
Binary diff not shown
0 /*!
1 * jQuery JavaScript Library v3.5.1
2 * https://jquery.com/
3 *
4 * Includes Sizzle.js
5 * https://sizzlejs.com/
6 *
7 * Copyright JS Foundation and other contributors
8 * Released under the MIT license
9 * https://jquery.org/license
10 *
11 * Date: 2020-05-04T22:49Z
12 */
13 ( function( global, factory ) {
14
15 "use strict";
16
17 if ( typeof module === "object" && typeof module.exports === "object" ) {
18
19 // For CommonJS and CommonJS-like environments where a proper `window`
20 // is present, execute the factory and get jQuery.
21 // For environments that do not have a `window` with a `document`
22 // (such as Node.js), expose a factory as module.exports.
23 // This accentuates the need for the creation of a real `window`.
24 // e.g. var jQuery = require("jquery")(window);
25 // See ticket #14549 for more info.
26 module.exports = global.document ?
27 factory( global, true ) :
28 function( w ) {
29 if ( !w.document ) {
30 throw new Error( "jQuery requires a window with a document" );
31 }
32 return factory( w );
33 };
34 } else {
35 factory( global );
36 }
37
38 // Pass this if window is not defined yet
39 } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
40
41 // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
42 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
43 // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
44 // enough that all such attempts are guarded in a try block.
45 "use strict";
46
47 var arr = [];
48
49 var getProto = Object.getPrototypeOf;
50
51 var slice = arr.slice;
52
53 var flat = arr.flat ? function( array ) {
54 return arr.flat.call( array );
55 } : function( array ) {
56 return arr.concat.apply( [], array );
57 };
58
59
60 var push = arr.push;
61
62 var indexOf = arr.indexOf;
63
64 var class2type = {};
65
66 var toString = class2type.toString;
67
68 var hasOwn = class2type.hasOwnProperty;
69
70 var fnToString = hasOwn.toString;
71
72 var ObjectFunctionString = fnToString.call( Object );
73
74 var support = {};
75
76 var isFunction = function isFunction( obj ) {
77
78 // Support: Chrome <=57, Firefox <=52
79 // In some browsers, typeof returns "function" for HTML <object> elements
80 // (i.e., `typeof document.createElement( "object" ) === "function"`).
81 // We don't want to classify *any* DOM node as a function.
82 return typeof obj === "function" && typeof obj.nodeType !== "number";
83 };
84
85
86 var isWindow = function isWindow( obj ) {
87 return obj != null && obj === obj.window;
88 };
89
90
91 var document = window.document;
92
93
94
95 var preservedScriptAttributes = {
96 type: true,
97 src: true,
98 nonce: true,
99 noModule: true
100 };
101
102 function DOMEval( code, node, doc ) {
103 doc = doc || document;
104
105 var i, val,
106 script = doc.createElement( "script" );
107
108 script.text = code;
109 if ( node ) {
110 for ( i in preservedScriptAttributes ) {
111
112 // Support: Firefox 64+, Edge 18+
113 // Some browsers don't support the "nonce" property on scripts.
114 // On the other hand, just using `getAttribute` is not enough as
115 // the `nonce` attribute is reset to an empty string whenever it
116 // becomes browsing-context connected.
117 // See https://github.com/whatwg/html/issues/2369
118 // See https://html.spec.whatwg.org/#nonce-attributes
119 // The `node.getAttribute` check was added for the sake of
120 // `jQuery.globalEval` so that it can fake a nonce-containing node
121 // via an object.
122 val = node[ i ] || node.getAttribute && node.getAttribute( i );
123 if ( val ) {
124 script.setAttribute( i, val );
125 }
126 }
127 }
128 doc.head.appendChild( script ).parentNode.removeChild( script );
129 }
130
131
132 function toType( obj ) {
133 if ( obj == null ) {
134 return obj + "";
135 }
136
137 // Support: Android <=2.3 only (functionish RegExp)
138 return typeof obj === "object" || typeof obj === "function" ?
139 class2type[ toString.call( obj ) ] || "object" :
140 typeof obj;
141 }
142 /* global Symbol */
143 // Defining this global in .eslintrc.json would create a danger of using the global
144 // unguarded in another place, it seems safer to define global only for this module
145
146
147
148 var
149 version = "3.5.1",
150
151 // Define a local copy of jQuery
152 jQuery = function( selector, context ) {
153
154 // The jQuery object is actually just the init constructor 'enhanced'
155 // Need init if jQuery is called (just allow error to be thrown if not included)
156 return new jQuery.fn.init( selector, context );
157 };
158
159 jQuery.fn = jQuery.prototype = {
160
161 // The current version of jQuery being used
162 jquery: version,
163
164 constructor: jQuery,
165
166 // The default length of a jQuery object is 0
167 length: 0,
168
169 toArray: function() {
170 return slice.call( this );
171 },
172
173 // Get the Nth element in the matched element set OR
174 // Get the whole matched element set as a clean array
175 get: function( num ) {
176
177 // Return all the elements in a clean array
178 if ( num == null ) {
179 return slice.call( this );
180 }
181
182 // Return just the one element from the set
183 return num < 0 ? this[ num + this.length ] : this[ num ];
184 },
185
186 // Take an array of elements and push it onto the stack
187 // (returning the new matched element set)
188 pushStack: function( elems ) {
189
190 // Build a new jQuery matched element set
191 var ret = jQuery.merge( this.constructor(), elems );
192
193 // Add the old object onto the stack (as a reference)
194 ret.prevObject = this;
195
196 // Return the newly-formed element set
197 return ret;
198 },
199
200 // Execute a callback for every element in the matched set.
201 each: function( callback ) {
202 return jQuery.each( this, callback );
203 },
204
205 map: function( callback ) {
206 return this.pushStack( jQuery.map( this, function( elem, i ) {
207 return callback.call( elem, i, elem );
208 } ) );
209 },
210
211 slice: function() {
212 return this.pushStack( slice.apply( this, arguments ) );
213 },
214
215 first: function() {
216 return this.eq( 0 );
217 },
218
219 last: function() {
220 return this.eq( -1 );
221 },
222
223 even: function() {
224 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
225 return ( i + 1 ) % 2;
226 } ) );
227 },
228
229 odd: function() {
230 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
231 return i % 2;
232 } ) );
233 },
234
235 eq: function( i ) {
236 var len = this.length,
237 j = +i + ( i < 0 ? len : 0 );
238 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
239 },
240
241 end: function() {
242 return this.prevObject || this.constructor();
243 },
244
245 // For internal use only.
246 // Behaves like an Array's method, not like a jQuery method.
247 push: push,
248 sort: arr.sort,
249 splice: arr.splice
250 };
251
252 jQuery.extend = jQuery.fn.extend = function() {
253 var options, name, src, copy, copyIsArray, clone,
254 target = arguments[ 0 ] || {},
255 i = 1,
256 length = arguments.length,
257 deep = false;
258
259 // Handle a deep copy situation
260 if ( typeof target === "boolean" ) {
261 deep = target;
262
263 // Skip the boolean and the target
264 target = arguments[ i ] || {};
265 i++;
266 }
267
268 // Handle case when target is a string or something (possible in deep copy)
269 if ( typeof target !== "object" && !isFunction( target ) ) {
270 target = {};
271 }
272
273 // Extend jQuery itself if only one argument is passed
274 if ( i === length ) {
275 target = this;
276 i--;
277 }
278
279 for ( ; i < length; i++ ) {
280
281 // Only deal with non-null/undefined values
282 if ( ( options = arguments[ i ] ) != null ) {
283
284 // Extend the base object
285 for ( name in options ) {
286 copy = options[ name ];
287
288 // Prevent Object.prototype pollution
289 // Prevent never-ending loop
290 if ( name === "__proto__" || target === copy ) {
291 continue;
292 }
293
294 // Recurse if we're merging plain objects or arrays
295 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
296 ( copyIsArray = Array.isArray( copy ) ) ) ) {
297 src = target[ name ];
298
299 // Ensure proper type for the source value
300 if ( copyIsArray && !Array.isArray( src ) ) {
301 clone = [];
302 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
303 clone = {};
304 } else {
305 clone = src;
306 }
307 copyIsArray = false;
308
309 // Never move original objects, clone them
310 target[ name ] = jQuery.extend( deep, clone, copy );
311
312 // Don't bring in undefined values
313 } else if ( copy !== undefined ) {
314 target[ name ] = copy;
315 }
316 }
317 }
318 }
319
320 // Return the modified object
321 return target;
322 };
323
324 jQuery.extend( {
325
326 // Unique for each copy of jQuery on the page
327 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
328
329 // Assume jQuery is ready without the ready module
330 isReady: true,
331
332 error: function( msg ) {
333 throw new Error( msg );
334 },
335
336 noop: function() {},
337
338 isPlainObject: function( obj ) {
339 var proto, Ctor;
340
341 // Detect obvious negatives
342 // Use toString instead of jQuery.type to catch host objects
343 if ( !obj || toString.call( obj ) !== "[object Object]" ) {
344 return false;
345 }
346
347 proto = getProto( obj );
348
349 // Objects with no prototype (e.g., `Object.create( null )`) are plain
350 if ( !proto ) {
351 return true;
352 }
353
354 // Objects with prototype are plain iff they were constructed by a global Object function
355 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
356 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
357 },
358
359 isEmptyObject: function( obj ) {
360 var name;
361
362 for ( name in obj ) {
363 return false;
364 }
365 return true;
366 },
367
368 // Evaluates a script in a provided context; falls back to the global one
369 // if not specified.
370 globalEval: function( code, options, doc ) {
371 DOMEval( code, { nonce: options && options.nonce }, doc );
372 },
373
374 each: function( obj, callback ) {
375 var length, i = 0;
376
377 if ( isArrayLike( obj ) ) {
378 length = obj.length;
379 for ( ; i < length; i++ ) {
380 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
381 break;
382 }
383 }
384 } else {
385 for ( i in obj ) {
386 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
387 break;
388 }
389 }
390 }
391
392 return obj;
393 },
394
395 // results is for internal usage only
396 makeArray: function( arr, results ) {
397 var ret = results || [];
398
399 if ( arr != null ) {
400 if ( isArrayLike( Object( arr ) ) ) {
401 jQuery.merge( ret,
402 typeof arr === "string" ?
403 [ arr ] : arr
404 );
405 } else {
406 push.call( ret, arr );
407 }
408 }
409
410 return ret;
411 },
412
413 inArray: function( elem, arr, i ) {
414 return arr == null ? -1 : indexOf.call( arr, elem, i );
415 },
416
417 // Support: Android <=4.0 only, PhantomJS 1 only
418 // push.apply(_, arraylike) throws on ancient WebKit
419 merge: function( first, second ) {
420 var len = +second.length,
421 j = 0,
422 i = first.length;
423
424 for ( ; j < len; j++ ) {
425 first[ i++ ] = second[ j ];
426 }
427
428 first.length = i;
429
430 return first;
431 },
432
433 grep: function( elems, callback, invert ) {
434 var callbackInverse,
435 matches = [],
436 i = 0,
437 length = elems.length,
438 callbackExpect = !invert;
439
440 // Go through the array, only saving the items
441 // that pass the validator function
442 for ( ; i < length; i++ ) {
443 callbackInverse = !callback( elems[ i ], i );
444 if ( callbackInverse !== callbackExpect ) {
445 matches.push( elems[ i ] );
446 }
447 }
448
449 return matches;
450 },
451
452 // arg is for internal usage only
453 map: function( elems, callback, arg ) {
454 var length, value,
455 i = 0,
456 ret = [];
457
458 // Go through the array, translating each of the items to their new values
459 if ( isArrayLike( elems ) ) {
460 length = elems.length;
461 for ( ; i < length; i++ ) {
462 value = callback( elems[ i ], i, arg );
463
464 if ( value != null ) {
465 ret.push( value );
466 }
467 }
468
469 // Go through every key on the object,
470 } else {
471 for ( i in elems ) {
472 value = callback( elems[ i ], i, arg );
473
474 if ( value != null ) {
475 ret.push( value );
476 }
477 }
478 }
479
480 // Flatten any nested arrays
481 return flat( ret );
482 },
483
484 // A global GUID counter for objects
485 guid: 1,
486
487 // jQuery.support is not used in Core but other projects attach their
488 // properties to it so it needs to exist.
489 support: support
490 } );
491
492 if ( typeof Symbol === "function" ) {
493 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
494 }
495
496 // Populate the class2type map
497 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
498 function( _i, name ) {
499 class2type[ "[object " + name + "]" ] = name.toLowerCase();
500 } );
501
502 function isArrayLike( obj ) {
503
504 // Support: real iOS 8.2 only (not reproducible in simulator)
505 // `in` check used to prevent JIT error (gh-2145)
506 // hasOwn isn't used here due to false negatives
507 // regarding Nodelist length in IE
508 var length = !!obj && "length" in obj && obj.length,
509 type = toType( obj );
510
511 if ( isFunction( obj ) || isWindow( obj ) ) {
512 return false;
513 }
514
515 return type === "array" || length === 0 ||
516 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
517 }
518 var Sizzle =
519 /*!
520 * Sizzle CSS Selector Engine v2.3.5
521 * https://sizzlejs.com/
522 *
523 * Copyright JS Foundation and other contributors
524 * Released under the MIT license
525 * https://js.foundation/
526 *
527 * Date: 2020-03-14
528 */
529 ( function( window ) {
530 var i,
531 support,
532 Expr,
533 getText,
534 isXML,
535 tokenize,
536 compile,
537 select,
538 outermostContext,
539 sortInput,
540 hasDuplicate,
541
542 // Local document vars
543 setDocument,
544 document,
545 docElem,
546 documentIsHTML,
547 rbuggyQSA,
548 rbuggyMatches,
549 matches,
550 contains,
551
552 // Instance-specific data
553 expando = "sizzle" + 1 * new Date(),
554 preferredDoc = window.document,
555 dirruns = 0,
556 done = 0,
557 classCache = createCache(),
558 tokenCache = createCache(),
559 compilerCache = createCache(),
560 nonnativeSelectorCache = createCache(),
561 sortOrder = function( a, b ) {
562 if ( a === b ) {
563 hasDuplicate = true;
564 }
565 return 0;
566 },
567
568 // Instance methods
569 hasOwn = ( {} ).hasOwnProperty,
570 arr = [],
571 pop = arr.pop,
572 pushNative = arr.push,
573 push = arr.push,
574 slice = arr.slice,
575
576 // Use a stripped-down indexOf as it's faster than native
577 // https://jsperf.com/thor-indexof-vs-for/5
578 indexOf = function( list, elem ) {
579 var i = 0,
580 len = list.length;
581 for ( ; i < len; i++ ) {
582 if ( list[ i ] === elem ) {
583 return i;
584 }
585 }
586 return -1;
587 },
588
589 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
590 "ismap|loop|multiple|open|readonly|required|scoped",
591
592 // Regular expressions
593
594 // http://www.w3.org/TR/css3-selectors/#whitespace
595 whitespace = "[\\x20\\t\\r\\n\\f]",
596
597 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
598 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
599 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
600
601 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
602 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
603
604 // Operator (capture 2)
605 "*([*^$|!~]?=)" + whitespace +
606
607 // "Attribute values must be CSS identifiers [capture 5]
608 // or strings [capture 3 or capture 4]"
609 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
610 whitespace + "*\\]",
611
612 pseudos = ":(" + identifier + ")(?:\\((" +
613
614 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
615 // 1. quoted (capture 3; capture 4 or capture 5)
616 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
617
618 // 2. simple (capture 6)
619 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
620
621 // 3. anything else (capture 2)
622 ".*" +
623 ")\\)|)",
624
625 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
626 rwhitespace = new RegExp( whitespace + "+", "g" ),
627 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
628 whitespace + "+$", "g" ),
629
630 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
631 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
632 "*" ),
633 rdescend = new RegExp( whitespace + "|>" ),
634
635 rpseudo = new RegExp( pseudos ),
636 ridentifier = new RegExp( "^" + identifier + "$" ),
637
638 matchExpr = {
639 "ID": new RegExp( "^#(" + identifier + ")" ),
640 "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
641 "TAG": new RegExp( "^(" + identifier + "|[*])" ),
642 "ATTR": new RegExp( "^" + attributes ),
643 "PSEUDO": new RegExp( "^" + pseudos ),
644 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
645 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
646 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
647 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
648
649 // For use in libraries implementing .is()
650 // We use this for POS matching in `select`
651 "needsContext": new RegExp( "^" + whitespace +
652 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
653 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
654 },
655
656 rhtml = /HTML$/i,
657 rinputs = /^(?:input|select|textarea|button)$/i,
658 rheader = /^h\d$/i,
659
660 rnative = /^[^{]+\{\s*\[native \w/,
661
662 // Easily-parseable/retrievable ID or TAG or CLASS selectors
663 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
664
665 rsibling = /[+~]/,
666
667 // CSS escapes
668 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
669 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
670 funescape = function( escape, nonHex ) {
671 var high = "0x" + escape.slice( 1 ) - 0x10000;
672
673 return nonHex ?
674
675 // Strip the backslash prefix from a non-hex escape sequence
676 nonHex :
677
678 // Replace a hexadecimal escape sequence with the encoded Unicode code point
679 // Support: IE <=11+
680 // For values outside the Basic Multilingual Plane (BMP), manually construct a
681 // surrogate pair
682 high < 0 ?
683 String.fromCharCode( high + 0x10000 ) :
684 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
685 },
686
687 // CSS string/identifier serialization
688 // https://drafts.csswg.org/cssom/#common-serializing-idioms
689 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
690 fcssescape = function( ch, asCodePoint ) {
691 if ( asCodePoint ) {
692
693 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
694 if ( ch === "\0" ) {
695 return "\uFFFD";
696 }
697
698 // Control characters and (dependent upon position) numbers get escaped as code points
699 return ch.slice( 0, -1 ) + "\\" +
700 ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
701 }
702
703 // Other potentially-special ASCII characters get backslash-escaped
704 return "\\" + ch;
705 },
706
707 // Used for iframes
708 // See setDocument()
709 // Removing the function wrapper causes a "Permission Denied"
710 // error in IE
711 unloadHandler = function() {
712 setDocument();
713 },
714
715 inDisabledFieldset = addCombinator(
716 function( elem ) {
717 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
718 },
719 { dir: "parentNode", next: "legend" }
720 );
721
722 // Optimize for push.apply( _, NodeList )
723 try {
724 push.apply(
725 ( arr = slice.call( preferredDoc.childNodes ) ),
726 preferredDoc.childNodes
727 );
728
729 // Support: Android<4.0
730 // Detect silently failing push.apply
731 // eslint-disable-next-line no-unused-expressions
732 arr[ preferredDoc.childNodes.length ].nodeType;
733 } catch ( e ) {
734 push = { apply: arr.length ?
735
736 // Leverage slice if possible
737 function( target, els ) {
738 pushNative.apply( target, slice.call( els ) );
739 } :
740
741 // Support: IE<9
742 // Otherwise append directly
743 function( target, els ) {
744 var j = target.length,
745 i = 0;
746
747 // Can't trust NodeList.length
748 while ( ( target[ j++ ] = els[ i++ ] ) ) {}
749 target.length = j - 1;
750 }
751 };
752 }
753
754 function Sizzle( selector, context, results, seed ) {
755 var m, i, elem, nid, match, groups, newSelector,
756 newContext = context && context.ownerDocument,
757
758 // nodeType defaults to 9, since context defaults to document
759 nodeType = context ? context.nodeType : 9;
760
761 results = results || [];
762
763 // Return early from calls with invalid selector or context
764 if ( typeof selector !== "string" || !selector ||
765 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
766
767 return results;
768 }
769
770 // Try to shortcut find operations (as opposed to filters) in HTML documents
771 if ( !seed ) {
772 setDocument( context );
773 context = context || document;
774
775 if ( documentIsHTML ) {
776
777 // If the selector is sufficiently simple, try using a "get*By*" DOM method
778 // (excepting DocumentFragment context, where the methods don't exist)
779 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
780
781 // ID selector
782 if ( ( m = match[ 1 ] ) ) {
783
784 // Document context
785 if ( nodeType === 9 ) {
786 if ( ( elem = context.getElementById( m ) ) ) {
787
788 // Support: IE, Opera, Webkit
789 // TODO: identify versions
790 // getElementById can match elements by name instead of ID
791 if ( elem.id === m ) {
792 results.push( elem );
793 return results;
794 }
795 } else {
796 return results;
797 }
798
799 // Element context
800 } else {
801
802 // Support: IE, Opera, Webkit
803 // TODO: identify versions
804 // getElementById can match elements by name instead of ID
805 if ( newContext && ( elem = newContext.getElementById( m ) ) &&
806 contains( context, elem ) &&
807 elem.id === m ) {
808
809 results.push( elem );
810 return results;
811 }
812 }
813
814 // Type selector
815 } else if ( match[ 2 ] ) {
816 push.apply( results, context.getElementsByTagName( selector ) );
817 return results;
818
819 // Class selector
820 } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
821 context.getElementsByClassName ) {
822
823 push.apply( results, context.getElementsByClassName( m ) );
824 return results;
825 }
826 }
827
828 // Take advantage of querySelectorAll
829 if ( support.qsa &&
830 !nonnativeSelectorCache[ selector + " " ] &&
831 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
832
833 // Support: IE 8 only
834 // Exclude object elements
835 ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
836
837 newSelector = selector;
838 newContext = context;
839
840 // qSA considers elements outside a scoping root when evaluating child or
841 // descendant combinators, which is not what we want.
842 // In such cases, we work around the behavior by prefixing every selector in the
843 // list with an ID selector referencing the scope context.
844 // The technique has to be used as well when a leading combinator is used
845 // as such selectors are not recognized by querySelectorAll.
846 // Thanks to Andrew Dupont for this technique.
847 if ( nodeType === 1 &&
848 ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
849
850 // Expand context for sibling selectors
851 newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
852 context;
853
854 // We can use :scope instead of the ID hack if the browser
855 // supports it & if we're not changing the context.
856 if ( newContext !== context || !support.scope ) {
857
858 // Capture the context ID, setting it first if necessary
859 if ( ( nid = context.getAttribute( "id" ) ) ) {
860 nid = nid.replace( rcssescape, fcssescape );
861 } else {
862 context.setAttribute( "id", ( nid = expando ) );
863 }
864 }
865
866 // Prefix every selector in the list
867 groups = tokenize( selector );
868 i = groups.length;
869 while ( i-- ) {
870 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
871 toSelector( groups[ i ] );
872 }
873 newSelector = groups.join( "," );
874 }
875
876 try {
877 push.apply( results,
878 newContext.querySelectorAll( newSelector )
879 );
880 return results;
881 } catch ( qsaError ) {
882 nonnativeSelectorCache( selector, true );
883 } finally {
884 if ( nid === expando ) {
885 context.removeAttribute( "id" );
886 }
887 }
888 }
889 }
890 }
891
892 // All others
893 return select( selector.replace( rtrim, "$1" ), context, results, seed );
894 }
895
896 /**
897 * Create key-value caches of limited size
898 * @returns {function(string, object)} Returns the Object data after storing it on itself with
899 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
900 * deleting the oldest entry
901 */
902 function createCache() {
903 var keys = [];
904
905 function cache( key, value ) {
906
907 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
908 if ( keys.push( key + " " ) > Expr.cacheLength ) {
909
910 // Only keep the most recent entries
911 delete cache[ keys.shift() ];
912 }
913 return ( cache[ key + " " ] = value );
914 }
915 return cache;
916 }
917
918 /**
919 * Mark a function for special use by Sizzle
920 * @param {Function} fn The function to mark
921 */
922 function markFunction( fn ) {
923 fn[ expando ] = true;
924 return fn;
925 }
926
927 /**
928 * Support testing using an element
929 * @param {Function} fn Passed the created element and returns a boolean result
930 */
931 function assert( fn ) {
932 var el = document.createElement( "fieldset" );
933
934 try {
935 return !!fn( el );
936 } catch ( e ) {
937 return false;
938 } finally {
939
940 // Remove from its parent by default
941 if ( el.parentNode ) {
942 el.parentNode.removeChild( el );
943 }
944
945 // release memory in IE
946 el = null;
947 }
948 }
949
950 /**
951 * Adds the same handler for all of the specified attrs
952 * @param {String} attrs Pipe-separated list of attributes
953 * @param {Function} handler The method that will be applied
954 */
955 function addHandle( attrs, handler ) {
956 var arr = attrs.split( "|" ),
957 i = arr.length;
958
959 while ( i-- ) {
960 Expr.attrHandle[ arr[ i ] ] = handler;
961 }
962 }
963
964 /**
965 * Checks document order of two siblings
966 * @param {Element} a
967 * @param {Element} b
968 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
969 */
970 function siblingCheck( a, b ) {
971 var cur = b && a,
972 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
973 a.sourceIndex - b.sourceIndex;
974
975 // Use IE sourceIndex if available on both nodes
976 if ( diff ) {
977 return diff;
978 }
979
980 // Check if b follows a
981 if ( cur ) {
982 while ( ( cur = cur.nextSibling ) ) {
983 if ( cur === b ) {
984 return -1;
985 }
986 }
987 }
988
989 return a ? 1 : -1;
990 }
991
992 /**
993 * Returns a function to use in pseudos for input types
994 * @param {String} type
995 */
996 function createInputPseudo( type ) {
997 return function( elem ) {
998 var name = elem.nodeName.toLowerCase();
999 return name === "input" && elem.type === type;
1000 };
1001 }
1002
1003 /**
1004 * Returns a function to use in pseudos for buttons
1005 * @param {String} type
1006 */
1007 function createButtonPseudo( type ) {
1008 return function( elem ) {
1009 var name = elem.nodeName.toLowerCase();
1010 return ( name === "input" || name === "button" ) && elem.type === type;
1011 };
1012 }
1013
1014 /**
1015 * Returns a function to use in pseudos for :enabled/:disabled
1016 * @param {Boolean} disabled true for :disabled; false for :enabled
1017 */
1018 function createDisabledPseudo( disabled ) {
1019
1020 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1021 return function( elem ) {
1022
1023 // Only certain elements can match :enabled or :disabled
1024 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1025 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1026 if ( "form" in elem ) {
1027
1028 // Check for inherited disabledness on relevant non-disabled elements:
1029 // * listed form-associated elements in a disabled fieldset
1030 // https://html.spec.whatwg.org/multipage/forms.html#category-listed
1031 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1032 // * option elements in a disabled optgroup
1033 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1034 // All such elements have a "form" property.
1035 if ( elem.parentNode && elem.disabled === false ) {
1036
1037 // Option elements defer to a parent optgroup if present
1038 if ( "label" in elem ) {
1039 if ( "label" in elem.parentNode ) {
1040 return elem.parentNode.disabled === disabled;
1041 } else {
1042 return elem.disabled === disabled;
1043 }
1044 }
1045
1046 // Support: IE 6 - 11
1047 // Use the isDisabled shortcut property to check for disabled fieldset ancestors
1048 return elem.isDisabled === disabled ||
1049
1050 // Where there is no isDisabled, check manually
1051 /* jshint -W018 */
1052 elem.isDisabled !== !disabled &&
1053 inDisabledFieldset( elem ) === disabled;
1054 }
1055
1056 return elem.disabled === disabled;
1057
1058 // Try to winnow out elements that can't be disabled before trusting the disabled property.
1059 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1060 // even exist on them, let alone have a boolean value.
1061 } else if ( "label" in elem ) {
1062 return elem.disabled === disabled;
1063 }
1064
1065 // Remaining elements are neither :enabled nor :disabled
1066 return false;
1067 };
1068 }
1069
1070 /**
1071 * Returns a function to use in pseudos for positionals
1072 * @param {Function} fn
1073 */
1074 function createPositionalPseudo( fn ) {
1075 return markFunction( function( argument ) {
1076 argument = +argument;
1077 return markFunction( function( seed, matches ) {
1078 var j,
1079 matchIndexes = fn( [], seed.length, argument ),
1080 i = matchIndexes.length;
1081
1082 // Match elements found at the specified indexes
1083 while ( i-- ) {
1084 if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
1085 seed[ j ] = !( matches[ j ] = seed[ j ] );
1086 }
1087 }
1088 } );
1089 } );
1090 }
1091
1092 /**
1093 * Checks a node for validity as a Sizzle context
1094 * @param {Element|Object=} context
1095 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1096 */
1097 function testContext( context ) {
1098 return context && typeof context.getElementsByTagName !== "undefined" && context;
1099 }
1100
1101 // Expose support vars for convenience
1102 support = Sizzle.support = {};
1103
1104 /**
1105 * Detects XML nodes
1106 * @param {Element|Object} elem An element or a document
1107 * @returns {Boolean} True iff elem is a non-HTML XML node
1108 */
1109 isXML = Sizzle.isXML = function( elem ) {
1110 var namespace = elem.namespaceURI,
1111 docElem = ( elem.ownerDocument || elem ).documentElement;
1112
1113 // Support: IE <=8
1114 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
1115 // https://bugs.jquery.com/ticket/4833
1116 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
1117 };
1118
1119 /**
1120 * Sets document-related variables once based on the current document
1121 * @param {Element|Object} [doc] An element or document object to use to set the document
1122 * @returns {Object} Returns the current document
1123 */
1124 setDocument = Sizzle.setDocument = function( node ) {
1125 var hasCompare, subWindow,
1126 doc = node ? node.ownerDocument || node : preferredDoc;
1127
1128 // Return early if doc is invalid or already selected
1129 // Support: IE 11+, Edge 17 - 18+
1130 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1131 // two documents; shallow comparisons work.
1132 // eslint-disable-next-line eqeqeq
1133 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
1134 return document;
1135 }
1136
1137 // Update global variables
1138 document = doc;
1139 docElem = document.documentElement;
1140 documentIsHTML = !isXML( document );
1141
1142 // Support: IE 9 - 11+, Edge 12 - 18+
1143 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1144 // Support: IE 11+, Edge 17 - 18+
1145 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1146 // two documents; shallow comparisons work.
1147 // eslint-disable-next-line eqeqeq
1148 if ( preferredDoc != document &&
1149 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
1150
1151 // Support: IE 11, Edge
1152 if ( subWindow.addEventListener ) {
1153 subWindow.addEventListener( "unload", unloadHandler, false );
1154
1155 // Support: IE 9 - 10 only
1156 } else if ( subWindow.attachEvent ) {
1157 subWindow.attachEvent( "onunload", unloadHandler );
1158 }
1159 }
1160
1161 // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
1162 // Safari 4 - 5 only, Opera <=11.6 - 12.x only
1163 // IE/Edge & older browsers don't support the :scope pseudo-class.
1164 // Support: Safari 6.0 only
1165 // Safari 6.0 supports :scope but it's an alias of :root there.
1166 support.scope = assert( function( el ) {
1167 docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
1168 return typeof el.querySelectorAll !== "undefined" &&
1169 !el.querySelectorAll( ":scope fieldset div" ).length;
1170 } );
1171
1172 /* Attributes
1173 ---------------------------------------------------------------------- */
1174
1175 // Support: IE<8
1176 // Verify that getAttribute really returns attributes and not properties
1177 // (excepting IE8 booleans)
1178 support.attributes = assert( function( el ) {
1179 el.className = "i";
1180 return !el.getAttribute( "className" );
1181 } );
1182
1183 /* getElement(s)By*
1184 ---------------------------------------------------------------------- */
1185
1186 // Check if getElementsByTagName("*") returns only elements
1187 support.getElementsByTagName = assert( function( el ) {
1188 el.appendChild( document.createComment( "" ) );
1189 return !el.getElementsByTagName( "*" ).length;
1190 } );
1191
1192 // Support: IE<9
1193 support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1194
1195 // Support: IE<10
1196 // Check if getElementById returns elements by name
1197 // The broken getElementById methods don't pick up programmatically-set names,
1198 // so use a roundabout getElementsByName test
1199 support.getById = assert( function( el ) {
1200 docElem.appendChild( el ).id = expando;
1201 return !document.getElementsByName || !document.getElementsByName( expando ).length;
1202 } );
1203
1204 // ID filter and find
1205 if ( support.getById ) {
1206 Expr.filter[ "ID" ] = function( id ) {
1207 var attrId = id.replace( runescape, funescape );
1208 return function( elem ) {
1209 return elem.getAttribute( "id" ) === attrId;
1210 };
1211 };
1212 Expr.find[ "ID" ] = function( id, context ) {
1213 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1214 var elem = context.getElementById( id );
1215 return elem ? [ elem ] : [];
1216 }
1217 };
1218 } else {
1219 Expr.filter[ "ID" ] = function( id ) {
1220 var attrId = id.replace( runescape, funescape );
1221 return function( elem ) {
1222 var node = typeof elem.getAttributeNode !== "undefined" &&
1223 elem.getAttributeNode( "id" );
1224 return node && node.value === attrId;
1225 };
1226 };
1227
1228 // Support: IE 6 - 7 only
1229 // getElementById is not reliable as a find shortcut
1230 Expr.find[ "ID" ] = function( id, context ) {
1231 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1232 var node, i, elems,
1233 elem = context.getElementById( id );
1234
1235 if ( elem ) {
1236
1237 // Verify the id attribute
1238 node = elem.getAttributeNode( "id" );
1239 if ( node && node.value === id ) {
1240 return [ elem ];
1241 }
1242
1243 // Fall back on getElementsByName
1244 elems = context.getElementsByName( id );
1245 i = 0;
1246 while ( ( elem = elems[ i++ ] ) ) {
1247 node = elem.getAttributeNode( "id" );
1248 if ( node && node.value === id ) {
1249 return [ elem ];
1250 }
1251 }
1252 }
1253
1254 return [];
1255 }
1256 };
1257 }
1258
1259 // Tag
1260 Expr.find[ "TAG" ] = support.getElementsByTagName ?
1261 function( tag, context ) {
1262 if ( typeof context.getElementsByTagName !== "undefined" ) {
1263 return context.getElementsByTagName( tag );
1264
1265 // DocumentFragment nodes don't have gEBTN
1266 } else if ( support.qsa ) {
1267 return context.querySelectorAll( tag );
1268 }
1269 } :
1270
1271 function( tag, context ) {
1272 var elem,
1273 tmp = [],
1274 i = 0,
1275
1276 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1277 results = context.getElementsByTagName( tag );
1278
1279 // Filter out possible comments
1280 if ( tag === "*" ) {
1281 while ( ( elem = results[ i++ ] ) ) {
1282 if ( elem.nodeType === 1 ) {
1283 tmp.push( elem );
1284 }
1285 }
1286
1287 return tmp;
1288 }
1289 return results;
1290 };
1291
1292 // Class
1293 Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
1294 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1295 return context.getElementsByClassName( className );
1296 }
1297 };
1298
1299 /* QSA/matchesSelector
1300 ---------------------------------------------------------------------- */
1301
1302 // QSA and matchesSelector support
1303
1304 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1305 rbuggyMatches = [];
1306
1307 // qSa(:focus) reports false when true (Chrome 21)
1308 // We allow this because of a bug in IE8/9 that throws an error
1309 // whenever `document.activeElement` is accessed on an iframe
1310 // So, we allow :focus to pass through QSA all the time to avoid the IE error
1311 // See https://bugs.jquery.com/ticket/13378
1312 rbuggyQSA = [];
1313
1314 if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
1315
1316 // Build QSA regex
1317 // Regex strategy adopted from Diego Perini
1318 assert( function( el ) {
1319
1320 var input;
1321
1322 // Select is set to empty string on purpose
1323 // This is to test IE's treatment of not explicitly
1324 // setting a boolean content attribute,
1325 // since its presence should be enough
1326 // https://bugs.jquery.com/ticket/12359
1327 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
1328 "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1329 "<option selected=''></option></select>";
1330
1331 // Support: IE8, Opera 11-12.16
1332 // Nothing should be selected when empty strings follow ^= or $= or *=
1333 // The test attribute must be unknown in Opera but "safe" for WinRT
1334 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1335 if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
1336 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1337 }
1338
1339 // Support: IE8
1340 // Boolean attributes and "value" are not treated correctly
1341 if ( !el.querySelectorAll( "[selected]" ).length ) {
1342 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1343 }
1344
1345 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1346 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1347 rbuggyQSA.push( "~=" );
1348 }
1349
1350 // Support: IE 11+, Edge 15 - 18+
1351 // IE 11/Edge don't find elements on a `[name='']` query in some cases.
1352 // Adding a temporary attribute to the document before the selection works
1353 // around the issue.
1354 // Interestingly, IE 10 & older don't seem to have the issue.
1355 input = document.createElement( "input" );
1356 input.setAttribute( "name", "" );
1357 el.appendChild( input );
1358 if ( !el.querySelectorAll( "[name='']" ).length ) {
1359 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
1360 whitespace + "*(?:''|\"\")" );
1361 }
1362
1363 // Webkit/Opera - :checked should return selected option elements
1364 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1365 // IE8 throws error here and will not see later tests
1366 if ( !el.querySelectorAll( ":checked" ).length ) {
1367 rbuggyQSA.push( ":checked" );
1368 }
1369
1370 // Support: Safari 8+, iOS 8+
1371 // https://bugs.webkit.org/show_bug.cgi?id=136851
1372 // In-page `selector#id sibling-combinator selector` fails
1373 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
1374 rbuggyQSA.push( ".#.+[+~]" );
1375 }
1376
1377 // Support: Firefox <=3.6 - 5 only
1378 // Old Firefox doesn't throw on a badly-escaped identifier.
1379 el.querySelectorAll( "\\\f" );
1380 rbuggyQSA.push( "[\\r\\n\\f]" );
1381 } );
1382
1383 assert( function( el ) {
1384 el.innerHTML = "<a href='' disabled='disabled'></a>" +
1385 "<select disabled='disabled'><option/></select>";
1386
1387 // Support: Windows 8 Native Apps
1388 // The type and name attributes are restricted during .innerHTML assignment
1389 var input = document.createElement( "input" );
1390 input.setAttribute( "type", "hidden" );
1391 el.appendChild( input ).setAttribute( "name", "D" );
1392
1393 // Support: IE8
1394 // Enforce case-sensitivity of name attribute
1395 if ( el.querySelectorAll( "[name=d]" ).length ) {
1396 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1397 }
1398
1399 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1400 // IE8 throws error here and will not see later tests
1401 if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
1402 rbuggyQSA.push( ":enabled", ":disabled" );
1403 }
1404
1405 // Support: IE9-11+
1406 // IE's :disabled selector does not pick up the children of disabled fieldsets
1407 docElem.appendChild( el ).disabled = true;
1408 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
1409 rbuggyQSA.push( ":enabled", ":disabled" );
1410 }
1411
1412 // Support: Opera 10 - 11 only
1413 // Opera 10-11 does not throw on post-comma invalid pseudos
1414 el.querySelectorAll( "*,:x" );
1415 rbuggyQSA.push( ",.*:" );
1416 } );
1417 }
1418
1419 if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
1420 docElem.webkitMatchesSelector ||
1421 docElem.mozMatchesSelector ||
1422 docElem.oMatchesSelector ||
1423 docElem.msMatchesSelector ) ) ) ) {
1424
1425 assert( function( el ) {
1426
1427 // Check to see if it's possible to do matchesSelector
1428 // on a disconnected node (IE 9)
1429 support.disconnectedMatch = matches.call( el, "*" );
1430
1431 // This should fail with an exception
1432 // Gecko does not error, returns false instead
1433 matches.call( el, "[s!='']:x" );
1434 rbuggyMatches.push( "!=", pseudos );
1435 } );
1436 }
1437
1438 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
1439 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
1440
1441 /* Contains
1442 ---------------------------------------------------------------------- */
1443 hasCompare = rnative.test( docElem.compareDocumentPosition );
1444
1445 // Element contains another
1446 // Purposefully self-exclusive
1447 // As in, an element does not contain itself
1448 contains = hasCompare || rnative.test( docElem.contains ) ?
1449 function( a, b ) {
1450 var adown = a.nodeType === 9 ? a.documentElement : a,
1451 bup = b && b.parentNode;
1452 return a === bup || !!( bup && bup.nodeType === 1 && (
1453 adown.contains ?
1454 adown.contains( bup ) :
1455 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1456 ) );
1457 } :
1458 function( a, b ) {
1459 if ( b ) {
1460 while ( ( b = b.parentNode ) ) {
1461 if ( b === a ) {
1462 return true;
1463 }
1464 }
1465 }
1466 return false;
1467 };
1468
1469 /* Sorting
1470 ---------------------------------------------------------------------- */
1471
1472 // Document order sorting
1473 sortOrder = hasCompare ?
1474 function( a, b ) {
1475
1476 // Flag for duplicate removal
1477 if ( a === b ) {
1478 hasDuplicate = true;
1479 return 0;
1480 }
1481
1482 // Sort on method existence if only one input has compareDocumentPosition
1483 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1484 if ( compare ) {
1485 return compare;
1486 }
1487
1488 // Calculate position if both inputs belong to the same document
1489 // Support: IE 11+, Edge 17 - 18+
1490 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1491 // two documents; shallow comparisons work.
1492 // eslint-disable-next-line eqeqeq
1493 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
1494 a.compareDocumentPosition( b ) :
1495
1496 // Otherwise we know they are disconnected
1497 1;
1498
1499 // Disconnected nodes
1500 if ( compare & 1 ||
1501 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
1502
1503 // Choose the first element that is related to our preferred document
1504 // Support: IE 11+, Edge 17 - 18+
1505 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1506 // two documents; shallow comparisons work.
1507 // eslint-disable-next-line eqeqeq
1508 if ( a == document || a.ownerDocument == preferredDoc &&
1509 contains( preferredDoc, a ) ) {
1510 return -1;
1511 }
1512
1513 // Support: IE 11+, Edge 17 - 18+
1514 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1515 // two documents; shallow comparisons work.
1516 // eslint-disable-next-line eqeqeq
1517 if ( b == document || b.ownerDocument == preferredDoc &&
1518 contains( preferredDoc, b ) ) {
1519 return 1;
1520 }
1521
1522 // Maintain original order
1523 return sortInput ?
1524 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1525 0;
1526 }
1527
1528 return compare & 4 ? -1 : 1;
1529 } :
1530 function( a, b ) {
1531
1532 // Exit early if the nodes are identical
1533 if ( a === b ) {
1534 hasDuplicate = true;
1535 return 0;
1536 }
1537
1538 var cur,
1539 i = 0,
1540 aup = a.parentNode,
1541 bup = b.parentNode,
1542 ap = [ a ],
1543 bp = [ b ];
1544
1545 // Parentless nodes are either documents or disconnected
1546 if ( !aup || !bup ) {
1547
1548 // Support: IE 11+, Edge 17 - 18+
1549 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1550 // two documents; shallow comparisons work.
1551 /* eslint-disable eqeqeq */
1552 return a == document ? -1 :
1553 b == document ? 1 :
1554 /* eslint-enable eqeqeq */
1555 aup ? -1 :
1556 bup ? 1 :
1557 sortInput ?
1558 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1559 0;
1560
1561 // If the nodes are siblings, we can do a quick check
1562 } else if ( aup === bup ) {
1563 return siblingCheck( a, b );
1564 }
1565
1566 // Otherwise we need full lists of their ancestors for comparison
1567 cur = a;
1568 while ( ( cur = cur.parentNode ) ) {
1569 ap.unshift( cur );
1570 }
1571 cur = b;
1572 while ( ( cur = cur.parentNode ) ) {
1573 bp.unshift( cur );
1574 }
1575
1576 // Walk down the tree looking for a discrepancy
1577 while ( ap[ i ] === bp[ i ] ) {
1578 i++;
1579 }
1580
1581 return i ?
1582
1583 // Do a sibling check if the nodes have a common ancestor
1584 siblingCheck( ap[ i ], bp[ i ] ) :
1585
1586 // Otherwise nodes in our document sort first
1587 // Support: IE 11+, Edge 17 - 18+
1588 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1589 // two documents; shallow comparisons work.
1590 /* eslint-disable eqeqeq */
1591 ap[ i ] == preferredDoc ? -1 :
1592 bp[ i ] == preferredDoc ? 1 :
1593 /* eslint-enable eqeqeq */
1594 0;
1595 };
1596
1597 return document;
1598 };
1599
1600 Sizzle.matches = function( expr, elements ) {
1601 return Sizzle( expr, null, null, elements );
1602 };
1603
1604 Sizzle.matchesSelector = function( elem, expr ) {
1605 setDocument( elem );
1606
1607 if ( support.matchesSelector && documentIsHTML &&
1608 !nonnativeSelectorCache[ expr + " " ] &&
1609 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1610 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1611
1612 try {
1613 var ret = matches.call( elem, expr );
1614
1615 // IE 9's matchesSelector returns false on disconnected nodes
1616 if ( ret || support.disconnectedMatch ||
1617
1618 // As well, disconnected nodes are said to be in a document
1619 // fragment in IE 9
1620 elem.document && elem.document.nodeType !== 11 ) {
1621 return ret;
1622 }
1623 } catch ( e ) {
1624 nonnativeSelectorCache( expr, true );
1625 }
1626 }
1627
1628 return Sizzle( expr, document, null, [ elem ] ).length > 0;
1629 };
1630
1631 Sizzle.contains = function( context, elem ) {
1632
1633 // Set document vars if needed
1634 // Support: IE 11+, Edge 17 - 18+
1635 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1636 // two documents; shallow comparisons work.
1637 // eslint-disable-next-line eqeqeq
1638 if ( ( context.ownerDocument || context ) != document ) {
1639 setDocument( context );
1640 }
1641 return contains( context, elem );
1642 };
1643
1644 Sizzle.attr = function( elem, name ) {
1645
1646 // Set document vars if needed
1647 // Support: IE 11+, Edge 17 - 18+
1648 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1649 // two documents; shallow comparisons work.
1650 // eslint-disable-next-line eqeqeq
1651 if ( ( elem.ownerDocument || elem ) != document ) {
1652 setDocument( elem );
1653 }
1654
1655 var fn = Expr.attrHandle[ name.toLowerCase() ],
1656
1657 // Don't get fooled by Object.prototype properties (jQuery #13807)
1658 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1659 fn( elem, name, !documentIsHTML ) :
1660 undefined;
1661
1662 return val !== undefined ?
1663 val :
1664 support.attributes || !documentIsHTML ?
1665 elem.getAttribute( name ) :
1666 ( val = elem.getAttributeNode( name ) ) && val.specified ?
1667 val.value :
1668 null;
1669 };
1670
1671 Sizzle.escape = function( sel ) {
1672 return ( sel + "" ).replace( rcssescape, fcssescape );
1673 };
1674
1675 Sizzle.error = function( msg ) {
1676 throw new Error( "Syntax error, unrecognized expression: " + msg );
1677 };
1678
1679 /**
1680 * Document sorting and removing duplicates
1681 * @param {ArrayLike} results
1682 */
1683 Sizzle.uniqueSort = function( results ) {
1684 var elem,
1685 duplicates = [],
1686 j = 0,
1687 i = 0;
1688
1689 // Unless we *know* we can detect duplicates, assume their presence
1690 hasDuplicate = !support.detectDuplicates;
1691 sortInput = !support.sortStable && results.slice( 0 );
1692 results.sort( sortOrder );
1693
1694 if ( hasDuplicate ) {
1695 while ( ( elem = results[ i++ ] ) ) {
1696 if ( elem === results[ i ] ) {
1697 j = duplicates.push( i );
1698 }
1699 }
1700 while ( j-- ) {
1701 results.splice( duplicates[ j ], 1 );
1702 }
1703 }
1704
1705 // Clear input after sorting to release objects
1706 // See https://github.com/jquery/sizzle/pull/225
1707 sortInput = null;
1708
1709 return results;
1710 };
1711
1712 /**
1713 * Utility function for retrieving the text value of an array of DOM nodes
1714 * @param {Array|Element} elem
1715 */
1716 getText = Sizzle.getText = function( elem ) {
1717 var node,
1718 ret = "",
1719 i = 0,
1720 nodeType = elem.nodeType;
1721
1722 if ( !nodeType ) {
1723
1724 // If no nodeType, this is expected to be an array
1725 while ( ( node = elem[ i++ ] ) ) {
1726
1727 // Do not traverse comment nodes
1728 ret += getText( node );
1729 }
1730 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1731
1732 // Use textContent for elements
1733 // innerText usage removed for consistency of new lines (jQuery #11153)
1734 if ( typeof elem.textContent === "string" ) {
1735 return elem.textContent;
1736 } else {
1737
1738 // Traverse its children
1739 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1740 ret += getText( elem );
1741 }
1742 }
1743 } else if ( nodeType === 3 || nodeType === 4 ) {
1744 return elem.nodeValue;
1745 }
1746
1747 // Do not include comment or processing instruction nodes
1748
1749 return ret;
1750 };
1751
1752 Expr = Sizzle.selectors = {
1753
1754 // Can be adjusted by the user
1755 cacheLength: 50,
1756
1757 createPseudo: markFunction,
1758
1759 match: matchExpr,
1760
1761 attrHandle: {},
1762
1763 find: {},
1764
1765 relative: {
1766 ">": { dir: "parentNode", first: true },
1767 " ": { dir: "parentNode" },
1768 "+": { dir: "previousSibling", first: true },
1769 "~": { dir: "previousSibling" }
1770 },
1771
1772 preFilter: {
1773 "ATTR": function( match ) {
1774 match[ 1 ] = match[ 1 ].replace( runescape, funescape );
1775
1776 // Move the given value to match[3] whether quoted or unquoted
1777 match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
1778 match[ 5 ] || "" ).replace( runescape, funescape );
1779
1780 if ( match[ 2 ] === "~=" ) {
1781 match[ 3 ] = " " + match[ 3 ] + " ";
1782 }
1783
1784 return match.slice( 0, 4 );
1785 },
1786
1787 "CHILD": function( match ) {
1788
1789 /* matches from matchExpr["CHILD"]
1790 1 type (only|nth|...)
1791 2 what (child|of-type)
1792 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1793 4 xn-component of xn+y argument ([+-]?\d*n|)
1794 5 sign of xn-component
1795 6 x of xn-component
1796 7 sign of y-component
1797 8 y of y-component
1798 */
1799 match[ 1 ] = match[ 1 ].toLowerCase();
1800
1801 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
1802
1803 // nth-* requires argument
1804 if ( !match[ 3 ] ) {
1805 Sizzle.error( match[ 0 ] );
1806 }
1807
1808 // numeric x and y parameters for Expr.filter.CHILD
1809 // remember that false/true cast respectively to 0/1
1810 match[ 4 ] = +( match[ 4 ] ?
1811 match[ 5 ] + ( match[ 6 ] || 1 ) :
1812 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
1813 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
1814
1815 // other types prohibit arguments
1816 } else if ( match[ 3 ] ) {
1817 Sizzle.error( match[ 0 ] );
1818 }
1819
1820 return match;
1821 },
1822
1823 "PSEUDO": function( match ) {
1824 var excess,
1825 unquoted = !match[ 6 ] && match[ 2 ];
1826
1827 if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
1828 return null;
1829 }
1830
1831 // Accept quoted arguments as-is
1832 if ( match[ 3 ] ) {
1833 match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
1834
1835 // Strip excess characters from unquoted arguments
1836 } else if ( unquoted && rpseudo.test( unquoted ) &&
1837
1838 // Get excess from tokenize (recursively)
1839 ( excess = tokenize( unquoted, true ) ) &&
1840
1841 // advance to the next closing parenthesis
1842 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
1843
1844 // excess is a negative index
1845 match[ 0 ] = match[ 0 ].slice( 0, excess );
1846 match[ 2 ] = unquoted.slice( 0, excess );
1847 }
1848
1849 // Return only captures needed by the pseudo filter method (type and argument)
1850 return match.slice( 0, 3 );
1851 }
1852 },
1853
1854 filter: {
1855
1856 "TAG": function( nodeNameSelector ) {
1857 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1858 return nodeNameSelector === "*" ?
1859 function() {
1860 return true;
1861 } :
1862 function( elem ) {
1863 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1864 };
1865 },
1866
1867 "CLASS": function( className ) {
1868 var pattern = classCache[ className + " " ];
1869
1870 return pattern ||
1871 ( pattern = new RegExp( "(^|" + whitespace +
1872 ")" + className + "(" + whitespace + "|$)" ) ) && classCache(
1873 className, function( elem ) {
1874 return pattern.test(
1875 typeof elem.className === "string" && elem.className ||
1876 typeof elem.getAttribute !== "undefined" &&
1877 elem.getAttribute( "class" ) ||
1878 ""
1879 );
1880 } );
1881 },
1882
1883 "ATTR": function( name, operator, check ) {
1884 return function( elem ) {
1885 var result = Sizzle.attr( elem, name );
1886
1887 if ( result == null ) {
1888 return operator === "!=";
1889 }
1890 if ( !operator ) {
1891 return true;
1892 }
1893
1894 result += "";
1895
1896 /* eslint-disable max-len */
1897
1898 return operator === "=" ? result === check :
1899 operator === "!=" ? result !== check :
1900 operator === "^=" ? check && result.indexOf( check ) === 0 :
1901 operator === "*=" ? check && result.indexOf( check ) > -1 :
1902 operator === "$=" ? check && result.slice( -check.length ) === check :
1903 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1904 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1905 false;
1906 /* eslint-enable max-len */
1907
1908 };
1909 },
1910
1911 "CHILD": function( type, what, _argument, first, last ) {
1912 var simple = type.slice( 0, 3 ) !== "nth",
1913 forward = type.slice( -4 ) !== "last",
1914 ofType = what === "of-type";
1915
1916 return first === 1 && last === 0 ?
1917
1918 // Shortcut for :nth-*(n)
1919 function( elem ) {
1920 return !!elem.parentNode;
1921 } :
1922
1923 function( elem, _context, xml ) {
1924 var cache, uniqueCache, outerCache, node, nodeIndex, start,
1925 dir = simple !== forward ? "nextSibling" : "previousSibling",
1926 parent = elem.parentNode,
1927 name = ofType && elem.nodeName.toLowerCase(),
1928 useCache = !xml && !ofType,
1929 diff = false;
1930
1931 if ( parent ) {
1932
1933 // :(first|last|only)-(child|of-type)
1934 if ( simple ) {
1935 while ( dir ) {
1936 node = elem;
1937 while ( ( node = node[ dir ] ) ) {
1938 if ( ofType ?
1939 node.nodeName.toLowerCase() === name :
1940 node.nodeType === 1 ) {
1941
1942 return false;
1943 }
1944 }
1945
1946 // Reverse direction for :only-* (if we haven't yet done so)
1947 start = dir = type === "only" && !start && "nextSibling";
1948 }
1949 return true;
1950 }
1951
1952 start = [ forward ? parent.firstChild : parent.lastChild ];
1953
1954 // non-xml :nth-child(...) stores cache data on `parent`
1955 if ( forward && useCache ) {
1956
1957 // Seek `elem` from a previously-cached index
1958
1959 // ...in a gzip-friendly way
1960 node = parent;
1961 outerCache = node[ expando ] || ( node[ expando ] = {} );
1962
1963 // Support: IE <9 only
1964 // Defend against cloned attroperties (jQuery gh-1709)
1965 uniqueCache = outerCache[ node.uniqueID ] ||
1966 ( outerCache[ node.uniqueID ] = {} );
1967
1968 cache = uniqueCache[ type ] || [];
1969 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1970 diff = nodeIndex && cache[ 2 ];
1971 node = nodeIndex && parent.childNodes[ nodeIndex ];
1972
1973 while ( ( node = ++nodeIndex && node && node[ dir ] ||
1974
1975 // Fallback to seeking `elem` from the start
1976 ( diff = nodeIndex = 0 ) || start.pop() ) ) {
1977
1978 // When found, cache indexes on `parent` and break
1979 if ( node.nodeType === 1 && ++diff && node === elem ) {
1980 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1981 break;
1982 }
1983 }
1984
1985 } else {
1986
1987 // Use previously-cached element index if available
1988 if ( useCache ) {
1989
1990 // ...in a gzip-friendly way
1991 node = elem;
1992 outerCache = node[ expando ] || ( node[ expando ] = {} );
1993
1994 // Support: IE <9 only
1995 // Defend against cloned attroperties (jQuery gh-1709)
1996 uniqueCache = outerCache[ node.uniqueID ] ||
1997 ( outerCache[ node.uniqueID ] = {} );
1998
1999 cache = uniqueCache[ type ] || [];
2000 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2001 diff = nodeIndex;
2002 }
2003
2004 // xml :nth-child(...)
2005 // or :nth-last-child(...) or :nth(-last)?-of-type(...)
2006 if ( diff === false ) {
2007
2008 // Use the same loop as above to seek `elem` from the start
2009 while ( ( node = ++nodeIndex && node && node[ dir ] ||
2010 ( diff = nodeIndex = 0 ) || start.pop() ) ) {
2011
2012 if ( ( ofType ?
2013 node.nodeName.toLowerCase() === name :
2014 node.nodeType === 1 ) &&
2015 ++diff ) {
2016
2017 // Cache the index of each encountered element
2018 if ( useCache ) {
2019 outerCache = node[ expando ] ||
2020 ( node[ expando ] = {} );
2021
2022 // Support: IE <9 only
2023 // Defend against cloned attroperties (jQuery gh-1709)
2024 uniqueCache = outerCache[ node.uniqueID ] ||
2025 ( outerCache[ node.uniqueID ] = {} );
2026
2027 uniqueCache[ type ] = [ dirruns, diff ];
2028 }
2029
2030 if ( node === elem ) {
2031 break;
2032 }
2033 }
2034 }
2035 }
2036 }
2037
2038 // Incorporate the offset, then check against cycle size
2039 diff -= last;
2040 return diff === first || ( diff % first === 0 && diff / first >= 0 );
2041 }
2042 };
2043 },
2044
2045 "PSEUDO": function( pseudo, argument ) {
2046
2047 // pseudo-class names are case-insensitive
2048 // http://www.w3.org/TR/selectors/#pseudo-classes
2049 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2050 // Remember that setFilters inherits from pseudos
2051 var args,
2052 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2053 Sizzle.error( "unsupported pseudo: " + pseudo );
2054
2055 // The user may use createPseudo to indicate that
2056 // arguments are needed to create the filter function
2057 // just as Sizzle does
2058 if ( fn[ expando ] ) {
2059 return fn( argument );
2060 }
2061
2062 // But maintain support for old signatures
2063 if ( fn.length > 1 ) {
2064 args = [ pseudo, pseudo, "", argument ];
2065 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2066 markFunction( function( seed, matches ) {
2067 var idx,
2068 matched = fn( seed, argument ),
2069 i = matched.length;
2070 while ( i-- ) {
2071 idx = indexOf( seed, matched[ i ] );
2072 seed[ idx ] = !( matches[ idx ] = matched[ i ] );
2073 }
2074 } ) :
2075 function( elem ) {
2076 return fn( elem, 0, args );
2077 };
2078 }
2079
2080 return fn;
2081 }
2082 },
2083
2084 pseudos: {
2085
2086 // Potentially complex pseudos
2087 "not": markFunction( function( selector ) {
2088
2089 // Trim the selector passed to compile
2090 // to avoid treating leading and trailing
2091 // spaces as combinators
2092 var input = [],
2093 results = [],
2094 matcher = compile( selector.replace( rtrim, "$1" ) );
2095
2096 return matcher[ expando ] ?
2097 markFunction( function( seed, matches, _context, xml ) {
2098 var elem,
2099 unmatched = matcher( seed, null, xml, [] ),
2100 i = seed.length;
2101
2102 // Match elements unmatched by `matcher`
2103 while ( i-- ) {
2104 if ( ( elem = unmatched[ i ] ) ) {
2105 seed[ i ] = !( matches[ i ] = elem );
2106 }
2107 }
2108 } ) :
2109 function( elem, _context, xml ) {
2110 input[ 0 ] = elem;
2111 matcher( input, null, xml, results );
2112
2113 // Don't keep the element (issue #299)
2114 input[ 0 ] = null;
2115 return !results.pop();
2116 };
2117 } ),
2118
2119 "has": markFunction( function( selector ) {
2120 return function( elem ) {
2121 return Sizzle( selector, elem ).length > 0;
2122 };
2123 } ),
2124
2125 "contains": markFunction( function( text ) {
2126 text = text.replace( runescape, funescape );
2127 return function( elem ) {
2128 return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
2129 };
2130 } ),
2131
2132 // "Whether an element is represented by a :lang() selector
2133 // is based solely on the element's language value
2134 // being equal to the identifier C,
2135 // or beginning with the identifier C immediately followed by "-".
2136 // The matching of C against the element's language value is performed case-insensitively.
2137 // The identifier C does not have to be a valid language name."
2138 // http://www.w3.org/TR/selectors/#lang-pseudo
2139 "lang": markFunction( function( lang ) {
2140
2141 // lang value must be a valid identifier
2142 if ( !ridentifier.test( lang || "" ) ) {
2143 Sizzle.error( "unsupported lang: " + lang );
2144 }
2145 lang = lang.replace( runescape, funescape ).toLowerCase();
2146 return function( elem ) {
2147 var elemLang;
2148 do {
2149 if ( ( elemLang = documentIsHTML ?
2150 elem.lang :
2151 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
2152
2153 elemLang = elemLang.toLowerCase();
2154 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2155 }
2156 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
2157 return false;
2158 };
2159 } ),
2160
2161 // Miscellaneous
2162 "target": function( elem ) {
2163 var hash = window.location && window.location.hash;
2164 return hash && hash.slice( 1 ) === elem.id;
2165 },
2166
2167 "root": function( elem ) {
2168 return elem === docElem;
2169 },
2170
2171 "focus": function( elem ) {
2172 return elem === document.activeElement &&
2173 ( !document.hasFocus || document.hasFocus() ) &&
2174 !!( elem.type || elem.href || ~elem.tabIndex );
2175 },
2176
2177 // Boolean properties
2178 "enabled": createDisabledPseudo( false ),
2179 "disabled": createDisabledPseudo( true ),
2180
2181 "checked": function( elem ) {
2182
2183 // In CSS3, :checked should return both checked and selected elements
2184 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2185 var nodeName = elem.nodeName.toLowerCase();
2186 return ( nodeName === "input" && !!elem.checked ) ||
2187 ( nodeName === "option" && !!elem.selected );
2188 },
2189
2190 "selected": function( elem ) {
2191
2192 // Accessing this property makes selected-by-default
2193 // options in Safari work properly
2194 if ( elem.parentNode ) {
2195 // eslint-disable-next-line no-unused-expressions
2196 elem.parentNode.selectedIndex;
2197 }
2198
2199 return elem.selected === true;
2200 },
2201
2202 // Contents
2203 "empty": function( elem ) {
2204
2205 // http://www.w3.org/TR/selectors/#empty-pseudo
2206 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2207 // but not by others (comment: 8; processing instruction: 7; etc.)
2208 // nodeType < 6 works because attributes (2) do not appear as children
2209 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2210 if ( elem.nodeType < 6 ) {
2211 return false;
2212 }
2213 }
2214 return true;
2215 },
2216
2217 "parent": function( elem ) {
2218 return !Expr.pseudos[ "empty" ]( elem );
2219 },
2220
2221 // Element/input types
2222 "header": function( elem ) {
2223 return rheader.test( elem.nodeName );
2224 },
2225
2226 "input": function( elem ) {
2227 return rinputs.test( elem.nodeName );
2228 },
2229
2230 "button": function( elem ) {
2231 var name = elem.nodeName.toLowerCase();
2232 return name === "input" && elem.type === "button" || name === "button";
2233 },
2234
2235 "text": function( elem ) {
2236 var attr;
2237 return elem.nodeName.toLowerCase() === "input" &&
2238 elem.type === "text" &&
2239
2240 // Support: IE<8
2241 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2242 ( ( attr = elem.getAttribute( "type" ) ) == null ||
2243 attr.toLowerCase() === "text" );
2244 },
2245
2246 // Position-in-collection
2247 "first": createPositionalPseudo( function() {
2248 return [ 0 ];
2249 } ),
2250
2251 "last": createPositionalPseudo( function( _matchIndexes, length ) {
2252 return [ length - 1 ];
2253 } ),
2254
2255 "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
2256 return [ argument < 0 ? argument + length : argument ];
2257 } ),
2258
2259 "even": createPositionalPseudo( function( matchIndexes, length ) {
2260 var i = 0;
2261 for ( ; i < length; i += 2 ) {
2262 matchIndexes.push( i );
2263 }
2264 return matchIndexes;
2265 } ),
2266
2267 "odd": createPositionalPseudo( function( matchIndexes, length ) {
2268 var i = 1;
2269 for ( ; i < length; i += 2 ) {
2270 matchIndexes.push( i );
2271 }
2272 return matchIndexes;
2273 } ),
2274
2275 "lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2276 var i = argument < 0 ?
2277 argument + length :
2278 argument > length ?
2279 length :
2280 argument;
2281 for ( ; --i >= 0; ) {
2282 matchIndexes.push( i );
2283 }
2284 return matchIndexes;
2285 } ),
2286
2287 "gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2288 var i = argument < 0 ? argument + length : argument;
2289 for ( ; ++i < length; ) {
2290 matchIndexes.push( i );
2291 }
2292 return matchIndexes;
2293 } )
2294 }
2295 };
2296
2297 Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
2298
2299 // Add button/input type pseudos
2300 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2301 Expr.pseudos[ i ] = createInputPseudo( i );
2302 }
2303 for ( i in { submit: true, reset: true } ) {
2304 Expr.pseudos[ i ] = createButtonPseudo( i );
2305 }
2306
2307 // Easy API for creating new setFilters
2308 function setFilters() {}
2309 setFilters.prototype = Expr.filters = Expr.pseudos;
2310 Expr.setFilters = new setFilters();
2311
2312 tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2313 var matched, match, tokens, type,
2314 soFar, groups, preFilters,
2315 cached = tokenCache[ selector + " " ];
2316
2317 if ( cached ) {
2318 return parseOnly ? 0 : cached.slice( 0 );
2319 }
2320
2321 soFar = selector;
2322 groups = [];
2323 preFilters = Expr.preFilter;
2324
2325 while ( soFar ) {
2326
2327 // Comma and first run
2328 if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
2329 if ( match ) {
2330
2331 // Don't consume trailing commas as valid
2332 soFar = soFar.slice( match[ 0 ].length ) || soFar;
2333 }
2334 groups.push( ( tokens = [] ) );
2335 }
2336
2337 matched = false;
2338
2339 // Combinators
2340 if ( ( match = rcombinators.exec( soFar ) ) ) {
2341 matched = match.shift();
2342 tokens.push( {
2343 value: matched,
2344
2345 // Cast descendant combinators to space
2346 type: match[ 0 ].replace( rtrim, " " )
2347 } );
2348 soFar = soFar.slice( matched.length );
2349 }
2350
2351 // Filters
2352 for ( type in Expr.filter ) {
2353 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
2354 ( match = preFilters[ type ]( match ) ) ) ) {
2355 matched = match.shift();
2356 tokens.push( {
2357 value: matched,
2358 type: type,
2359 matches: match
2360 } );
2361 soFar = soFar.slice( matched.length );
2362 }
2363 }
2364
2365 if ( !matched ) {
2366 break;
2367 }
2368 }
2369
2370 // Return the length of the invalid excess
2371 // if we're just parsing
2372 // Otherwise, throw an error or return tokens
2373 return parseOnly ?
2374 soFar.length :
2375 soFar ?
2376 Sizzle.error( selector ) :
2377
2378 // Cache the tokens
2379 tokenCache( selector, groups ).slice( 0 );
2380 };
2381
2382 function toSelector( tokens ) {
2383 var i = 0,
2384 len = tokens.length,
2385 selector = "";
2386 for ( ; i < len; i++ ) {
2387 selector += tokens[ i ].value;
2388 }
2389 return selector;
2390 }
2391
2392 function addCombinator( matcher, combinator, base ) {
2393 var dir = combinator.dir,
2394 skip = combinator.next,
2395 key = skip || dir,
2396 checkNonElements = base && key === "parentNode",
2397 doneName = done++;
2398
2399 return combinator.first ?
2400
2401 // Check against closest ancestor/preceding element
2402 function( elem, context, xml ) {
2403 while ( ( elem = elem[ dir ] ) ) {
2404 if ( elem.nodeType === 1 || checkNonElements ) {
2405 return matcher( elem, context, xml );
2406 }
2407 }
2408 return false;
2409 } :
2410
2411 // Check against all ancestor/preceding elements
2412 function( elem, context, xml ) {
2413 var oldCache, uniqueCache, outerCache,
2414 newCache = [ dirruns, doneName ];
2415
2416 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2417 if ( xml ) {
2418 while ( ( elem = elem[ dir ] ) ) {
2419 if ( elem.nodeType === 1 || checkNonElements ) {
2420 if ( matcher( elem, context, xml ) ) {
2421 return true;
2422 }
2423 }
2424 }
2425 } else {
2426 while ( ( elem = elem[ dir ] ) ) {
2427 if ( elem.nodeType === 1 || checkNonElements ) {
2428 outerCache = elem[ expando ] || ( elem[ expando ] = {} );
2429
2430 // Support: IE <9 only
2431 // Defend against cloned attroperties (jQuery gh-1709)
2432 uniqueCache = outerCache[ elem.uniqueID ] ||
2433 ( outerCache[ elem.uniqueID ] = {} );
2434
2435 if ( skip && skip === elem.nodeName.toLowerCase() ) {
2436 elem = elem[ dir ] || elem;
2437 } else if ( ( oldCache = uniqueCache[ key ] ) &&
2438 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2439
2440 // Assign to newCache so results back-propagate to previous elements
2441 return ( newCache[ 2 ] = oldCache[ 2 ] );
2442 } else {
2443
2444 // Reuse newcache so results back-propagate to previous elements
2445 uniqueCache[ key ] = newCache;
2446
2447 // A match means we're done; a fail means we have to keep checking
2448 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
2449 return true;
2450 }
2451 }
2452 }
2453 }
2454 }
2455 return false;
2456 };
2457 }
2458
2459 function elementMatcher( matchers ) {
2460 return matchers.length > 1 ?
2461 function( elem, context, xml ) {
2462 var i = matchers.length;
2463 while ( i-- ) {
2464 if ( !matchers[ i ]( elem, context, xml ) ) {
2465 return false;
2466 }
2467 }
2468 return true;
2469 } :
2470 matchers[ 0 ];
2471 }
2472
2473 function multipleContexts( selector, contexts, results ) {
2474 var i = 0,
2475 len = contexts.length;
2476 for ( ; i < len; i++ ) {
2477 Sizzle( selector, contexts[ i ], results );
2478 }
2479 return results;
2480 }
2481
2482 function condense( unmatched, map, filter, context, xml ) {
2483 var elem,
2484 newUnmatched = [],
2485 i = 0,
2486 len = unmatched.length,
2487 mapped = map != null;
2488
2489 for ( ; i < len; i++ ) {
2490 if ( ( elem = unmatched[ i ] ) ) {
2491 if ( !filter || filter( elem, context, xml ) ) {
2492 newUnmatched.push( elem );
2493 if ( mapped ) {
2494 map.push( i );
2495 }
2496 }
2497 }
2498 }
2499
2500 return newUnmatched;
2501 }
2502
2503 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2504 if ( postFilter && !postFilter[ expando ] ) {
2505 postFilter = setMatcher( postFilter );
2506 }
2507 if ( postFinder && !postFinder[ expando ] ) {
2508 postFinder = setMatcher( postFinder, postSelector );
2509 }
2510 return markFunction( function( seed, results, context, xml ) {
2511 var temp, i, elem,
2512 preMap = [],
2513 postMap = [],
2514 preexisting = results.length,
2515
2516 // Get initial elements from seed or context
2517 elems = seed || multipleContexts(
2518 selector || "*",
2519 context.nodeType ? [ context ] : context,
2520 []
2521 ),
2522
2523 // Prefilter to get matcher input, preserving a map for seed-results synchronization
2524 matcherIn = preFilter && ( seed || !selector ) ?
2525 condense( elems, preMap, preFilter, context, xml ) :
2526 elems,
2527
2528 matcherOut = matcher ?
2529
2530 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2531 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2532
2533 // ...intermediate processing is necessary
2534 [] :
2535
2536 // ...otherwise use results directly
2537 results :
2538 matcherIn;
2539
2540 // Find primary matches
2541 if ( matcher ) {
2542 matcher( matcherIn, matcherOut, context, xml );
2543 }
2544
2545 // Apply postFilter
2546 if ( postFilter ) {
2547 temp = condense( matcherOut, postMap );
2548 postFilter( temp, [], context, xml );
2549
2550 // Un-match failing elements by moving them back to matcherIn
2551 i = temp.length;
2552 while ( i-- ) {
2553 if ( ( elem = temp[ i ] ) ) {
2554 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
2555 }
2556 }
2557 }
2558
2559 if ( seed ) {
2560 if ( postFinder || preFilter ) {
2561 if ( postFinder ) {
2562
2563 // Get the final matcherOut by condensing this intermediate into postFinder contexts
2564 temp = [];
2565 i = matcherOut.length;
2566 while ( i-- ) {
2567 if ( ( elem = matcherOut[ i ] ) ) {
2568
2569 // Restore matcherIn since elem is not yet a final match
2570 temp.push( ( matcherIn[ i ] = elem ) );
2571 }
2572 }
2573 postFinder( null, ( matcherOut = [] ), temp, xml );
2574 }
2575
2576 // Move matched elements from seed to results to keep them synchronized
2577 i = matcherOut.length;
2578 while ( i-- ) {
2579 if ( ( elem = matcherOut[ i ] ) &&
2580 ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
2581
2582 seed[ temp ] = !( results[ temp ] = elem );
2583 }
2584 }
2585 }
2586
2587 // Add elements to results, through postFinder if defined
2588 } else {
2589 matcherOut = condense(
2590 matcherOut === results ?
2591 matcherOut.splice( preexisting, matcherOut.length ) :
2592 matcherOut
2593 );
2594 if ( postFinder ) {
2595 postFinder( null, results, matcherOut, xml );
2596 } else {
2597 push.apply( results, matcherOut );
2598 }
2599 }
2600 } );
2601 }
2602
2603 function matcherFromTokens( tokens ) {
2604 var checkContext, matcher, j,
2605 len = tokens.length,
2606 leadingRelative = Expr.relative[ tokens[ 0 ].type ],
2607 implicitRelative = leadingRelative || Expr.relative[ " " ],
2608 i = leadingRelative ? 1 : 0,
2609
2610 // The foundational matcher ensures that elements are reachable from top-level context(s)
2611 matchContext = addCombinator( function( elem ) {
2612 return elem === checkContext;
2613 }, implicitRelative, true ),
2614 matchAnyContext = addCombinator( function( elem ) {
2615 return indexOf( checkContext, elem ) > -1;
2616 }, implicitRelative, true ),
2617 matchers = [ function( elem, context, xml ) {
2618 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2619 ( checkContext = context ).nodeType ?
2620 matchContext( elem, context, xml ) :
2621 matchAnyContext( elem, context, xml ) );
2622
2623 // Avoid hanging onto element (issue #299)
2624 checkContext = null;
2625 return ret;
2626 } ];
2627
2628 for ( ; i < len; i++ ) {
2629 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
2630 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
2631 } else {
2632 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
2633
2634 // Return special upon seeing a positional matcher
2635 if ( matcher[ expando ] ) {
2636
2637 // Find the next relative operator (if any) for proper handling
2638 j = ++i;
2639 for ( ; j < len; j++ ) {
2640 if ( Expr.relative[ tokens[ j ].type ] ) {
2641 break;
2642 }
2643 }
2644 return setMatcher(
2645 i > 1 && elementMatcher( matchers ),
2646 i > 1 && toSelector(
2647
2648 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2649 tokens
2650 .slice( 0, i - 1 )
2651 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
2652 ).replace( rtrim, "$1" ),
2653 matcher,
2654 i < j && matcherFromTokens( tokens.slice( i, j ) ),
2655 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
2656 j < len && toSelector( tokens )
2657 );
2658 }
2659 matchers.push( matcher );
2660 }
2661 }
2662
2663 return elementMatcher( matchers );
2664 }
2665
2666 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2667 var bySet = setMatchers.length > 0,
2668 byElement = elementMatchers.length > 0,
2669 superMatcher = function( seed, context, xml, results, outermost ) {
2670 var elem, j, matcher,
2671 matchedCount = 0,
2672 i = "0",
2673 unmatched = seed && [],
2674 setMatched = [],
2675 contextBackup = outermostContext,
2676
2677 // We must always have either seed elements or outermost context
2678 elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
2679
2680 // Use integer dirruns iff this is the outermost matcher
2681 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
2682 len = elems.length;
2683
2684 if ( outermost ) {
2685
2686 // Support: IE 11+, Edge 17 - 18+
2687 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2688 // two documents; shallow comparisons work.
2689 // eslint-disable-next-line eqeqeq
2690 outermostContext = context == document || context || outermost;
2691 }
2692
2693 // Add elements passing elementMatchers directly to results
2694 // Support: IE<9, Safari
2695 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2696 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
2697 if ( byElement && elem ) {
2698 j = 0;
2699
2700 // Support: IE 11+, Edge 17 - 18+
2701 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2702 // two documents; shallow comparisons work.
2703 // eslint-disable-next-line eqeqeq
2704 if ( !context && elem.ownerDocument != document ) {
2705 setDocument( elem );
2706 xml = !documentIsHTML;
2707 }
2708 while ( ( matcher = elementMatchers[ j++ ] ) ) {
2709 if ( matcher( elem, context || document, xml ) ) {
2710 results.push( elem );
2711 break;
2712 }
2713 }
2714 if ( outermost ) {
2715 dirruns = dirrunsUnique;
2716 }
2717 }
2718
2719 // Track unmatched elements for set filters
2720 if ( bySet ) {
2721
2722 // They will have gone through all possible matchers
2723 if ( ( elem = !matcher && elem ) ) {
2724 matchedCount--;
2725 }
2726
2727 // Lengthen the array for every element, matched or not
2728 if ( seed ) {
2729 unmatched.push( elem );
2730 }
2731 }
2732 }
2733
2734 // `i` is now the count of elements visited above, and adding it to `matchedCount`
2735 // makes the latter nonnegative.
2736 matchedCount += i;
2737
2738 // Apply set filters to unmatched elements
2739 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2740 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2741 // no element matchers and no seed.
2742 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2743 // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2744 // numerically zero.
2745 if ( bySet && i !== matchedCount ) {
2746 j = 0;
2747 while ( ( matcher = setMatchers[ j++ ] ) ) {
2748 matcher( unmatched, setMatched, context, xml );
2749 }
2750
2751 if ( seed ) {
2752
2753 // Reintegrate element matches to eliminate the need for sorting
2754 if ( matchedCount > 0 ) {
2755 while ( i-- ) {
2756 if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
2757 setMatched[ i ] = pop.call( results );
2758 }
2759 }
2760 }
2761
2762 // Discard index placeholder values to get only actual matches
2763 setMatched = condense( setMatched );
2764 }
2765
2766 // Add matches to results
2767 push.apply( results, setMatched );
2768
2769 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2770 if ( outermost && !seed && setMatched.length > 0 &&
2771 ( matchedCount + setMatchers.length ) > 1 ) {
2772
2773 Sizzle.uniqueSort( results );
2774 }
2775 }
2776
2777 // Override manipulation of globals by nested matchers
2778 if ( outermost ) {
2779 dirruns = dirrunsUnique;
2780 outermostContext = contextBackup;
2781 }
2782
2783 return unmatched;
2784 };
2785
2786 return bySet ?
2787 markFunction( superMatcher ) :
2788 superMatcher;
2789 }
2790
2791 compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2792 var i,
2793 setMatchers = [],
2794 elementMatchers = [],
2795 cached = compilerCache[ selector + " " ];
2796
2797 if ( !cached ) {
2798
2799 // Generate a function of recursive functions that can be used to check each element
2800 if ( !match ) {
2801 match = tokenize( selector );
2802 }
2803 i = match.length;
2804 while ( i-- ) {
2805 cached = matcherFromTokens( match[ i ] );
2806 if ( cached[ expando ] ) {
2807 setMatchers.push( cached );
2808 } else {
2809 elementMatchers.push( cached );
2810 }
2811 }
2812
2813 // Cache the compiled function
2814 cached = compilerCache(
2815 selector,
2816 matcherFromGroupMatchers( elementMatchers, setMatchers )
2817 );
2818
2819 // Save selector and tokenization
2820 cached.selector = selector;
2821 }
2822 return cached;
2823 };
2824
2825 /**
2826 * A low-level selection function that works with Sizzle's compiled
2827 * selector functions
2828 * @param {String|Function} selector A selector or a pre-compiled
2829 * selector function built with Sizzle.compile
2830 * @param {Element} context
2831 * @param {Array} [results]
2832 * @param {Array} [seed] A set of elements to match against
2833 */
2834 select = Sizzle.select = function( selector, context, results, seed ) {
2835 var i, tokens, token, type, find,
2836 compiled = typeof selector === "function" && selector,
2837 match = !seed && tokenize( ( selector = compiled.selector || selector ) );
2838
2839 results = results || [];
2840
2841 // Try to minimize operations if there is only one selector in the list and no seed
2842 // (the latter of which guarantees us context)
2843 if ( match.length === 1 ) {
2844
2845 // Reduce context if the leading compound selector is an ID
2846 tokens = match[ 0 ] = match[ 0 ].slice( 0 );
2847 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
2848 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
2849
2850 context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
2851 .replace( runescape, funescape ), context ) || [] )[ 0 ];
2852 if ( !context ) {
2853 return results;
2854
2855 // Precompiled matchers will still verify ancestry, so step up a level
2856 } else if ( compiled ) {
2857 context = context.parentNode;
2858 }
2859
2860 selector = selector.slice( tokens.shift().value.length );
2861 }
2862
2863 // Fetch a seed set for right-to-left matching
2864 i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
2865 while ( i-- ) {
2866 token = tokens[ i ];
2867
2868 // Abort if we hit a combinator
2869 if ( Expr.relative[ ( type = token.type ) ] ) {
2870 break;
2871 }
2872 if ( ( find = Expr.find[ type ] ) ) {
2873
2874 // Search, expanding context for leading sibling combinators
2875 if ( ( seed = find(
2876 token.matches[ 0 ].replace( runescape, funescape ),
2877 rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
2878 context
2879 ) ) ) {
2880
2881 // If seed is empty or no tokens remain, we can return early
2882 tokens.splice( i, 1 );
2883 selector = seed.length && toSelector( tokens );
2884 if ( !selector ) {
2885 push.apply( results, seed );
2886 return results;
2887 }
2888
2889 break;
2890 }
2891 }
2892 }
2893 }
2894
2895 // Compile and execute a filtering function if one is not provided
2896 // Provide `match` to avoid retokenization if we modified the selector above
2897 ( compiled || compile( selector, match ) )(
2898 seed,
2899 context,
2900 !documentIsHTML,
2901 results,
2902 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2903 );
2904 return results;
2905 };
2906
2907 // One-time assignments
2908
2909 // Sort stability
2910 support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
2911
2912 // Support: Chrome 14-35+
2913 // Always assume duplicates if they aren't passed to the comparison function
2914 support.detectDuplicates = !!hasDuplicate;
2915
2916 // Initialize against the default document
2917 setDocument();
2918
2919 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2920 // Detached nodes confoundingly follow *each other*
2921 support.sortDetached = assert( function( el ) {
2922
2923 // Should return 1, but returns 4 (following)
2924 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
2925 } );
2926
2927 // Support: IE<8
2928 // Prevent attribute/property "interpolation"
2929 // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2930 if ( !assert( function( el ) {
2931 el.innerHTML = "<a href='#'></a>";
2932 return el.firstChild.getAttribute( "href" ) === "#";
2933 } ) ) {
2934 addHandle( "type|href|height|width", function( elem, name, isXML ) {
2935 if ( !isXML ) {
2936 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2937 }
2938 } );
2939 }
2940
2941 // Support: IE<9
2942 // Use defaultValue in place of getAttribute("value")
2943 if ( !support.attributes || !assert( function( el ) {
2944 el.innerHTML = "<input/>";
2945 el.firstChild.setAttribute( "value", "" );
2946 return el.firstChild.getAttribute( "value" ) === "";
2947 } ) ) {
2948 addHandle( "value", function( elem, _name, isXML ) {
2949 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2950 return elem.defaultValue;
2951 }
2952 } );
2953 }
2954
2955 // Support: IE<9
2956 // Use getAttributeNode to fetch booleans when getAttribute lies
2957 if ( !assert( function( el ) {
2958 return el.getAttribute( "disabled" ) == null;
2959 } ) ) {
2960 addHandle( booleans, function( elem, name, isXML ) {
2961 var val;
2962 if ( !isXML ) {
2963 return elem[ name ] === true ? name.toLowerCase() :
2964 ( val = elem.getAttributeNode( name ) ) && val.specified ?
2965 val.value :
2966 null;
2967 }
2968 } );
2969 }
2970
2971 return Sizzle;
2972
2973 } )( window );
2974
2975
2976
2977 jQuery.find = Sizzle;
2978 jQuery.expr = Sizzle.selectors;
2979
2980 // Deprecated
2981 jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2982 jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2983 jQuery.text = Sizzle.getText;
2984 jQuery.isXMLDoc = Sizzle.isXML;
2985 jQuery.contains = Sizzle.contains;
2986 jQuery.escapeSelector = Sizzle.escape;
2987
2988
2989
2990
2991 var dir = function( elem, dir, until ) {
2992 var matched = [],
2993 truncate = until !== undefined;
2994
2995 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2996 if ( elem.nodeType === 1 ) {
2997 if ( truncate && jQuery( elem ).is( until ) ) {
2998 break;
2999 }
3000 matched.push( elem );
3001 }
3002 }
3003 return matched;
3004 };
3005
3006
3007 var siblings = function( n, elem ) {
3008 var matched = [];
3009
3010 for ( ; n; n = n.nextSibling ) {
3011 if ( n.nodeType === 1 && n !== elem ) {
3012 matched.push( n );
3013 }
3014 }
3015
3016 return matched;
3017 };
3018
3019
3020 var rneedsContext = jQuery.expr.match.needsContext;
3021
3022
3023
3024 function nodeName( elem, name ) {
3025
3026 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
3027
3028 };
3029 var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
3030
3031
3032
3033 // Implement the identical functionality for filter and not
3034 function winnow( elements, qualifier, not ) {
3035 if ( isFunction( qualifier ) ) {
3036 return jQuery.grep( elements, function( elem, i ) {
3037 return !!qualifier.call( elem, i, elem ) !== not;
3038 } );
3039 }
3040
3041 // Single element
3042 if ( qualifier.nodeType ) {
3043 return jQuery.grep( elements, function( elem ) {
3044 return ( elem === qualifier ) !== not;
3045 } );
3046 }
3047
3048 // Arraylike of elements (jQuery, arguments, Array)
3049 if ( typeof qualifier !== "string" ) {
3050 return jQuery.grep( elements, function( elem ) {
3051 return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
3052 } );
3053 }
3054
3055 // Filtered directly for both simple and complex selectors
3056 return jQuery.filter( qualifier, elements, not );
3057 }
3058
3059 jQuery.filter = function( expr, elems, not ) {
3060 var elem = elems[ 0 ];
3061
3062 if ( not ) {
3063 expr = ":not(" + expr + ")";
3064 }
3065
3066 if ( elems.length === 1 && elem.nodeType === 1 ) {
3067 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
3068 }
3069
3070 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
3071 return elem.nodeType === 1;
3072 } ) );
3073 };
3074
3075 jQuery.fn.extend( {
3076 find: function( selector ) {
3077 var i, ret,
3078 len = this.length,
3079 self = this;
3080
3081 if ( typeof selector !== "string" ) {
3082 return this.pushStack( jQuery( selector ).filter( function() {
3083 for ( i = 0; i < len; i++ ) {
3084 if ( jQuery.contains( self[ i ], this ) ) {
3085 return true;
3086 }
3087 }
3088 } ) );
3089 }
3090
3091 ret = this.pushStack( [] );
3092
3093 for ( i = 0; i < len; i++ ) {
3094 jQuery.find( selector, self[ i ], ret );
3095 }
3096
3097 return len > 1 ? jQuery.uniqueSort( ret ) : ret;
3098 },
3099 filter: function( selector ) {
3100 return this.pushStack( winnow( this, selector || [], false ) );
3101 },
3102 not: function( selector ) {
3103 return this.pushStack( winnow( this, selector || [], true ) );
3104 },
3105 is: function( selector ) {
3106 return !!winnow(
3107 this,
3108
3109 // If this is a positional/relative selector, check membership in the returned set
3110 // so $("p:first").is("p:last") won't return true for a doc with two "p".
3111 typeof selector === "string" && rneedsContext.test( selector ) ?
3112 jQuery( selector ) :
3113 selector || [],
3114 false
3115 ).length;
3116 }
3117 } );
3118
3119
3120 // Initialize a jQuery object
3121
3122
3123 // A central reference to the root jQuery(document)
3124 var rootjQuery,
3125
3126 // A simple way to check for HTML strings
3127 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
3128 // Strict HTML recognition (#11290: must start with <)
3129 // Shortcut simple #id case for speed
3130 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
3131
3132 init = jQuery.fn.init = function( selector, context, root ) {
3133 var match, elem;
3134
3135 // HANDLE: $(""), $(null), $(undefined), $(false)
3136 if ( !selector ) {
3137 return this;
3138 }
3139
3140 // Method init() accepts an alternate rootjQuery
3141 // so migrate can support jQuery.sub (gh-2101)
3142 root = root || rootjQuery;
3143
3144 // Handle HTML strings
3145 if ( typeof selector === "string" ) {
3146 if ( selector[ 0 ] === "<" &&
3147 selector[ selector.length - 1 ] === ">" &&
3148 selector.length >= 3 ) {
3149
3150 // Assume that strings that start and end with <> are HTML and skip the regex check
3151 match = [ null, selector, null ];
3152
3153 } else {
3154 match = rquickExpr.exec( selector );
3155 }
3156
3157 // Match html or make sure no context is specified for #id
3158 if ( match && ( match[ 1 ] || !context ) ) {
3159
3160 // HANDLE: $(html) -> $(array)
3161 if ( match[ 1 ] ) {
3162 context = context instanceof jQuery ? context[ 0 ] : context;
3163
3164 // Option to run scripts is true for back-compat
3165 // Intentionally let the error be thrown if parseHTML is not present
3166 jQuery.merge( this, jQuery.parseHTML(
3167 match[ 1 ],
3168 context && context.nodeType ? context.ownerDocument || context : document,
3169 true
3170 ) );
3171
3172 // HANDLE: $(html, props)
3173 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
3174 for ( match in context ) {
3175
3176 // Properties of context are called as methods if possible
3177 if ( isFunction( this[ match ] ) ) {
3178 this[ match ]( context[ match ] );
3179
3180 // ...and otherwise set as attributes
3181 } else {
3182 this.attr( match, context[ match ] );
3183 }
3184 }
3185 }
3186
3187 return this;
3188
3189 // HANDLE: $(#id)
3190 } else {
3191 elem = document.getElementById( match[ 2 ] );
3192
3193 if ( elem ) {
3194
3195 // Inject the element directly into the jQuery object
3196 this[ 0 ] = elem;
3197 this.length = 1;
3198 }
3199 return this;
3200 }
3201
3202 // HANDLE: $(expr, $(...))
3203 } else if ( !context || context.jquery ) {
3204 return ( context || root ).find( selector );
3205
3206 // HANDLE: $(expr, context)
3207 // (which is just equivalent to: $(context).find(expr)
3208 } else {
3209 return this.constructor( context ).find( selector );
3210 }
3211
3212 // HANDLE: $(DOMElement)
3213 } else if ( selector.nodeType ) {
3214 this[ 0 ] = selector;
3215 this.length = 1;
3216 return this;
3217
3218 // HANDLE: $(function)
3219 // Shortcut for document ready
3220 } else if ( isFunction( selector ) ) {
3221 return root.ready !== undefined ?
3222 root.ready( selector ) :
3223
3224 // Execute immediately if ready is not present
3225 selector( jQuery );
3226 }
3227
3228 return jQuery.makeArray( selector, this );
3229 };
3230
3231 // Give the init function the jQuery prototype for later instantiation
3232 init.prototype = jQuery.fn;
3233
3234 // Initialize central reference
3235 rootjQuery = jQuery( document );
3236
3237
3238 var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3239
3240 // Methods guaranteed to produce a unique set when starting from a unique set
3241 guaranteedUnique = {
3242 children: true,
3243 contents: true,
3244 next: true,
3245 prev: true
3246 };
3247
3248 jQuery.fn.extend( {
3249 has: function( target ) {
3250 var targets = jQuery( target, this ),
3251 l = targets.length;
3252
3253 return this.filter( function() {
3254 var i = 0;
3255 for ( ; i < l; i++ ) {
3256 if ( jQuery.contains( this, targets[ i ] ) ) {
3257 return true;
3258 }
3259 }
3260 } );
3261 },
3262
3263 closest: function( selectors, context ) {
3264 var cur,
3265 i = 0,
3266 l = this.length,
3267 matched = [],
3268 targets = typeof selectors !== "string" && jQuery( selectors );
3269
3270 // Positional selectors never match, since there's no _selection_ context
3271 if ( !rneedsContext.test( selectors ) ) {
3272 for ( ; i < l; i++ ) {
3273 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3274
3275 // Always skip document fragments
3276 if ( cur.nodeType < 11 && ( targets ?
3277 targets.index( cur ) > -1 :
3278
3279 // Don't pass non-elements to Sizzle
3280 cur.nodeType === 1 &&
3281 jQuery.find.matchesSelector( cur, selectors ) ) ) {
3282
3283 matched.push( cur );
3284 break;
3285 }
3286 }
3287 }
3288 }
3289
3290 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3291 },
3292
3293 // Determine the position of an element within the set
3294 index: function( elem ) {
3295
3296 // No argument, return index in parent
3297 if ( !elem ) {
3298 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3299 }
3300
3301 // Index in selector
3302 if ( typeof elem === "string" ) {
3303 return indexOf.call( jQuery( elem ), this[ 0 ] );
3304 }
3305
3306 // Locate the position of the desired element
3307 return indexOf.call( this,
3308
3309 // If it receives a jQuery object, the first element is used
3310 elem.jquery ? elem[ 0 ] : elem
3311 );
3312 },
3313
3314 add: function( selector, context ) {
3315 return this.pushStack(
3316 jQuery.uniqueSort(
3317 jQuery.merge( this.get(), jQuery( selector, context ) )
3318 )
3319 );
3320 },
3321
3322 addBack: function( selector ) {
3323 return this.add( selector == null ?
3324 this.prevObject : this.prevObject.filter( selector )
3325 );
3326 }
3327 } );
3328
3329 function sibling( cur, dir ) {
3330 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3331 return cur;
3332 }
3333
3334 jQuery.each( {
3335 parent: function( elem ) {
3336 var parent = elem.parentNode;
3337 return parent && parent.nodeType !== 11 ? parent : null;
3338 },
3339 parents: function( elem ) {
3340 return dir( elem, "parentNode" );
3341 },
3342 parentsUntil: function( elem, _i, until ) {
3343 return dir( elem, "parentNode", until );
3344 },
3345 next: function( elem ) {
3346 return sibling( elem, "nextSibling" );
3347 },
3348 prev: function( elem ) {
3349 return sibling( elem, "previousSibling" );
3350 },
3351 nextAll: function( elem ) {
3352 return dir( elem, "nextSibling" );
3353 },
3354 prevAll: function( elem ) {
3355 return dir( elem, "previousSibling" );
3356 },
3357 nextUntil: function( elem, _i, until ) {
3358 return dir( elem, "nextSibling", until );
3359 },
3360 prevUntil: function( elem, _i, until ) {
3361 return dir( elem, "previousSibling", until );
3362 },
3363 siblings: function( elem ) {
3364 return siblings( ( elem.parentNode || {} ).firstChild, elem );
3365 },
3366 children: function( elem ) {
3367 return siblings( elem.firstChild );
3368 },
3369 contents: function( elem ) {
3370 if ( elem.contentDocument != null &&
3371
3372 // Support: IE 11+
3373 // <object> elements with no `data` attribute has an object
3374 // `contentDocument` with a `null` prototype.
3375 getProto( elem.contentDocument ) ) {
3376
3377 return elem.contentDocument;
3378 }
3379
3380 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3381 // Treat the template element as a regular one in browsers that
3382 // don't support it.
3383 if ( nodeName( elem, "template" ) ) {
3384 elem = elem.content || elem;
3385 }
3386
3387 return jQuery.merge( [], elem.childNodes );
3388 }
3389 }, function( name, fn ) {
3390 jQuery.fn[ name ] = function( until, selector ) {
3391 var matched = jQuery.map( this, fn, until );
3392
3393 if ( name.slice( -5 ) !== "Until" ) {
3394 selector = until;
3395 }
3396
3397 if ( selector && typeof selector === "string" ) {
3398 matched = jQuery.filter( selector, matched );
3399 }
3400
3401 if ( this.length > 1 ) {
3402
3403 // Remove duplicates
3404 if ( !guaranteedUnique[ name ] ) {
3405 jQuery.uniqueSort( matched );
3406 }
3407
3408 // Reverse order for parents* and prev-derivatives
3409 if ( rparentsprev.test( name ) ) {
3410 matched.reverse();
3411 }
3412 }
3413
3414 return this.pushStack( matched );
3415 };
3416 } );
3417 var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
3418
3419
3420
3421 // Convert String-formatted options into Object-formatted ones
3422 function createOptions( options ) {
3423 var object = {};
3424 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
3425 object[ flag ] = true;
3426 } );
3427 return object;
3428 }
3429
3430 /*
3431 * Create a callback list using the following parameters:
3432 *
3433 * options: an optional list of space-separated options that will change how
3434 * the callback list behaves or a more traditional option object
3435 *
3436 * By default a callback list will act like an event callback list and can be
3437 * "fired" multiple times.
3438 *
3439 * Possible options:
3440 *
3441 * once: will ensure the callback list can only be fired once (like a Deferred)
3442 *
3443 * memory: will keep track of previous values and will call any callback added
3444 * after the list has been fired right away with the latest "memorized"
3445 * values (like a Deferred)
3446 *
3447 * unique: will ensure a callback can only be added once (no duplicate in the list)
3448 *
3449 * stopOnFalse: interrupt callings when a callback returns false
3450 *
3451 */
3452 jQuery.Callbacks = function( options ) {
3453
3454 // Convert options from String-formatted to Object-formatted if needed
3455 // (we check in cache first)
3456 options = typeof options === "string" ?
3457 createOptions( options ) :
3458 jQuery.extend( {}, options );
3459
3460 var // Flag to know if list is currently firing
3461 firing,
3462
3463 // Last fire value for non-forgettable lists
3464 memory,
3465
3466 // Flag to know if list was already fired
3467 fired,
3468
3469 // Flag to prevent firing
3470 locked,
3471
3472 // Actual callback list
3473 list = [],
3474
3475 // Queue of execution data for repeatable lists
3476 queue = [],
3477
3478 // Index of currently firing callback (modified by add/remove as needed)
3479 firingIndex = -1,
3480
3481 // Fire callbacks
3482 fire = function() {
3483
3484 // Enforce single-firing
3485 locked = locked || options.once;
3486
3487 // Execute callbacks for all pending executions,
3488 // respecting firingIndex overrides and runtime changes
3489 fired = firing = true;
3490 for ( ; queue.length; firingIndex = -1 ) {
3491 memory = queue.shift();
3492 while ( ++firingIndex < list.length ) {
3493
3494 // Run callback and check for early termination
3495 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3496 options.stopOnFalse ) {
3497
3498 // Jump to end and forget the data so .add doesn't re-fire
3499 firingIndex = list.length;
3500 memory = false;
3501 }
3502 }
3503 }
3504
3505 // Forget the data if we're done with it
3506 if ( !options.memory ) {
3507 memory = false;
3508 }
3509
3510 firing = false;
3511
3512 // Clean up if we're done firing for good
3513 if ( locked ) {
3514
3515 // Keep an empty list if we have data for future add calls
3516 if ( memory ) {
3517 list = [];
3518
3519 // Otherwise, this object is spent
3520 } else {
3521 list = "";
3522 }
3523 }
3524 },
3525
3526 // Actual Callbacks object
3527 self = {
3528
3529 // Add a callback or a collection of callbacks to the list
3530 add: function() {
3531 if ( list ) {
3532
3533 // If we have memory from a past run, we should fire after adding
3534 if ( memory && !firing ) {
3535 firingIndex = list.length - 1;
3536 queue.push( memory );
3537 }
3538
3539 ( function add( args ) {
3540 jQuery.each( args, function( _, arg ) {
3541 if ( isFunction( arg ) ) {
3542 if ( !options.unique || !self.has( arg ) ) {
3543 list.push( arg );
3544 }
3545 } else if ( arg && arg.length && toType( arg ) !== "string" ) {
3546
3547 // Inspect recursively
3548 add( arg );
3549 }
3550 } );
3551 } )( arguments );
3552
3553 if ( memory && !firing ) {
3554 fire();
3555 }
3556 }
3557 return this;
3558 },
3559
3560 // Remove a callback from the list
3561 remove: function() {
3562 jQuery.each( arguments, function( _, arg ) {
3563 var index;
3564 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3565 list.splice( index, 1 );
3566
3567 // Handle firing indexes
3568 if ( index <= firingIndex ) {
3569 firingIndex--;
3570 }
3571 }
3572 } );
3573 return this;
3574 },
3575
3576 // Check if a given callback is in the list.
3577 // If no argument is given, return whether or not list has callbacks attached.
3578 has: function( fn ) {
3579 return fn ?
3580 jQuery.inArray( fn, list ) > -1 :
3581 list.length > 0;
3582 },
3583
3584 // Remove all callbacks from the list
3585 empty: function() {
3586 if ( list ) {
3587 list = [];
3588 }
3589 return this;
3590 },
3591
3592 // Disable .fire and .add
3593 // Abort any current/pending executions
3594 // Clear all callbacks and values
3595 disable: function() {
3596 locked = queue = [];
3597 list = memory = "";
3598 return this;
3599 },
3600 disabled: function() {
3601 return !list;
3602 },
3603
3604 // Disable .fire
3605 // Also disable .add unless we have memory (since it would have no effect)
3606 // Abort any pending executions
3607 lock: function() {
3608 locked = queue = [];
3609 if ( !memory && !firing ) {
3610 list = memory = "";
3611 }
3612 return this;
3613 },
3614 locked: function() {
3615 return !!locked;
3616 },
3617
3618 // Call all callbacks with the given context and arguments
3619 fireWith: function( context, args ) {
3620 if ( !locked ) {
3621 args = args || [];
3622 args = [ context, args.slice ? args.slice() : args ];
3623 queue.push( args );
3624 if ( !firing ) {
3625 fire();
3626 }
3627 }
3628 return this;
3629 },
3630
3631 // Call all the callbacks with the given arguments
3632 fire: function() {
3633 self.fireWith( this, arguments );
3634 return this;
3635 },
3636
3637 // To know if the callbacks have already been called at least once
3638 fired: function() {
3639 return !!fired;
3640 }
3641 };
3642
3643 return self;
3644 };
3645
3646
3647 function Identity( v ) {
3648 return v;
3649 }
3650 function Thrower( ex ) {
3651 throw ex;
3652 }
3653
3654 function adoptValue( value, resolve, reject, noValue ) {
3655 var method;
3656
3657 try {
3658
3659 // Check for promise aspect first to privilege synchronous behavior
3660 if ( value && isFunction( ( method = value.promise ) ) ) {
3661 method.call( value ).done( resolve ).fail( reject );
3662
3663 // Other thenables
3664 } else if ( value && isFunction( ( method = value.then ) ) ) {
3665 method.call( value, resolve, reject );
3666
3667 // Other non-thenables
3668 } else {
3669
3670 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3671 // * false: [ value ].slice( 0 ) => resolve( value )
3672 // * true: [ value ].slice( 1 ) => resolve()
3673 resolve.apply( undefined, [ value ].slice( noValue ) );
3674 }
3675
3676 // For Promises/A+, convert exceptions into rejections
3677 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3678 // Deferred#then to conditionally suppress rejection.
3679 } catch ( value ) {
3680
3681 // Support: Android 4.0 only
3682 // Strict mode functions invoked without .call/.apply get global-object context
3683 reject.apply( undefined, [ value ] );
3684 }
3685 }
3686
3687 jQuery.extend( {
3688
3689 Deferred: function( func ) {
3690 var tuples = [
3691
3692 // action, add listener, callbacks,
3693 // ... .then handlers, argument index, [final state]
3694 [ "notify", "progress", jQuery.Callbacks( "memory" ),
3695 jQuery.Callbacks( "memory" ), 2 ],
3696 [ "resolve", "done", jQuery.Callbacks( "once memory" ),
3697 jQuery.Callbacks( "once memory" ), 0, "resolved" ],
3698 [ "reject", "fail", jQuery.Callbacks( "once memory" ),
3699 jQuery.Callbacks( "once memory" ), 1, "rejected" ]
3700 ],
3701 state = "pending",
3702 promise = {
3703 state: function() {
3704 return state;
3705 },
3706 always: function() {
3707 deferred.done( arguments ).fail( arguments );
3708 return this;
3709 },
3710 "catch": function( fn ) {
3711 return promise.then( null, fn );
3712 },
3713
3714 // Keep pipe for back-compat
3715 pipe: function( /* fnDone, fnFail, fnProgress */ ) {
3716 var fns = arguments;
3717
3718 return jQuery.Deferred( function( newDefer ) {
3719 jQuery.each( tuples, function( _i, tuple ) {
3720
3721 // Map tuples (progress, done, fail) to arguments (done, fail, progress)
3722 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
3723
3724 // deferred.progress(function() { bind to newDefer or newDefer.notify })
3725 // deferred.done(function() { bind to newDefer or newDefer.resolve })
3726 // deferred.fail(function() { bind to newDefer or newDefer.reject })
3727 deferred[ tuple[ 1 ] ]( function() {
3728 var returned = fn && fn.apply( this, arguments );
3729 if ( returned && isFunction( returned.promise ) ) {
3730 returned.promise()
3731 .progress( newDefer.notify )
3732 .done( newDefer.resolve )
3733 .fail( newDefer.reject );
3734 } else {
3735 newDefer[ tuple[ 0 ] + "With" ](
3736 this,
3737 fn ? [ returned ] : arguments
3738 );
3739 }
3740 } );
3741 } );
3742 fns = null;
3743 } ).promise();
3744 },
3745 then: function( onFulfilled, onRejected, onProgress ) {
3746 var maxDepth = 0;
3747 function resolve( depth, deferred, handler, special ) {
3748 return function() {
3749 var that = this,
3750 args = arguments,
3751 mightThrow = function() {
3752 var returned, then;
3753
3754 // Support: Promises/A+ section 2.3.3.3.3
3755 // https://promisesaplus.com/#point-59
3756 // Ignore double-resolution attempts
3757 if ( depth < maxDepth ) {
3758 return;
3759 }
3760
3761 returned = handler.apply( that, args );
3762
3763 // Support: Promises/A+ section 2.3.1
3764 // https://promisesaplus.com/#point-48
3765 if ( returned === deferred.promise() ) {
3766 throw new TypeError( "Thenable self-resolution" );
3767 }
3768
3769 // Support: Promises/A+ sections 2.3.3.1, 3.5
3770 // https://promisesaplus.com/#point-54
3771 // https://promisesaplus.com/#point-75
3772 // Retrieve `then` only once
3773 then = returned &&
3774
3775 // Support: Promises/A+ section 2.3.4
3776 // https://promisesaplus.com/#point-64
3777 // Only check objects and functions for thenability
3778 ( typeof returned === "object" ||
3779 typeof returned === "function" ) &&
3780 returned.then;
3781
3782 // Handle a returned thenable
3783 if ( isFunction( then ) ) {
3784
3785 // Special processors (notify) just wait for resolution
3786 if ( special ) {
3787 then.call(
3788 returned,
3789 resolve( maxDepth, deferred, Identity, special ),
3790 resolve( maxDepth, deferred, Thrower, special )
3791 );
3792
3793 // Normal processors (resolve) also hook into progress
3794 } else {
3795
3796 // ...and disregard older resolution values
3797 maxDepth++;
3798
3799 then.call(
3800 returned,
3801 resolve( maxDepth, deferred, Identity, special ),
3802 resolve( maxDepth, deferred, Thrower, special ),
3803 resolve( maxDepth, deferred, Identity,
3804 deferred.notifyWith )
3805 );
3806 }
3807
3808 // Handle all other returned values
3809 } else {
3810
3811 // Only substitute handlers pass on context
3812 // and multiple values (non-spec behavior)
3813 if ( handler !== Identity ) {
3814 that = undefined;
3815 args = [ returned ];
3816 }
3817
3818 // Process the value(s)
3819 // Default process is resolve
3820 ( special || deferred.resolveWith )( that, args );
3821 }
3822 },
3823
3824 // Only normal processors (resolve) catch and reject exceptions
3825 process = special ?
3826 mightThrow :
3827 function() {
3828 try {
3829 mightThrow();
3830 } catch ( e ) {
3831
3832 if ( jQuery.Deferred.exceptionHook ) {
3833 jQuery.Deferred.exceptionHook( e,
3834 process.stackTrace );
3835 }
3836
3837 // Support: Promises/A+ section 2.3.3.3.4.1
3838 // https://promisesaplus.com/#point-61
3839 // Ignore post-resolution exceptions
3840 if ( depth + 1 >= maxDepth ) {
3841
3842 // Only substitute handlers pass on context
3843 // and multiple values (non-spec behavior)
3844 if ( handler !== Thrower ) {
3845 that = undefined;
3846 args = [ e ];
3847 }
3848
3849 deferred.rejectWith( that, args );
3850 }
3851 }
3852 };
3853
3854 // Support: Promises/A+ section 2.3.3.3.1
3855 // https://promisesaplus.com/#point-57
3856 // Re-resolve promises immediately to dodge false rejection from
3857 // subsequent errors
3858 if ( depth ) {
3859 process();
3860 } else {
3861
3862 // Call an optional hook to record the stack, in case of exception
3863 // since it's otherwise lost when execution goes async
3864 if ( jQuery.Deferred.getStackHook ) {
3865 process.stackTrace = jQuery.Deferred.getStackHook();
3866 }
3867 window.setTimeout( process );
3868 }
3869 };
3870 }
3871
3872 return jQuery.Deferred( function( newDefer ) {
3873
3874 // progress_handlers.add( ... )
3875 tuples[ 0 ][ 3 ].add(
3876 resolve(
3877 0,
3878 newDefer,
3879 isFunction( onProgress ) ?
3880 onProgress :
3881 Identity,
3882 newDefer.notifyWith
3883 )
3884 );
3885
3886 // fulfilled_handlers.add( ... )
3887 tuples[ 1 ][ 3 ].add(
3888 resolve(
3889 0,
3890 newDefer,
3891 isFunction( onFulfilled ) ?
3892 onFulfilled :
3893 Identity
3894 )
3895 );
3896
3897 // rejected_handlers.add( ... )
3898 tuples[ 2 ][ 3 ].add(
3899 resolve(
3900 0,
3901 newDefer,
3902 isFunction( onRejected ) ?
3903 onRejected :
3904 Thrower
3905 )
3906 );
3907 } ).promise();
3908 },
3909
3910 // Get a promise for this deferred
3911 // If obj is provided, the promise aspect is added to the object
3912 promise: function( obj ) {
3913 return obj != null ? jQuery.extend( obj, promise ) : promise;
3914 }
3915 },
3916 deferred = {};
3917
3918 // Add list-specific methods
3919 jQuery.each( tuples, function( i, tuple ) {
3920 var list = tuple[ 2 ],
3921 stateString = tuple[ 5 ];
3922
3923 // promise.progress = list.add
3924 // promise.done = list.add
3925 // promise.fail = list.add
3926 promise[ tuple[ 1 ] ] = list.add;
3927
3928 // Handle state
3929 if ( stateString ) {
3930 list.add(
3931 function() {
3932
3933 // state = "resolved" (i.e., fulfilled)
3934 // state = "rejected"
3935 state = stateString;
3936 },
3937
3938 // rejected_callbacks.disable
3939 // fulfilled_callbacks.disable
3940 tuples[ 3 - i ][ 2 ].disable,
3941
3942 // rejected_handlers.disable
3943 // fulfilled_handlers.disable
3944 tuples[ 3 - i ][ 3 ].disable,
3945
3946 // progress_callbacks.lock
3947 tuples[ 0 ][ 2 ].lock,
3948
3949 // progress_handlers.lock
3950 tuples[ 0 ][ 3 ].lock
3951 );
3952 }
3953
3954 // progress_handlers.fire
3955 // fulfilled_handlers.fire
3956 // rejected_handlers.fire
3957 list.add( tuple[ 3 ].fire );
3958
3959 // deferred.notify = function() { deferred.notifyWith(...) }
3960 // deferred.resolve = function() { deferred.resolveWith(...) }
3961 // deferred.reject = function() { deferred.rejectWith(...) }
3962 deferred[ tuple[ 0 ] ] = function() {
3963 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
3964 return this;
3965 };
3966
3967 // deferred.notifyWith = list.fireWith
3968 // deferred.resolveWith = list.fireWith
3969 // deferred.rejectWith = list.fireWith
3970 deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3971 } );
3972
3973 // Make the deferred a promise
3974 promise.promise( deferred );
3975
3976 // Call given func if any
3977 if ( func ) {
3978 func.call( deferred, deferred );
3979 }
3980
3981 // All done!
3982 return deferred;
3983 },
3984
3985 // Deferred helper
3986 when: function( singleValue ) {
3987 var
3988
3989 // count of uncompleted subordinates
3990 remaining = arguments.length,
3991
3992 // count of unprocessed arguments
3993 i = remaining,
3994
3995 // subordinate fulfillment data
3996 resolveContexts = Array( i ),
3997 resolveValues = slice.call( arguments ),
3998
3999 // the master Deferred
4000 master = jQuery.Deferred(),
4001
4002 // subordinate callback factory
4003 updateFunc = function( i ) {
4004 return function( value ) {
4005 resolveContexts[ i ] = this;
4006 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
4007 if ( !( --remaining ) ) {
4008 master.resolveWith( resolveContexts, resolveValues );
4009 }
4010 };
4011 };
4012
4013 // Single- and empty arguments are adopted like Promise.resolve
4014 if ( remaining <= 1 ) {
4015 adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
4016 !remaining );
4017
4018 // Use .then() to unwrap secondary thenables (cf. gh-3000)
4019 if ( master.state() === "pending" ||
4020 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
4021
4022 return master.then();
4023 }
4024 }
4025
4026 // Multiple arguments are aggregated like Promise.all array elements
4027 while ( i-- ) {
4028 adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
4029 }
4030
4031 return master.promise();
4032 }
4033 } );
4034
4035
4036 // These usually indicate a programmer mistake during development,
4037 // warn about them ASAP rather than swallowing them by default.
4038 var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
4039
4040 jQuery.Deferred.exceptionHook = function( error, stack ) {
4041
4042 // Support: IE 8 - 9 only
4043 // Console exists when dev tools are open, which can happen at any time
4044 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
4045 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
4046 }
4047 };
4048
4049
4050
4051
4052 jQuery.readyException = function( error ) {
4053 window.setTimeout( function() {
4054 throw error;
4055 } );
4056 };
4057
4058
4059
4060
4061 // The deferred used on DOM ready
4062 var readyList = jQuery.Deferred();
4063
4064 jQuery.fn.ready = function( fn ) {
4065
4066 readyList
4067 .then( fn )
4068
4069 // Wrap jQuery.readyException in a function so that the lookup
4070 // happens at the time of error handling instead of callback
4071 // registration.
4072 .catch( function( error ) {
4073 jQuery.readyException( error );
4074 } );
4075
4076 return this;
4077 };
4078
4079 jQuery.extend( {
4080
4081 // Is the DOM ready to be used? Set to true once it occurs.
4082 isReady: false,
4083
4084 // A counter to track how many items to wait for before
4085 // the ready event fires. See #6781
4086 readyWait: 1,
4087
4088 // Handle when the DOM is ready
4089 ready: function( wait ) {
4090
4091 // Abort if there are pending holds or we're already ready
4092 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
4093 return;
4094 }
4095
4096 // Remember that the DOM is ready
4097 jQuery.isReady = true;
4098
4099 // If a normal DOM Ready event fired, decrement, and wait if need be
4100 if ( wait !== true && --jQuery.readyWait > 0 ) {
4101 return;
4102 }
4103
4104 // If there are functions bound, to execute
4105 readyList.resolveWith( document, [ jQuery ] );
4106 }
4107 } );
4108
4109 jQuery.ready.then = readyList.then;
4110
4111 // The ready event handler and self cleanup method
4112 function completed() {
4113 document.removeEventListener( "DOMContentLoaded", completed );
4114 window.removeEventListener( "load", completed );
4115 jQuery.ready();
4116 }
4117
4118 // Catch cases where $(document).ready() is called
4119 // after the browser event has already occurred.
4120 // Support: IE <=9 - 10 only
4121 // Older IE sometimes signals "interactive" too soon
4122 if ( document.readyState === "complete" ||
4123 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
4124
4125 // Handle it asynchronously to allow scripts the opportunity to delay ready
4126 window.setTimeout( jQuery.ready );
4127
4128 } else {
4129
4130 // Use the handy event callback
4131 document.addEventListener( "DOMContentLoaded", completed );
4132
4133 // A fallback to window.onload, that will always work
4134 window.addEventListener( "load", completed );
4135 }
4136
4137
4138
4139
4140 // Multifunctional method to get and set values of a collection
4141 // The value/s can optionally be executed if it's a function
4142 var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4143 var i = 0,
4144 len = elems.length,
4145 bulk = key == null;
4146
4147 // Sets many values
4148 if ( toType( key ) === "object" ) {
4149 chainable = true;
4150 for ( i in key ) {
4151 access( elems, fn, i, key[ i ], true, emptyGet, raw );
4152 }
4153
4154 // Sets one value
4155 } else if ( value !== undefined ) {
4156 chainable = true;
4157
4158 if ( !isFunction( value ) ) {
4159 raw = true;
4160 }
4161
4162 if ( bulk ) {
4163
4164 // Bulk operations run against the entire set
4165 if ( raw ) {
4166 fn.call( elems, value );
4167 fn = null;
4168
4169 // ...except when executing function values
4170 } else {
4171 bulk = fn;
4172 fn = function( elem, _key, value ) {
4173 return bulk.call( jQuery( elem ), value );
4174 };
4175 }
4176 }
4177
4178 if ( fn ) {
4179 for ( ; i < len; i++ ) {
4180 fn(
4181 elems[ i ], key, raw ?
4182 value :
4183 value.call( elems[ i ], i, fn( elems[ i ], key ) )
4184 );
4185 }
4186 }
4187 }
4188
4189 if ( chainable ) {
4190 return elems;
4191 }
4192
4193 // Gets
4194 if ( bulk ) {
4195 return fn.call( elems );
4196 }
4197
4198 return len ? fn( elems[ 0 ], key ) : emptyGet;
4199 };
4200
4201
4202 // Matches dashed string for camelizing
4203 var rmsPrefix = /^-ms-/,
4204 rdashAlpha = /-([a-z])/g;
4205
4206 // Used by camelCase as callback to replace()
4207 function fcamelCase( _all, letter ) {
4208 return letter.toUpperCase();
4209 }
4210
4211 // Convert dashed to camelCase; used by the css and data modules
4212 // Support: IE <=9 - 11, Edge 12 - 15
4213 // Microsoft forgot to hump their vendor prefix (#9572)
4214 function camelCase( string ) {
4215 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
4216 }
4217 var acceptData = function( owner ) {
4218
4219 // Accepts only:
4220 // - Node
4221 // - Node.ELEMENT_NODE
4222 // - Node.DOCUMENT_NODE
4223 // - Object
4224 // - Any
4225 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
4226 };
4227
4228
4229
4230
4231 function Data() {
4232 this.expando = jQuery.expando + Data.uid++;
4233 }
4234
4235 Data.uid = 1;
4236
4237 Data.prototype = {
4238
4239 cache: function( owner ) {
4240
4241 // Check if the owner object already has a cache
4242 var value = owner[ this.expando ];
4243
4244 // If not, create one
4245 if ( !value ) {
4246 value = {};
4247
4248 // We can accept data for non-element nodes in modern browsers,
4249 // but we should not, see #8335.
4250 // Always return an empty object.
4251 if ( acceptData( owner ) ) {
4252
4253 // If it is a node unlikely to be stringify-ed or looped over
4254 // use plain assignment
4255 if ( owner.nodeType ) {
4256 owner[ this.expando ] = value;
4257
4258 // Otherwise secure it in a non-enumerable property
4259 // configurable must be true to allow the property to be
4260 // deleted when data is removed
4261 } else {
4262 Object.defineProperty( owner, this.expando, {
4263 value: value,
4264 configurable: true
4265 } );
4266 }
4267 }
4268 }
4269
4270 return value;
4271 },
4272 set: function( owner, data, value ) {
4273 var prop,
4274 cache = this.cache( owner );
4275
4276 // Handle: [ owner, key, value ] args
4277 // Always use camelCase key (gh-2257)
4278 if ( typeof data === "string" ) {
4279 cache[ camelCase( data ) ] = value;
4280
4281 // Handle: [ owner, { properties } ] args
4282 } else {
4283
4284 // Copy the properties one-by-one to the cache object
4285 for ( prop in data ) {
4286 cache[ camelCase( prop ) ] = data[ prop ];
4287 }
4288 }
4289 return cache;
4290 },
4291 get: function( owner, key ) {
4292 return key === undefined ?
4293 this.cache( owner ) :
4294
4295 // Always use camelCase key (gh-2257)
4296 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
4297 },
4298 access: function( owner, key, value ) {
4299
4300 // In cases where either:
4301 //
4302 // 1. No key was specified
4303 // 2. A string key was specified, but no value provided
4304 //
4305 // Take the "read" path and allow the get method to determine
4306 // which value to return, respectively either:
4307 //
4308 // 1. The entire cache object
4309 // 2. The data stored at the key
4310 //
4311 if ( key === undefined ||
4312 ( ( key && typeof key === "string" ) && value === undefined ) ) {
4313
4314 return this.get( owner, key );
4315 }
4316
4317 // When the key is not a string, or both a key and value
4318 // are specified, set or extend (existing objects) with either:
4319 //
4320 // 1. An object of properties
4321 // 2. A key and value
4322 //
4323 this.set( owner, key, value );
4324
4325 // Since the "set" path can have two possible entry points
4326 // return the expected data based on which path was taken[*]
4327 return value !== undefined ? value : key;
4328 },
4329 remove: function( owner, key ) {
4330 var i,
4331 cache = owner[ this.expando ];
4332
4333 if ( cache === undefined ) {
4334 return;
4335 }
4336
4337 if ( key !== undefined ) {
4338
4339 // Support array or space separated string of keys
4340 if ( Array.isArray( key ) ) {
4341
4342 // If key is an array of keys...
4343 // We always set camelCase keys, so remove that.
4344 key = key.map( camelCase );
4345 } else {
4346 key = camelCase( key );
4347
4348 // If a key with the spaces exists, use it.
4349 // Otherwise, create an array by matching non-whitespace
4350 key = key in cache ?
4351 [ key ] :
4352 ( key.match( rnothtmlwhite ) || [] );
4353 }
4354
4355 i = key.length;
4356
4357 while ( i-- ) {
4358 delete cache[ key[ i ] ];
4359 }
4360 }
4361
4362 // Remove the expando if there's no more data
4363 if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4364
4365 // Support: Chrome <=35 - 45
4366 // Webkit & Blink performance suffers when deleting properties
4367 // from DOM nodes, so set to undefined instead
4368 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4369 if ( owner.nodeType ) {
4370 owner[ this.expando ] = undefined;
4371 } else {
4372 delete owner[ this.expando ];
4373 }
4374 }
4375 },
4376 hasData: function( owner ) {
4377 var cache = owner[ this.expando ];
4378 return cache !== undefined && !jQuery.isEmptyObject( cache );
4379 }
4380 };
4381 var dataPriv = new Data();
4382
4383 var dataUser = new Data();
4384
4385
4386
4387 // Implementation Summary
4388 //
4389 // 1. Enforce API surface and semantic compatibility with 1.9.x branch
4390 // 2. Improve the module's maintainability by reducing the storage
4391 // paths to a single mechanism.
4392 // 3. Use the same single mechanism to support "private" and "user" data.
4393 // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4394 // 5. Avoid exposing implementation details on user objects (eg. expando properties)
4395 // 6. Provide a clear path for implementation upgrade to WeakMap in 2014
4396
4397 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4398 rmultiDash = /[A-Z]/g;
4399
4400 function getData( data ) {
4401 if ( data === "true" ) {
4402 return true;
4403 }
4404
4405 if ( data === "false" ) {
4406 return false;
4407 }
4408
4409 if ( data === "null" ) {
4410 return null;
4411 }
4412
4413 // Only convert to a number if it doesn't change the string
4414 if ( data === +data + "" ) {
4415 return +data;
4416 }
4417
4418 if ( rbrace.test( data ) ) {
4419 return JSON.parse( data );
4420 }
4421
4422 return data;
4423 }
4424
4425 function dataAttr( elem, key, data ) {
4426 var name;
4427
4428 // If nothing was found internally, try to fetch any
4429 // data from the HTML5 data-* attribute
4430 if ( data === undefined && elem.nodeType === 1 ) {
4431 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
4432 data = elem.getAttribute( name );
4433
4434 if ( typeof data === "string" ) {
4435 try {
4436 data = getData( data );
4437 } catch ( e ) {}
4438
4439 // Make sure we set the data so it isn't changed later
4440 dataUser.set( elem, key, data );
4441 } else {
4442 data = undefined;
4443 }
4444 }
4445 return data;
4446 }
4447
4448 jQuery.extend( {
4449 hasData: function( elem ) {
4450 return dataUser.hasData( elem ) || dataPriv.hasData( elem );
4451 },
4452
4453 data: function( elem, name, data ) {
4454 return dataUser.access( elem, name, data );
4455 },
4456
4457 removeData: function( elem, name ) {
4458 dataUser.remove( elem, name );
4459 },
4460
4461 // TODO: Now that all calls to _data and _removeData have been replaced
4462 // with direct calls to dataPriv methods, these can be deprecated.
4463 _data: function( elem, name, data ) {
4464 return dataPriv.access( elem, name, data );
4465 },
4466
4467 _removeData: function( elem, name ) {
4468 dataPriv.remove( elem, name );
4469 }
4470 } );
4471
4472 jQuery.fn.extend( {
4473 data: function( key, value ) {
4474 var i, name, data,
4475 elem = this[ 0 ],
4476 attrs = elem && elem.attributes;
4477
4478 // Gets all values
4479 if ( key === undefined ) {
4480 if ( this.length ) {
4481 data = dataUser.get( elem );
4482
4483 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
4484 i = attrs.length;
4485 while ( i-- ) {
4486
4487 // Support: IE 11 only
4488 // The attrs elements can be null (#14894)
4489 if ( attrs[ i ] ) {
4490 name = attrs[ i ].name;
4491 if ( name.indexOf( "data-" ) === 0 ) {
4492 name = camelCase( name.slice( 5 ) );
4493 dataAttr( elem, name, data[ name ] );
4494 }
4495 }
4496 }
4497 dataPriv.set( elem, "hasDataAttrs", true );
4498 }
4499 }
4500
4501 return data;
4502 }
4503
4504 // Sets multiple values
4505 if ( typeof key === "object" ) {
4506 return this.each( function() {
4507 dataUser.set( this, key );
4508 } );
4509 }
4510
4511 return access( this, function( value ) {
4512 var data;
4513
4514 // The calling jQuery object (element matches) is not empty
4515 // (and therefore has an element appears at this[ 0 ]) and the
4516 // `value` parameter was not undefined. An empty jQuery object
4517 // will result in `undefined` for elem = this[ 0 ] which will
4518 // throw an exception if an attempt to read a data cache is made.
4519 if ( elem && value === undefined ) {
4520
4521 // Attempt to get data from the cache
4522 // The key will always be camelCased in Data
4523 data = dataUser.get( elem, key );
4524 if ( data !== undefined ) {
4525 return data;
4526 }
4527
4528 // Attempt to "discover" the data in
4529 // HTML5 custom data-* attrs
4530 data = dataAttr( elem, key );
4531 if ( data !== undefined ) {
4532 return data;
4533 }
4534
4535 // We tried really hard, but the data doesn't exist.
4536 return;
4537 }
4538
4539 // Set the data...
4540 this.each( function() {
4541
4542 // We always store the camelCased key
4543 dataUser.set( this, key, value );
4544 } );
4545 }, null, value, arguments.length > 1, null, true );
4546 },
4547
4548 removeData: function( key ) {
4549 return this.each( function() {
4550 dataUser.remove( this, key );
4551 } );
4552 }
4553 } );
4554
4555
4556 jQuery.extend( {
4557 queue: function( elem, type, data ) {
4558 var queue;
4559
4560 if ( elem ) {
4561 type = ( type || "fx" ) + "queue";
4562 queue = dataPriv.get( elem, type );
4563
4564 // Speed up dequeue by getting out quickly if this is just a lookup
4565 if ( data ) {
4566 if ( !queue || Array.isArray( data ) ) {
4567 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4568 } else {
4569 queue.push( data );
4570 }
4571 }
4572 return queue || [];
4573 }
4574 },
4575
4576 dequeue: function( elem, type ) {
4577 type = type || "fx";
4578
4579 var queue = jQuery.queue( elem, type ),
4580 startLength = queue.length,
4581 fn = queue.shift(),
4582 hooks = jQuery._queueHooks( elem, type ),
4583 next = function() {
4584 jQuery.dequeue( elem, type );
4585 };
4586
4587 // If the fx queue is dequeued, always remove the progress sentinel
4588 if ( fn === "inprogress" ) {
4589 fn = queue.shift();
4590 startLength--;
4591 }
4592
4593 if ( fn ) {
4594
4595 // Add a progress sentinel to prevent the fx queue from being
4596 // automatically dequeued
4597 if ( type === "fx" ) {
4598 queue.unshift( "inprogress" );
4599 }
4600
4601 // Clear up the last queue stop function
4602 delete hooks.stop;
4603 fn.call( elem, next, hooks );
4604 }
4605
4606 if ( !startLength && hooks ) {
4607 hooks.empty.fire();
4608 }
4609 },
4610
4611 // Not public - generate a queueHooks object, or return the current one
4612 _queueHooks: function( elem, type ) {
4613 var key = type + "queueHooks";
4614 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4615 empty: jQuery.Callbacks( "once memory" ).add( function() {
4616 dataPriv.remove( elem, [ type + "queue", key ] );
4617 } )
4618 } );
4619 }
4620 } );
4621
4622 jQuery.fn.extend( {
4623 queue: function( type, data ) {
4624 var setter = 2;
4625
4626 if ( typeof type !== "string" ) {
4627 data = type;
4628 type = "fx";
4629 setter--;
4630 }
4631
4632 if ( arguments.length < setter ) {
4633 return jQuery.queue( this[ 0 ], type );
4634 }
4635
4636 return data === undefined ?
4637 this :
4638 this.each( function() {
4639 var queue = jQuery.queue( this, type, data );
4640
4641 // Ensure a hooks for this queue
4642 jQuery._queueHooks( this, type );
4643
4644 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4645 jQuery.dequeue( this, type );
4646 }
4647 } );
4648 },
4649 dequeue: function( type ) {
4650 return this.each( function() {
4651 jQuery.dequeue( this, type );
4652 } );
4653 },
4654 clearQueue: function( type ) {
4655 return this.queue( type || "fx", [] );
4656 },
4657
4658 // Get a promise resolved when queues of a certain type
4659 // are emptied (fx is the type by default)
4660 promise: function( type, obj ) {
4661 var tmp,
4662 count = 1,
4663 defer = jQuery.Deferred(),
4664 elements = this,
4665 i = this.length,
4666 resolve = function() {
4667 if ( !( --count ) ) {
4668 defer.resolveWith( elements, [ elements ] );
4669 }
4670 };
4671
4672 if ( typeof type !== "string" ) {
4673 obj = type;
4674 type = undefined;
4675 }
4676 type = type || "fx";
4677
4678 while ( i-- ) {
4679 tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4680 if ( tmp && tmp.empty ) {
4681 count++;
4682 tmp.empty.add( resolve );
4683 }
4684 }
4685 resolve();
4686 return defer.promise( obj );
4687 }
4688 } );
4689 var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4690
4691 var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4692
4693
4694 var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4695
4696 var documentElement = document.documentElement;
4697
4698
4699
4700 var isAttached = function( elem ) {
4701 return jQuery.contains( elem.ownerDocument, elem );
4702 },
4703 composed = { composed: true };
4704
4705 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
4706 // Check attachment across shadow DOM boundaries when possible (gh-3504)
4707 // Support: iOS 10.0-10.2 only
4708 // Early iOS 10 versions support `attachShadow` but not `getRootNode`,
4709 // leading to errors. We need to check for `getRootNode`.
4710 if ( documentElement.getRootNode ) {
4711 isAttached = function( elem ) {
4712 return jQuery.contains( elem.ownerDocument, elem ) ||
4713 elem.getRootNode( composed ) === elem.ownerDocument;
4714 };
4715 }
4716 var isHiddenWithinTree = function( elem, el ) {
4717
4718 // isHiddenWithinTree might be called from jQuery#filter function;
4719 // in that case, element will be second argument
4720 elem = el || elem;
4721
4722 // Inline style trumps all
4723 return elem.style.display === "none" ||
4724 elem.style.display === "" &&
4725
4726 // Otherwise, check computed style
4727 // Support: Firefox <=43 - 45
4728 // Disconnected elements can have computed display: none, so first confirm that elem is
4729 // in the document.
4730 isAttached( elem ) &&
4731
4732 jQuery.css( elem, "display" ) === "none";
4733 };
4734
4735
4736
4737 function adjustCSS( elem, prop, valueParts, tween ) {
4738 var adjusted, scale,
4739 maxIterations = 20,
4740 currentValue = tween ?
4741 function() {
4742 return tween.cur();
4743 } :
4744 function() {
4745 return jQuery.css( elem, prop, "" );
4746 },
4747 initial = currentValue(),
4748 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4749
4750 // Starting value computation is required for potential unit mismatches
4751 initialInUnit = elem.nodeType &&
4752 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4753 rcssNum.exec( jQuery.css( elem, prop ) );
4754
4755 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4756
4757 // Support: Firefox <=54
4758 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
4759 initial = initial / 2;
4760
4761 // Trust units reported by jQuery.css
4762 unit = unit || initialInUnit[ 3 ];
4763
4764 // Iteratively approximate from a nonzero starting point
4765 initialInUnit = +initial || 1;
4766
4767 while ( maxIterations-- ) {
4768
4769 // Evaluate and update our best guess (doubling guesses that zero out).
4770 // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
4771 jQuery.style( elem, prop, initialInUnit + unit );
4772 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
4773 maxIterations = 0;
4774 }
4775 initialInUnit = initialInUnit / scale;
4776
4777 }
4778
4779 initialInUnit = initialInUnit * 2;
4780 jQuery.style( elem, prop, initialInUnit + unit );
4781
4782 // Make sure we update the tween properties later on
4783 valueParts = valueParts || [];
4784 }
4785
4786 if ( valueParts ) {
4787 initialInUnit = +initialInUnit || +initial || 0;
4788
4789 // Apply relative offset (+=/-=) if specified
4790 adjusted = valueParts[ 1 ] ?
4791 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4792 +valueParts[ 2 ];
4793 if ( tween ) {
4794 tween.unit = unit;
4795 tween.start = initialInUnit;
4796 tween.end = adjusted;
4797 }
4798 }
4799 return adjusted;
4800 }
4801
4802
4803 var defaultDisplayMap = {};
4804
4805 function getDefaultDisplay( elem ) {
4806 var temp,
4807 doc = elem.ownerDocument,
4808 nodeName = elem.nodeName,
4809 display = defaultDisplayMap[ nodeName ];
4810
4811 if ( display ) {
4812 return display;
4813 }
4814
4815 temp = doc.body.appendChild( doc.createElement( nodeName ) );
4816 display = jQuery.css( temp, "display" );
4817
4818 temp.parentNode.removeChild( temp );
4819
4820 if ( display === "none" ) {
4821 display = "block";
4822 }
4823 defaultDisplayMap[ nodeName ] = display;
4824
4825 return display;
4826 }
4827
4828 function showHide( elements, show ) {
4829 var display, elem,
4830 values = [],
4831 index = 0,
4832 length = elements.length;
4833
4834 // Determine new display value for elements that need to change
4835 for ( ; index < length; index++ ) {
4836 elem = elements[ index ];
4837 if ( !elem.style ) {
4838 continue;
4839 }
4840
4841 display = elem.style.display;
4842 if ( show ) {
4843
4844 // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4845 // check is required in this first loop unless we have a nonempty display value (either
4846 // inline or about-to-be-restored)
4847 if ( display === "none" ) {
4848 values[ index ] = dataPriv.get( elem, "display" ) || null;
4849 if ( !values[ index ] ) {
4850 elem.style.display = "";
4851 }
4852 }
4853 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
4854 values[ index ] = getDefaultDisplay( elem );
4855 }
4856 } else {
4857 if ( display !== "none" ) {
4858 values[ index ] = "none";
4859
4860 // Remember what we're overwriting
4861 dataPriv.set( elem, "display", display );
4862 }
4863 }
4864 }
4865
4866 // Set the display of the elements in a second loop to avoid constant reflow
4867 for ( index = 0; index < length; index++ ) {
4868 if ( values[ index ] != null ) {
4869 elements[ index ].style.display = values[ index ];
4870 }
4871 }
4872
4873 return elements;
4874 }
4875
4876 jQuery.fn.extend( {
4877 show: function() {
4878 return showHide( this, true );
4879 },
4880 hide: function() {
4881 return showHide( this );
4882 },
4883 toggle: function( state ) {
4884 if ( typeof state === "boolean" ) {
4885 return state ? this.show() : this.hide();
4886 }
4887
4888 return this.each( function() {
4889 if ( isHiddenWithinTree( this ) ) {
4890 jQuery( this ).show();
4891 } else {
4892 jQuery( this ).hide();
4893 }
4894 } );
4895 }
4896 } );
4897 var rcheckableType = ( /^(?:checkbox|radio)$/i );
4898
4899 var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
4900
4901 var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
4902
4903
4904
4905 ( function() {
4906 var fragment = document.createDocumentFragment(),
4907 div = fragment.appendChild( document.createElement( "div" ) ),
4908 input = document.createElement( "input" );
4909
4910 // Support: Android 4.0 - 4.3 only
4911 // Check state lost if the name is set (#11217)
4912 // Support: Windows Web Apps (WWA)
4913 // `name` and `type` must use .setAttribute for WWA (#14901)
4914 input.setAttribute( "type", "radio" );
4915 input.setAttribute( "checked", "checked" );
4916 input.setAttribute( "name", "t" );
4917
4918 div.appendChild( input );
4919
4920 // Support: Android <=4.1 only
4921 // Older WebKit doesn't clone checked state correctly in fragments
4922 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4923
4924 // Support: IE <=11 only
4925 // Make sure textarea (and checkbox) defaultValue is properly cloned
4926 div.innerHTML = "<textarea>x</textarea>";
4927 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4928
4929 // Support: IE <=9 only
4930 // IE <=9 replaces <option> tags with their contents when inserted outside of
4931 // the select element.
4932 div.innerHTML = "<option></option>";
4933 support.option = !!div.lastChild;
4934 } )();
4935
4936
4937 // We have to close these tags to support XHTML (#13200)
4938 var wrapMap = {
4939
4940 // XHTML parsers do not magically insert elements in the
4941 // same way that tag soup parsers do. So we cannot shorten
4942 // this by omitting <tbody> or other required elements.
4943 thead: [ 1, "<table>", "</table>" ],
4944 col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4945 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4946 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4947
4948 _default: [ 0, "", "" ]
4949 };
4950
4951 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4952 wrapMap.th = wrapMap.td;
4953
4954 // Support: IE <=9 only
4955 if ( !support.option ) {
4956 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
4957 }
4958
4959
4960 function getAll( context, tag ) {
4961
4962 // Support: IE <=9 - 11 only
4963 // Use typeof to avoid zero-argument method invocation on host objects (#15151)
4964 var ret;
4965
4966 if ( typeof context.getElementsByTagName !== "undefined" ) {
4967 ret = context.getElementsByTagName( tag || "*" );
4968
4969 } else if ( typeof context.querySelectorAll !== "undefined" ) {
4970 ret = context.querySelectorAll( tag || "*" );
4971
4972 } else {
4973 ret = [];
4974 }
4975
4976 if ( tag === undefined || tag && nodeName( context, tag ) ) {
4977 return jQuery.merge( [ context ], ret );
4978 }
4979
4980 return ret;
4981 }
4982
4983
4984 // Mark scripts as having already been evaluated
4985 function setGlobalEval( elems, refElements ) {
4986 var i = 0,
4987 l = elems.length;
4988
4989 for ( ; i < l; i++ ) {
4990 dataPriv.set(
4991 elems[ i ],
4992 "globalEval",
4993 !refElements || dataPriv.get( refElements[ i ], "globalEval" )
4994 );
4995 }
4996 }
4997
4998
4999 var rhtml = /<|&#?\w+;/;
5000
5001 function buildFragment( elems, context, scripts, selection, ignored ) {
5002 var elem, tmp, tag, wrap, attached, j,
5003 fragment = context.createDocumentFragment(),
5004 nodes = [],
5005 i = 0,
5006 l = elems.length;
5007
5008 for ( ; i < l; i++ ) {
5009 elem = elems[ i ];
5010
5011 if ( elem || elem === 0 ) {
5012
5013 // Add nodes directly
5014 if ( toType( elem ) === "object" ) {
5015
5016 // Support: Android <=4.0 only, PhantomJS 1 only
5017 // push.apply(_, arraylike) throws on ancient WebKit
5018 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5019
5020 // Convert non-html into a text node
5021 } else if ( !rhtml.test( elem ) ) {
5022 nodes.push( context.createTextNode( elem ) );
5023
5024 // Convert html into DOM nodes
5025 } else {
5026 tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
5027
5028 // Deserialize a standard representation
5029 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5030 wrap = wrapMap[ tag ] || wrapMap._default;
5031 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
5032
5033 // Descend through wrappers to the right content
5034 j = wrap[ 0 ];
5035 while ( j-- ) {
5036 tmp = tmp.lastChild;
5037 }
5038
5039 // Support: Android <=4.0 only, PhantomJS 1 only
5040 // push.apply(_, arraylike) throws on ancient WebKit
5041 jQuery.merge( nodes, tmp.childNodes );
5042
5043 // Remember the top-level container
5044 tmp = fragment.firstChild;
5045
5046 // Ensure the created nodes are orphaned (#12392)
5047 tmp.textContent = "";
5048 }
5049 }
5050 }
5051
5052 // Remove wrapper from fragment
5053 fragment.textContent = "";
5054
5055 i = 0;
5056 while ( ( elem = nodes[ i++ ] ) ) {
5057
5058 // Skip elements already in the context collection (trac-4087)
5059 if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
5060 if ( ignored ) {
5061 ignored.push( elem );
5062 }
5063 continue;
5064 }
5065
5066 attached = isAttached( elem );
5067
5068 // Append to fragment
5069 tmp = getAll( fragment.appendChild( elem ), "script" );
5070
5071 // Preserve script evaluation history
5072 if ( attached ) {
5073 setGlobalEval( tmp );
5074 }
5075
5076 // Capture executables
5077 if ( scripts ) {
5078 j = 0;
5079 while ( ( elem = tmp[ j++ ] ) ) {
5080 if ( rscriptType.test( elem.type || "" ) ) {
5081 scripts.push( elem );
5082 }
5083 }
5084 }
5085 }
5086
5087 return fragment;
5088 }
5089
5090
5091 var
5092 rkeyEvent = /^key/,
5093 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
5094 rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
5095
5096 function returnTrue() {
5097 return true;
5098 }
5099
5100 function returnFalse() {
5101 return false;
5102 }
5103
5104 // Support: IE <=9 - 11+
5105 // focus() and blur() are asynchronous, except when they are no-op.
5106 // So expect focus to be synchronous when the element is already active,
5107 // and blur to be synchronous when the element is not already active.
5108 // (focus and blur are always synchronous in other supported browsers,
5109 // this just defines when we can count on it).
5110 function expectSync( elem, type ) {
5111 return ( elem === safeActiveElement() ) === ( type === "focus" );
5112 }
5113
5114 // Support: IE <=9 only
5115 // Accessing document.activeElement can throw unexpectedly
5116 // https://bugs.jquery.com/ticket/13393
5117 function safeActiveElement() {
5118 try {
5119 return document.activeElement;
5120 } catch ( err ) { }
5121 }
5122
5123 function on( elem, types, selector, data, fn, one ) {
5124 var origFn, type;
5125
5126 // Types can be a map of types/handlers
5127 if ( typeof types === "object" ) {
5128
5129 // ( types-Object, selector, data )
5130 if ( typeof selector !== "string" ) {
5131
5132 // ( types-Object, data )
5133 data = data || selector;
5134 selector = undefined;
5135 }
5136 for ( type in types ) {
5137 on( elem, type, selector, data, types[ type ], one );
5138 }
5139 return elem;
5140 }
5141
5142 if ( data == null && fn == null ) {
5143
5144 // ( types, fn )
5145 fn = selector;
5146 data = selector = undefined;
5147 } else if ( fn == null ) {
5148 if ( typeof selector === "string" ) {
5149
5150 // ( types, selector, fn )
5151 fn = data;
5152 data = undefined;
5153 } else {
5154
5155 // ( types, data, fn )
5156 fn = data;
5157 data = selector;
5158 selector = undefined;
5159 }
5160 }
5161 if ( fn === false ) {
5162 fn = returnFalse;
5163 } else if ( !fn ) {
5164 return elem;
5165 }
5166
5167 if ( one === 1 ) {
5168 origFn = fn;
5169 fn = function( event ) {
5170
5171 // Can use an empty set, since event contains the info
5172 jQuery().off( event );
5173 return origFn.apply( this, arguments );
5174 };
5175
5176 // Use same guid so caller can remove using origFn
5177 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5178 }
5179 return elem.each( function() {
5180 jQuery.event.add( this, types, fn, data, selector );
5181 } );
5182 }
5183
5184 /*
5185 * Helper functions for managing events -- not part of the public interface.
5186 * Props to Dean Edwards' addEvent library for many of the ideas.
5187 */
5188 jQuery.event = {
5189
5190 global: {},
5191
5192 add: function( elem, types, handler, data, selector ) {
5193
5194 var handleObjIn, eventHandle, tmp,
5195 events, t, handleObj,
5196 special, handlers, type, namespaces, origType,
5197 elemData = dataPriv.get( elem );
5198
5199 // Only attach events to objects that accept data
5200 if ( !acceptData( elem ) ) {
5201 return;
5202 }
5203
5204 // Caller can pass in an object of custom data in lieu of the handler
5205 if ( handler.handler ) {
5206 handleObjIn = handler;
5207 handler = handleObjIn.handler;
5208 selector = handleObjIn.selector;
5209 }
5210
5211 // Ensure that invalid selectors throw exceptions at attach time
5212 // Evaluate against documentElement in case elem is a non-element node (e.g., document)
5213 if ( selector ) {
5214 jQuery.find.matchesSelector( documentElement, selector );
5215 }
5216
5217 // Make sure that the handler has a unique ID, used to find/remove it later
5218 if ( !handler.guid ) {
5219 handler.guid = jQuery.guid++;
5220 }
5221
5222 // Init the element's event structure and main handler, if this is the first
5223 if ( !( events = elemData.events ) ) {
5224 events = elemData.events = Object.create( null );
5225 }
5226 if ( !( eventHandle = elemData.handle ) ) {
5227 eventHandle = elemData.handle = function( e ) {
5228
5229 // Discard the second event of a jQuery.event.trigger() and
5230 // when an event is called after a page has unloaded
5231 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
5232 jQuery.event.dispatch.apply( elem, arguments ) : undefined;
5233 };
5234 }
5235
5236 // Handle multiple events separated by a space
5237 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5238 t = types.length;
5239 while ( t-- ) {
5240 tmp = rtypenamespace.exec( types[ t ] ) || [];
5241 type = origType = tmp[ 1 ];
5242 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5243
5244 // There *must* be a type, no attaching namespace-only handlers
5245 if ( !type ) {
5246 continue;
5247 }
5248
5249 // If event changes its type, use the special event handlers for the changed type
5250 special = jQuery.event.special[ type ] || {};
5251
5252 // If selector defined, determine special event api type, otherwise given type
5253 type = ( selector ? special.delegateType : special.bindType ) || type;
5254
5255 // Update special based on newly reset type
5256 special = jQuery.event.special[ type ] || {};
5257
5258 // handleObj is passed to all event handlers
5259 handleObj = jQuery.extend( {
5260 type: type,
5261 origType: origType,
5262 data: data,
5263 handler: handler,
5264 guid: handler.guid,
5265 selector: selector,
5266 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
5267 namespace: namespaces.join( "." )
5268 }, handleObjIn );
5269
5270 // Init the event handler queue if we're the first
5271 if ( !( handlers = events[ type ] ) ) {
5272 handlers = events[ type ] = [];
5273 handlers.delegateCount = 0;
5274
5275 // Only use addEventListener if the special events handler returns false
5276 if ( !special.setup ||
5277 special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
5278
5279 if ( elem.addEventListener ) {
5280 elem.addEventListener( type, eventHandle );
5281 }
5282 }
5283 }
5284
5285 if ( special.add ) {
5286 special.add.call( elem, handleObj );
5287
5288 if ( !handleObj.handler.guid ) {
5289 handleObj.handler.guid = handler.guid;
5290 }
5291 }
5292
5293 // Add to the element's handler list, delegates in front
5294 if ( selector ) {
5295 handlers.splice( handlers.delegateCount++, 0, handleObj );
5296 } else {
5297 handlers.push( handleObj );
5298 }
5299
5300 // Keep track of which events have ever been used, for event optimization
5301 jQuery.event.global[ type ] = true;
5302 }
5303
5304 },
5305
5306 // Detach an event or set of events from an element
5307 remove: function( elem, types, handler, selector, mappedTypes ) {
5308
5309 var j, origCount, tmp,
5310 events, t, handleObj,
5311 special, handlers, type, namespaces, origType,
5312 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
5313
5314 if ( !elemData || !( events = elemData.events ) ) {
5315 return;
5316 }
5317
5318 // Once for each type.namespace in types; type may be omitted
5319 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5320 t = types.length;
5321 while ( t-- ) {
5322 tmp = rtypenamespace.exec( types[ t ] ) || [];
5323 type = origType = tmp[ 1 ];
5324 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5325
5326 // Unbind all events (on this namespace, if provided) for the element
5327 if ( !type ) {
5328 for ( type in events ) {
5329 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
5330 }
5331 continue;
5332 }
5333
5334 special = jQuery.event.special[ type ] || {};
5335 type = ( selector ? special.delegateType : special.bindType ) || type;
5336 handlers = events[ type ] || [];
5337 tmp = tmp[ 2 ] &&
5338 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
5339
5340 // Remove matching events
5341 origCount = j = handlers.length;
5342 while ( j-- ) {
5343 handleObj = handlers[ j ];
5344
5345 if ( ( mappedTypes || origType === handleObj.origType ) &&
5346 ( !handler || handler.guid === handleObj.guid ) &&
5347 ( !tmp || tmp.test( handleObj.namespace ) ) &&
5348 ( !selector || selector === handleObj.selector ||
5349 selector === "**" && handleObj.selector ) ) {
5350 handlers.splice( j, 1 );
5351
5352 if ( handleObj.selector ) {
5353 handlers.delegateCount--;
5354 }
5355 if ( special.remove ) {
5356 special.remove.call( elem, handleObj );
5357 }
5358 }
5359 }
5360
5361 // Remove generic event handler if we removed something and no more handlers exist
5362 // (avoids potential for endless recursion during removal of special event handlers)
5363 if ( origCount && !handlers.length ) {
5364 if ( !special.teardown ||
5365 special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5366
5367 jQuery.removeEvent( elem, type, elemData.handle );
5368 }
5369
5370 delete events[ type ];
5371 }
5372 }
5373
5374 // Remove data and the expando if it's no longer used
5375 if ( jQuery.isEmptyObject( events ) ) {
5376 dataPriv.remove( elem, "handle events" );
5377 }
5378 },
5379
5380 dispatch: function( nativeEvent ) {
5381
5382 var i, j, ret, matched, handleObj, handlerQueue,
5383 args = new Array( arguments.length ),
5384
5385 // Make a writable jQuery.Event from the native event object
5386 event = jQuery.event.fix( nativeEvent ),
5387
5388 handlers = (
5389 dataPriv.get( this, "events" ) || Object.create( null )
5390 )[ event.type ] || [],
5391 special = jQuery.event.special[ event.type ] || {};
5392
5393 // Use the fix-ed jQuery.Event rather than the (read-only) native event
5394 args[ 0 ] = event;
5395
5396 for ( i = 1; i < arguments.length; i++ ) {
5397 args[ i ] = arguments[ i ];
5398 }
5399
5400 event.delegateTarget = this;
5401
5402 // Call the preDispatch hook for the mapped type, and let it bail if desired
5403 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5404 return;
5405 }
5406
5407 // Determine handlers
5408 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5409
5410 // Run delegates first; they may want to stop propagation beneath us
5411 i = 0;
5412 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5413 event.currentTarget = matched.elem;
5414
5415 j = 0;
5416 while ( ( handleObj = matched.handlers[ j++ ] ) &&
5417 !event.isImmediatePropagationStopped() ) {
5418
5419 // If the event is namespaced, then each handler is only invoked if it is
5420 // specially universal or its namespaces are a superset of the event's.
5421 if ( !event.rnamespace || handleObj.namespace === false ||
5422 event.rnamespace.test( handleObj.namespace ) ) {
5423
5424 event.handleObj = handleObj;
5425 event.data = handleObj.data;
5426
5427 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5428 handleObj.handler ).apply( matched.elem, args );
5429
5430 if ( ret !== undefined ) {
5431 if ( ( event.result = ret ) === false ) {
5432 event.preventDefault();
5433 event.stopPropagation();
5434 }
5435 }
5436 }
5437 }
5438 }
5439
5440 // Call the postDispatch hook for the mapped type
5441 if ( special.postDispatch ) {
5442 special.postDispatch.call( this, event );
5443 }
5444
5445 return event.result;
5446 },
5447
5448 handlers: function( event, handlers ) {
5449 var i, handleObj, sel, matchedHandlers, matchedSelectors,
5450 handlerQueue = [],
5451 delegateCount = handlers.delegateCount,
5452 cur = event.target;
5453
5454 // Find delegate handlers
5455 if ( delegateCount &&
5456
5457 // Support: IE <=9
5458 // Black-hole SVG <use> instance trees (trac-13180)
5459 cur.nodeType &&
5460
5461 // Support: Firefox <=42
5462 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5463 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5464 // Support: IE 11 only
5465 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5466 !( event.type === "click" && event.button >= 1 ) ) {
5467
5468 for ( ; cur !== this; cur = cur.parentNode || this ) {
5469
5470 // Don't check non-elements (#13208)
5471 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5472 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
5473 matchedHandlers = [];
5474 matchedSelectors = {};
5475 for ( i = 0; i < delegateCount; i++ ) {
5476 handleObj = handlers[ i ];
5477
5478 // Don't conflict with Object.prototype properties (#13203)
5479 sel = handleObj.selector + " ";
5480
5481 if ( matchedSelectors[ sel ] === undefined ) {
5482 matchedSelectors[ sel ] = handleObj.needsContext ?
5483 jQuery( sel, this ).index( cur ) > -1 :
5484 jQuery.find( sel, this, null, [ cur ] ).length;
5485 }
5486 if ( matchedSelectors[ sel ] ) {
5487 matchedHandlers.push( handleObj );
5488 }
5489 }
5490 if ( matchedHandlers.length ) {
5491 handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
5492 }
5493 }
5494 }
5495 }
5496
5497 // Add the remaining (directly-bound) handlers
5498 cur = this;
5499 if ( delegateCount < handlers.length ) {
5500 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
5501 }
5502
5503 return handlerQueue;
5504 },
5505
5506 addProp: function( name, hook ) {
5507 Object.defineProperty( jQuery.Event.prototype, name, {
5508 enumerable: true,
5509 configurable: true,
5510
5511 get: isFunction( hook ) ?
5512 function() {
5513 if ( this.originalEvent ) {
5514 return hook( this.originalEvent );
5515 }
5516 } :
5517 function() {
5518 if ( this.originalEvent ) {
5519 return this.originalEvent[ name ];
5520 }
5521 },
5522
5523 set: function( value ) {
5524 Object.defineProperty( this, name, {
5525 enumerable: true,
5526 configurable: true,
5527 writable: true,
5528 value: value
5529 } );
5530 }
5531 } );
5532 },
5533
5534 fix: function( originalEvent ) {
5535 return originalEvent[ jQuery.expando ] ?
5536 originalEvent :
5537 new jQuery.Event( originalEvent );
5538 },
5539
5540 special: {
5541 load: {
5542
5543 // Prevent triggered image.load events from bubbling to window.load
5544 noBubble: true
5545 },
5546 click: {
5547
5548 // Utilize native event to ensure correct state for checkable inputs
5549 setup: function( data ) {
5550
5551 // For mutual compressibility with _default, replace `this` access with a local var.
5552 // `|| data` is dead code meant only to preserve the variable through minification.
5553 var el = this || data;
5554
5555 // Claim the first handler
5556 if ( rcheckableType.test( el.type ) &&
5557 el.click && nodeName( el, "input" ) ) {
5558
5559 // dataPriv.set( el, "click", ... )
5560 leverageNative( el, "click", returnTrue );
5561 }
5562
5563 // Return false to allow normal processing in the caller
5564 return false;
5565 },
5566 trigger: function( data ) {
5567
5568 // For mutual compressibility with _default, replace `this` access with a local var.
5569 // `|| data` is dead code meant only to preserve the variable through minification.
5570 var el = this || data;
5571
5572 // Force setup before triggering a click
5573 if ( rcheckableType.test( el.type ) &&
5574 el.click && nodeName( el, "input" ) ) {
5575
5576 leverageNative( el, "click" );
5577 }
5578
5579 // Return non-false to allow normal event-path propagation
5580 return true;
5581 },
5582
5583 // For cross-browser consistency, suppress native .click() on links
5584 // Also prevent it if we're currently inside a leveraged native-event stack
5585 _default: function( event ) {
5586 var target = event.target;
5587 return rcheckableType.test( target.type ) &&
5588 target.click && nodeName( target, "input" ) &&
5589 dataPriv.get( target, "click" ) ||
5590 nodeName( target, "a" );
5591 }
5592 },
5593
5594 beforeunload: {
5595 postDispatch: function( event ) {
5596
5597 // Support: Firefox 20+
5598 // Firefox doesn't alert if the returnValue field is not set.
5599 if ( event.result !== undefined && event.originalEvent ) {
5600 event.originalEvent.returnValue = event.result;
5601 }
5602 }
5603 }
5604 }
5605 };
5606
5607 // Ensure the presence of an event listener that handles manually-triggered
5608 // synthetic events by interrupting progress until reinvoked in response to
5609 // *native* events that it fires directly, ensuring that state changes have
5610 // already occurred before other listeners are invoked.
5611 function leverageNative( el, type, expectSync ) {
5612
5613 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
5614 if ( !expectSync ) {
5615 if ( dataPriv.get( el, type ) === undefined ) {
5616 jQuery.event.add( el, type, returnTrue );
5617 }
5618 return;
5619 }
5620
5621 // Register the controller as a special universal handler for all event namespaces
5622 dataPriv.set( el, type, false );
5623 jQuery.event.add( el, type, {
5624 namespace: false,
5625 handler: function( event ) {
5626 var notAsync, result,
5627 saved = dataPriv.get( this, type );
5628
5629 if ( ( event.isTrigger & 1 ) && this[ type ] ) {
5630
5631 // Interrupt processing of the outer synthetic .trigger()ed event
5632 // Saved data should be false in such cases, but might be a leftover capture object
5633 // from an async native handler (gh-4350)
5634 if ( !saved.length ) {
5635
5636 // Store arguments for use when handling the inner native event
5637 // There will always be at least one argument (an event object), so this array
5638 // will not be confused with a leftover capture object.
5639 saved = slice.call( arguments );
5640 dataPriv.set( this, type, saved );
5641
5642 // Trigger the native event and capture its result
5643 // Support: IE <=9 - 11+
5644 // focus() and blur() are asynchronous
5645 notAsync = expectSync( this, type );
5646 this[ type ]();
5647 result = dataPriv.get( this, type );
5648 if ( saved !== result || notAsync ) {
5649 dataPriv.set( this, type, false );
5650 } else {
5651 result = {};
5652 }
5653 if ( saved !== result ) {
5654
5655 // Cancel the outer synthetic event
5656 event.stopImmediatePropagation();
5657 event.preventDefault();
5658 return result.value;
5659 }
5660
5661 // If this is an inner synthetic event for an event with a bubbling surrogate
5662 // (focus or blur), assume that the surrogate already propagated from triggering the
5663 // native event and prevent that from happening again here.
5664 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
5665 // bubbling surrogate propagates *after* the non-bubbling base), but that seems
5666 // less bad than duplication.
5667 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
5668 event.stopPropagation();
5669 }
5670
5671 // If this is a native event triggered above, everything is now in order
5672 // Fire an inner synthetic event with the original arguments
5673 } else if ( saved.length ) {
5674
5675 // ...and capture the result
5676 dataPriv.set( this, type, {
5677 value: jQuery.event.trigger(
5678
5679 // Support: IE <=9 - 11+
5680 // Extend with the prototype to reset the above stopImmediatePropagation()
5681 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
5682 saved.slice( 1 ),
5683 this
5684 )
5685 } );
5686
5687 // Abort handling of the native event
5688 event.stopImmediatePropagation();
5689 }
5690 }
5691 } );
5692 }
5693
5694 jQuery.removeEvent = function( elem, type, handle ) {
5695
5696 // This "if" is needed for plain objects
5697 if ( elem.removeEventListener ) {
5698 elem.removeEventListener( type, handle );
5699 }
5700 };
5701
5702 jQuery.Event = function( src, props ) {
5703
5704 // Allow instantiation without the 'new' keyword
5705 if ( !( this instanceof jQuery.Event ) ) {
5706 return new jQuery.Event( src, props );
5707 }
5708
5709 // Event object
5710 if ( src && src.type ) {
5711 this.originalEvent = src;
5712 this.type = src.type;
5713
5714 // Events bubbling up the document may have been marked as prevented
5715 // by a handler lower down the tree; reflect the correct value.
5716 this.isDefaultPrevented = src.defaultPrevented ||
5717 src.defaultPrevented === undefined &&
5718
5719 // Support: Android <=2.3 only
5720 src.returnValue === false ?
5721 returnTrue :
5722 returnFalse;
5723
5724 // Create target properties
5725 // Support: Safari <=6 - 7 only
5726 // Target should not be a text node (#504, #13143)
5727 this.target = ( src.target && src.target.nodeType === 3 ) ?
5728 src.target.parentNode :
5729 src.target;
5730
5731 this.currentTarget = src.currentTarget;
5732 this.relatedTarget = src.relatedTarget;
5733
5734 // Event type
5735 } else {
5736 this.type = src;
5737 }
5738
5739 // Put explicitly provided properties onto the event object
5740 if ( props ) {
5741 jQuery.extend( this, props );
5742 }
5743
5744 // Create a timestamp if incoming event doesn't have one
5745 this.timeStamp = src && src.timeStamp || Date.now();
5746
5747 // Mark it as fixed
5748 this[ jQuery.expando ] = true;
5749 };
5750
5751 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5752 // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5753 jQuery.Event.prototype = {
5754 constructor: jQuery.Event,
5755 isDefaultPrevented: returnFalse,
5756 isPropagationStopped: returnFalse,
5757 isImmediatePropagationStopped: returnFalse,
5758 isSimulated: false,
5759
5760 preventDefault: function() {
5761 var e = this.originalEvent;
5762
5763 this.isDefaultPrevented = returnTrue;
5764
5765 if ( e && !this.isSimulated ) {
5766 e.preventDefault();
5767 }
5768 },
5769 stopPropagation: function() {
5770 var e = this.originalEvent;
5771
5772 this.isPropagationStopped = returnTrue;
5773
5774 if ( e && !this.isSimulated ) {
5775 e.stopPropagation();
5776 }
5777 },
5778 stopImmediatePropagation: function() {
5779 var e = this.originalEvent;
5780
5781 this.isImmediatePropagationStopped = returnTrue;
5782
5783 if ( e && !this.isSimulated ) {
5784 e.stopImmediatePropagation();
5785 }
5786
5787 this.stopPropagation();
5788 }
5789 };
5790
5791 // Includes all common event props including KeyEvent and MouseEvent specific props
5792 jQuery.each( {
5793 altKey: true,
5794 bubbles: true,
5795 cancelable: true,
5796 changedTouches: true,
5797 ctrlKey: true,
5798 detail: true,
5799 eventPhase: true,
5800 metaKey: true,
5801 pageX: true,
5802 pageY: true,
5803 shiftKey: true,
5804 view: true,
5805 "char": true,
5806 code: true,
5807 charCode: true,
5808 key: true,
5809 keyCode: true,
5810 button: true,
5811 buttons: true,
5812 clientX: true,
5813 clientY: true,
5814 offsetX: true,
5815 offsetY: true,
5816 pointerId: true,
5817 pointerType: true,
5818 screenX: true,
5819 screenY: true,
5820 targetTouches: true,
5821 toElement: true,
5822 touches: true,
5823
5824 which: function( event ) {
5825 var button = event.button;
5826
5827 // Add which for key events
5828 if ( event.which == null && rkeyEvent.test( event.type ) ) {
5829 return event.charCode != null ? event.charCode : event.keyCode;
5830 }
5831
5832 // Add which for click: 1 === left; 2 === middle; 3 === right
5833 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
5834 if ( button & 1 ) {
5835 return 1;
5836 }
5837
5838 if ( button & 2 ) {
5839 return 3;
5840 }
5841
5842 if ( button & 4 ) {
5843 return 2;
5844 }
5845
5846 return 0;
5847 }
5848
5849 return event.which;
5850 }
5851 }, jQuery.event.addProp );
5852
5853 jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
5854 jQuery.event.special[ type ] = {
5855
5856 // Utilize native event if possible so blur/focus sequence is correct
5857 setup: function() {
5858
5859 // Claim the first handler
5860 // dataPriv.set( this, "focus", ... )
5861 // dataPriv.set( this, "blur", ... )
5862 leverageNative( this, type, expectSync );
5863
5864 // Return false to allow normal processing in the caller
5865 return false;
5866 },
5867 trigger: function() {
5868
5869 // Force setup before trigger
5870 leverageNative( this, type );
5871
5872 // Return non-false to allow normal event-path propagation
5873 return true;
5874 },
5875
5876 delegateType: delegateType
5877 };
5878 } );
5879
5880 // Create mouseenter/leave events using mouseover/out and event-time checks
5881 // so that event delegation works in jQuery.
5882 // Do the same for pointerenter/pointerleave and pointerover/pointerout
5883 //
5884 // Support: Safari 7 only
5885 // Safari sends mouseenter too often; see:
5886 // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5887 // for the description of the bug (it existed in older Chrome versions as well).
5888 jQuery.each( {
5889 mouseenter: "mouseover",
5890 mouseleave: "mouseout",
5891 pointerenter: "pointerover",
5892 pointerleave: "pointerout"
5893 }, function( orig, fix ) {
5894 jQuery.event.special[ orig ] = {
5895 delegateType: fix,
5896 bindType: fix,
5897
5898 handle: function( event ) {
5899 var ret,
5900 target = this,
5901 related = event.relatedTarget,
5902 handleObj = event.handleObj;
5903
5904 // For mouseenter/leave call the handler if related is outside the target.
5905 // NB: No relatedTarget if the mouse left/entered the browser window
5906 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5907 event.type = handleObj.origType;
5908 ret = handleObj.handler.apply( this, arguments );
5909 event.type = fix;
5910 }
5911 return ret;
5912 }
5913 };
5914 } );
5915
5916 jQuery.fn.extend( {
5917
5918 on: function( types, selector, data, fn ) {
5919 return on( this, types, selector, data, fn );
5920 },
5921 one: function( types, selector, data, fn ) {
5922 return on( this, types, selector, data, fn, 1 );
5923 },
5924 off: function( types, selector, fn ) {
5925 var handleObj, type;
5926 if ( types && types.preventDefault && types.handleObj ) {
5927
5928 // ( event ) dispatched jQuery.Event
5929 handleObj = types.handleObj;
5930 jQuery( types.delegateTarget ).off(
5931 handleObj.namespace ?
5932 handleObj.origType + "." + handleObj.namespace :
5933 handleObj.origType,
5934 handleObj.selector,
5935 handleObj.handler
5936 );
5937 return this;
5938 }
5939 if ( typeof types === "object" ) {
5940
5941 // ( types-object [, selector] )
5942 for ( type in types ) {
5943 this.off( type, selector, types[ type ] );
5944 }
5945 return this;
5946 }
5947 if ( selector === false || typeof selector === "function" ) {
5948
5949 // ( types [, fn] )
5950 fn = selector;
5951 selector = undefined;
5952 }
5953 if ( fn === false ) {
5954 fn = returnFalse;
5955 }
5956 return this.each( function() {
5957 jQuery.event.remove( this, types, fn, selector );
5958 } );
5959 }
5960 } );
5961
5962
5963 var
5964
5965 // Support: IE <=10 - 11, Edge 12 - 13 only
5966 // In IE/Edge using regex groups here causes severe slowdowns.
5967 // See https://connect.microsoft.com/IE/feedback/details/1736512/
5968 rnoInnerhtml = /<script|<style|<link/i,
5969
5970 // checked="checked" or checked
5971 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5972 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5973
5974 // Prefer a tbody over its parent table for containing new rows
5975 function manipulationTarget( elem, content ) {
5976 if ( nodeName( elem, "table" ) &&
5977 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
5978
5979 return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
5980 }
5981
5982 return elem;
5983 }
5984
5985 // Replace/restore the type attribute of script elements for safe DOM manipulation
5986 function disableScript( elem ) {
5987 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5988 return elem;
5989 }
5990 function restoreScript( elem ) {
5991 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
5992 elem.type = elem.type.slice( 5 );
5993 } else {
5994 elem.removeAttribute( "type" );
5995 }
5996
5997 return elem;
5998 }
5999
6000 function cloneCopyEvent( src, dest ) {
6001 var i, l, type, pdataOld, udataOld, udataCur, events;
6002
6003 if ( dest.nodeType !== 1 ) {
6004 return;
6005 }
6006
6007 // 1. Copy private data: events, handlers, etc.
6008 if ( dataPriv.hasData( src ) ) {
6009 pdataOld = dataPriv.get( src );
6010 events = pdataOld.events;
6011
6012 if ( events ) {
6013 dataPriv.remove( dest, "handle events" );
6014
6015 for ( type in events ) {
6016 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6017 jQuery.event.add( dest, type, events[ type ][ i ] );
6018 }
6019 }
6020 }
6021 }
6022
6023 // 2. Copy user data
6024 if ( dataUser.hasData( src ) ) {
6025 udataOld = dataUser.access( src );
6026 udataCur = jQuery.extend( {}, udataOld );
6027
6028 dataUser.set( dest, udataCur );
6029 }
6030 }
6031
6032 // Fix IE bugs, see support tests
6033 function fixInput( src, dest ) {
6034 var nodeName = dest.nodeName.toLowerCase();
6035
6036 // Fails to persist the checked state of a cloned checkbox or radio button.
6037 if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6038 dest.checked = src.checked;
6039
6040 // Fails to return the selected option to the default selected state when cloning options
6041 } else if ( nodeName === "input" || nodeName === "textarea" ) {
6042 dest.defaultValue = src.defaultValue;
6043 }
6044 }
6045
6046 function domManip( collection, args, callback, ignored ) {
6047
6048 // Flatten any nested arrays
6049 args = flat( args );
6050
6051 var fragment, first, scripts, hasScripts, node, doc,
6052 i = 0,
6053 l = collection.length,
6054 iNoClone = l - 1,
6055 value = args[ 0 ],
6056 valueIsFunction = isFunction( value );
6057
6058 // We can't cloneNode fragments that contain checked, in WebKit
6059 if ( valueIsFunction ||
6060 ( l > 1 && typeof value === "string" &&
6061 !support.checkClone && rchecked.test( value ) ) ) {
6062 return collection.each( function( index ) {
6063 var self = collection.eq( index );
6064 if ( valueIsFunction ) {
6065 args[ 0 ] = value.call( this, index, self.html() );
6066 }
6067 domManip( self, args, callback, ignored );
6068 } );
6069 }
6070
6071 if ( l ) {
6072 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6073 first = fragment.firstChild;
6074
6075 if ( fragment.childNodes.length === 1 ) {
6076 fragment = first;
6077 }
6078
6079 // Require either new content or an interest in ignored elements to invoke the callback
6080 if ( first || ignored ) {
6081 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6082 hasScripts = scripts.length;
6083
6084 // Use the original fragment for the last item
6085 // instead of the first because it can end up
6086 // being emptied incorrectly in certain situations (#8070).
6087 for ( ; i < l; i++ ) {
6088 node = fragment;
6089
6090 if ( i !== iNoClone ) {
6091 node = jQuery.clone( node, true, true );
6092
6093 // Keep references to cloned scripts for later restoration
6094 if ( hasScripts ) {
6095
6096 // Support: Android <=4.0 only, PhantomJS 1 only
6097 // push.apply(_, arraylike) throws on ancient WebKit
6098 jQuery.merge( scripts, getAll( node, "script" ) );
6099 }
6100 }
6101
6102 callback.call( collection[ i ], node, i );
6103 }
6104
6105 if ( hasScripts ) {
6106 doc = scripts[ scripts.length - 1 ].ownerDocument;
6107
6108 // Reenable scripts
6109 jQuery.map( scripts, restoreScript );
6110
6111 // Evaluate executable scripts on first document insertion
6112 for ( i = 0; i < hasScripts; i++ ) {
6113 node = scripts[ i ];
6114 if ( rscriptType.test( node.type || "" ) &&
6115 !dataPriv.access( node, "globalEval" ) &&
6116 jQuery.contains( doc, node ) ) {
6117
6118 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) {
6119
6120 // Optional AJAX dependency, but won't run scripts if not present
6121 if ( jQuery._evalUrl && !node.noModule ) {
6122 jQuery._evalUrl( node.src, {
6123 nonce: node.nonce || node.getAttribute( "nonce" )
6124 }, doc );
6125 }
6126 } else {
6127 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
6128 }
6129 }
6130 }
6131 }
6132 }
6133 }
6134
6135 return collection;
6136 }
6137
6138 function remove( elem, selector, keepData ) {
6139 var node,
6140 nodes = selector ? jQuery.filter( selector, elem ) : elem,
6141 i = 0;
6142
6143 for ( ; ( node = nodes[ i ] ) != null; i++ ) {
6144 if ( !keepData && node.nodeType === 1 ) {
6145 jQuery.cleanData( getAll( node ) );
6146 }
6147
6148 if ( node.parentNode ) {
6149 if ( keepData && isAttached( node ) ) {
6150 setGlobalEval( getAll( node, "script" ) );
6151 }
6152 node.parentNode.removeChild( node );
6153 }
6154 }
6155
6156 return elem;
6157 }
6158
6159 jQuery.extend( {
6160 htmlPrefilter: function( html ) {
6161 return html;
6162 },
6163
6164 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6165 var i, l, srcElements, destElements,
6166 clone = elem.cloneNode( true ),
6167 inPage = isAttached( elem );
6168
6169 // Fix IE cloning issues
6170 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
6171 !jQuery.isXMLDoc( elem ) ) {
6172
6173 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
6174 destElements = getAll( clone );
6175 srcElements = getAll( elem );
6176
6177 for ( i = 0, l = srcElements.length; i < l; i++ ) {
6178 fixInput( srcElements[ i ], destElements[ i ] );
6179 }
6180 }
6181
6182 // Copy the events from the original to the clone
6183 if ( dataAndEvents ) {
6184 if ( deepDataAndEvents ) {
6185 srcElements = srcElements || getAll( elem );
6186 destElements = destElements || getAll( clone );
6187
6188 for ( i = 0, l = srcElements.length; i < l; i++ ) {
6189 cloneCopyEvent( srcElements[ i ], destElements[ i ] );
6190 }
6191 } else {
6192 cloneCopyEvent( elem, clone );
6193 }
6194 }
6195
6196 // Preserve script evaluation history
6197 destElements = getAll( clone, "script" );
6198 if ( destElements.length > 0 ) {
6199 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6200 }
6201
6202 // Return the cloned set
6203 return clone;
6204 },
6205
6206 cleanData: function( elems ) {
6207 var data, elem, type,
6208 special = jQuery.event.special,
6209 i = 0;
6210
6211 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
6212 if ( acceptData( elem ) ) {
6213 if ( ( data = elem[ dataPriv.expando ] ) ) {
6214 if ( data.events ) {
6215 for ( type in data.events ) {
6216 if ( special[ type ] ) {
6217 jQuery.event.remove( elem, type );
6218
6219 // This is a shortcut to avoid jQuery.event.remove's overhead
6220 } else {
6221 jQuery.removeEvent( elem, type, data.handle );
6222 }
6223 }
6224 }
6225
6226 // Support: Chrome <=35 - 45+
6227 // Assign undefined instead of using delete, see Data#remove
6228 elem[ dataPriv.expando ] = undefined;
6229 }
6230 if ( elem[ dataUser.expando ] ) {
6231
6232 // Support: Chrome <=35 - 45+
6233 // Assign undefined instead of using delete, see Data#remove
6234 elem[ dataUser.expando ] = undefined;
6235 }
6236 }
6237 }
6238 }
6239 } );
6240
6241 jQuery.fn.extend( {
6242 detach: function( selector ) {
6243 return remove( this, selector, true );
6244 },
6245
6246 remove: function( selector ) {
6247 return remove( this, selector );
6248 },
6249
6250 text: function( value ) {
6251 return access( this, function( value ) {
6252 return value === undefined ?
6253 jQuery.text( this ) :
6254 this.empty().each( function() {
6255 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6256 this.textContent = value;
6257 }
6258 } );
6259 }, null, value, arguments.length );
6260 },
6261
6262 append: function() {
6263 return domManip( this, arguments, function( elem ) {
6264 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6265 var target = manipulationTarget( this, elem );
6266 target.appendChild( elem );
6267 }
6268 } );
6269 },
6270
6271 prepend: function() {
6272 return domManip( this, arguments, function( elem ) {
6273 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6274 var target = manipulationTarget( this, elem );
6275 target.insertBefore( elem, target.firstChild );
6276 }
6277 } );
6278 },
6279
6280 before: function() {
6281 return domManip( this, arguments, function( elem ) {
6282 if ( this.parentNode ) {
6283 this.parentNode.insertBefore( elem, this );
6284 }
6285 } );
6286 },
6287
6288 after: function() {
6289 return domManip( this, arguments, function( elem ) {
6290 if ( this.parentNode ) {
6291 this.parentNode.insertBefore( elem, this.nextSibling );
6292 }
6293 } );
6294 },
6295
6296 empty: function() {
6297 var elem,
6298 i = 0;
6299
6300 for ( ; ( elem = this[ i ] ) != null; i++ ) {
6301 if ( elem.nodeType === 1 ) {
6302
6303 // Prevent memory leaks
6304 jQuery.cleanData( getAll( elem, false ) );
6305
6306 // Remove any remaining nodes
6307 elem.textContent = "";
6308 }
6309 }
6310
6311 return this;
6312 },
6313
6314 clone: function( dataAndEvents, deepDataAndEvents ) {
6315 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6316 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6317
6318 return this.map( function() {
6319 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6320 } );
6321 },
6322
6323 html: function( value ) {
6324 return access( this, function( value ) {
6325 var elem = this[ 0 ] || {},
6326 i = 0,
6327 l = this.length;
6328
6329 if ( value === undefined && elem.nodeType === 1 ) {
6330 return elem.innerHTML;
6331 }
6332
6333 // See if we can take a shortcut and just use innerHTML
6334 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6335 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6336
6337 value = jQuery.htmlPrefilter( value );
6338
6339 try {
6340 for ( ; i < l; i++ ) {
6341 elem = this[ i ] || {};
6342
6343 // Remove element nodes and prevent memory leaks
6344 if ( elem.nodeType === 1 ) {
6345 jQuery.cleanData( getAll( elem, false ) );
6346 elem.innerHTML = value;
6347 }
6348 }
6349
6350 elem = 0;
6351
6352 // If using innerHTML throws an exception, use the fallback method
6353 } catch ( e ) {}
6354 }
6355
6356 if ( elem ) {
6357 this.empty().append( value );
6358 }
6359 }, null, value, arguments.length );
6360 },
6361
6362 replaceWith: function() {
6363 var ignored = [];
6364
6365 // Make the changes, replacing each non-ignored context element with the new content
6366 return domManip( this, arguments, function( elem ) {
6367 var parent = this.parentNode;
6368
6369 if ( jQuery.inArray( this, ignored ) < 0 ) {
6370 jQuery.cleanData( getAll( this ) );
6371 if ( parent ) {
6372 parent.replaceChild( elem, this );
6373 }
6374 }
6375
6376 // Force callback invocation
6377 }, ignored );
6378 }
6379 } );
6380
6381 jQuery.each( {
6382 appendTo: "append",
6383 prependTo: "prepend",
6384 insertBefore: "before",
6385 insertAfter: "after",
6386 replaceAll: "replaceWith"
6387 }, function( name, original ) {
6388 jQuery.fn[ name ] = function( selector ) {
6389 var elems,
6390 ret = [],
6391 insert = jQuery( selector ),
6392 last = insert.length - 1,
6393 i = 0;
6394
6395 for ( ; i <= last; i++ ) {
6396 elems = i === last ? this : this.clone( true );
6397 jQuery( insert[ i ] )[ original ]( elems );
6398
6399 // Support: Android <=4.0 only, PhantomJS 1 only
6400 // .get() because push.apply(_, arraylike) throws on ancient WebKit
6401 push.apply( ret, elems.get() );
6402 }
6403
6404 return this.pushStack( ret );
6405 };
6406 } );
6407 var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6408
6409 var getStyles = function( elem ) {
6410
6411 // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
6412 // IE throws on elements created in popups
6413 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6414 var view = elem.ownerDocument.defaultView;
6415
6416 if ( !view || !view.opener ) {
6417 view = window;
6418 }
6419
6420 return view.getComputedStyle( elem );
6421 };
6422
6423 var swap = function( elem, options, callback ) {
6424 var ret, name,
6425 old = {};
6426
6427 // Remember the old values, and insert the new ones
6428 for ( name in options ) {
6429 old[ name ] = elem.style[ name ];
6430 elem.style[ name ] = options[ name ];
6431 }
6432
6433 ret = callback.call( elem );
6434
6435 // Revert the old values
6436 for ( name in options ) {
6437 elem.style[ name ] = old[ name ];
6438 }
6439
6440 return ret;
6441 };
6442
6443
6444 var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
6445
6446
6447
6448 ( function() {
6449
6450 // Executing both pixelPosition & boxSizingReliable tests require only one layout
6451 // so they're executed at the same time to save the second computation.
6452 function computeStyleTests() {
6453
6454 // This is a singleton, we need to execute it only once
6455 if ( !div ) {
6456 return;
6457 }
6458
6459 container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
6460 "margin-top:1px;padding:0;border:0";
6461 div.style.cssText =
6462 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
6463 "margin:auto;border:1px;padding:1px;" +
6464 "width:60%;top:1%";
6465 documentElement.appendChild( container ).appendChild( div );
6466
6467 var divStyle = window.getComputedStyle( div );
6468 pixelPositionVal = divStyle.top !== "1%";
6469
6470 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6471 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
6472
6473 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
6474 // Some styles come back with percentage values, even though they shouldn't
6475 div.style.right = "60%";
6476 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
6477
6478 // Support: IE 9 - 11 only
6479 // Detect misreporting of content dimensions for box-sizing:border-box elements
6480 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
6481
6482 // Support: IE 9 only
6483 // Detect overflow:scroll screwiness (gh-3699)
6484 // Support: Chrome <=64
6485 // Don't get tricked when zoom affects offsetWidth (gh-4029)
6486 div.style.position = "absolute";
6487 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
6488
6489 documentElement.removeChild( container );
6490
6491 // Nullify the div so it wouldn't be stored in the memory and
6492 // it will also be a sign that checks already performed
6493 div = null;
6494 }
6495
6496 function roundPixelMeasures( measure ) {
6497 return Math.round( parseFloat( measure ) );
6498 }
6499
6500 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
6501 reliableTrDimensionsVal, reliableMarginLeftVal,
6502 container = document.createElement( "div" ),
6503 div = document.createElement( "div" );
6504
6505 // Finish early in limited (non-browser) environments
6506 if ( !div.style ) {
6507 return;
6508 }
6509
6510 // Support: IE <=9 - 11 only
6511 // Style of cloned element affects source element cloned (#8908)
6512 div.style.backgroundClip = "content-box";
6513 div.cloneNode( true ).style.backgroundClip = "";
6514 support.clearCloneStyle = div.style.backgroundClip === "content-box";
6515
6516 jQuery.extend( support, {
6517 boxSizingReliable: function() {
6518 computeStyleTests();
6519 return boxSizingReliableVal;
6520 },
6521 pixelBoxStyles: function() {
6522 computeStyleTests();
6523 return pixelBoxStylesVal;
6524 },
6525 pixelPosition: function() {
6526 computeStyleTests();
6527 return pixelPositionVal;
6528 },
6529 reliableMarginLeft: function() {
6530 computeStyleTests();
6531 return reliableMarginLeftVal;
6532 },
6533 scrollboxSize: function() {
6534 computeStyleTests();
6535 return scrollboxSizeVal;
6536 },
6537
6538 // Support: IE 9 - 11+, Edge 15 - 18+
6539 // IE/Edge misreport `getComputedStyle` of table rows with width/height
6540 // set in CSS while `offset*` properties report correct values.
6541 // Behavior in IE 9 is more subtle than in newer versions & it passes
6542 // some versions of this test; make sure not to make it pass there!
6543 reliableTrDimensions: function() {
6544 var table, tr, trChild, trStyle;
6545 if ( reliableTrDimensionsVal == null ) {
6546 table = document.createElement( "table" );
6547 tr = document.createElement( "tr" );
6548 trChild = document.createElement( "div" );
6549
6550 table.style.cssText = "position:absolute;left:-11111px";
6551 tr.style.height = "1px";
6552 trChild.style.height = "9px";
6553
6554 documentElement
6555 .appendChild( table )
6556 .appendChild( tr )
6557 .appendChild( trChild );
6558
6559 trStyle = window.getComputedStyle( tr );
6560 reliableTrDimensionsVal = parseInt( trStyle.height ) > 3;
6561
6562 documentElement.removeChild( table );
6563 }
6564 return reliableTrDimensionsVal;
6565 }
6566 } );
6567 } )();
6568
6569
6570 function curCSS( elem, name, computed ) {
6571 var width, minWidth, maxWidth, ret,
6572
6573 // Support: Firefox 51+
6574 // Retrieving style before computed somehow
6575 // fixes an issue with getting wrong values
6576 // on detached elements
6577 style = elem.style;
6578
6579 computed = computed || getStyles( elem );
6580
6581 // getPropertyValue is needed for:
6582 // .css('filter') (IE 9 only, #12537)
6583 // .css('--customProperty) (#3144)
6584 if ( computed ) {
6585 ret = computed.getPropertyValue( name ) || computed[ name ];
6586
6587 if ( ret === "" && !isAttached( elem ) ) {
6588 ret = jQuery.style( elem, name );
6589 }
6590
6591 // A tribute to the "awesome hack by Dean Edwards"
6592 // Android Browser returns percentage for some values,
6593 // but width seems to be reliably pixels.
6594 // This is against the CSSOM draft spec:
6595 // https://drafts.csswg.org/cssom/#resolved-values
6596 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
6597
6598 // Remember the original values
6599 width = style.width;
6600 minWidth = style.minWidth;
6601 maxWidth = style.maxWidth;
6602
6603 // Put in the new values to get a computed value out
6604 style.minWidth = style.maxWidth = style.width = ret;
6605 ret = computed.width;
6606
6607 // Revert the changed values
6608 style.width = width;
6609 style.minWidth = minWidth;
6610 style.maxWidth = maxWidth;
6611 }
6612 }
6613
6614 return ret !== undefined ?
6615
6616 // Support: IE <=9 - 11 only
6617 // IE returns zIndex value as an integer.
6618 ret + "" :
6619 ret;
6620 }
6621
6622
6623 function addGetHookIf( conditionFn, hookFn ) {
6624
6625 // Define the hook, we'll check on the first run if it's really needed.
6626 return {
6627 get: function() {
6628 if ( conditionFn() ) {
6629
6630 // Hook not needed (or it's not possible to use it due
6631 // to missing dependency), remove it.
6632 delete this.get;
6633 return;
6634 }
6635
6636 // Hook needed; redefine it so that the support test is not executed again.
6637 return ( this.get = hookFn ).apply( this, arguments );
6638 }
6639 };
6640 }
6641
6642
6643 var cssPrefixes = [ "Webkit", "Moz", "ms" ],
6644 emptyStyle = document.createElement( "div" ).style,
6645 vendorProps = {};
6646
6647 // Return a vendor-prefixed property or undefined
6648 function vendorPropName( name ) {
6649
6650 // Check for vendor prefixed names
6651 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
6652 i = cssPrefixes.length;
6653
6654 while ( i-- ) {
6655 name = cssPrefixes[ i ] + capName;
6656 if ( name in emptyStyle ) {
6657 return name;
6658 }
6659 }
6660 }
6661
6662 // Return a potentially-mapped jQuery.cssProps or vendor prefixed property
6663 function finalPropName( name ) {
6664 var final = jQuery.cssProps[ name ] || vendorProps[ name ];
6665
6666 if ( final ) {
6667 return final;
6668 }
6669 if ( name in emptyStyle ) {
6670 return name;
6671 }
6672 return vendorProps[ name ] = vendorPropName( name ) || name;
6673 }
6674
6675
6676 var
6677
6678 // Swappable if display is none or starts with table
6679 // except "table", "table-cell", or "table-caption"
6680 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6681 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6682 rcustomProp = /^--/,
6683 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6684 cssNormalTransform = {
6685 letterSpacing: "0",
6686 fontWeight: "400"
6687 };
6688
6689 function setPositiveNumber( _elem, value, subtract ) {
6690
6691 // Any relative (+/-) values have already been
6692 // normalized at this point
6693 var matches = rcssNum.exec( value );
6694 return matches ?
6695
6696 // Guard against undefined "subtract", e.g., when used as in cssHooks
6697 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
6698 value;
6699 }
6700
6701 function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
6702 var i = dimension === "width" ? 1 : 0,
6703 extra = 0,
6704 delta = 0;
6705
6706 // Adjustment may not be necessary
6707 if ( box === ( isBorderBox ? "border" : "content" ) ) {
6708 return 0;
6709 }
6710
6711 for ( ; i < 4; i += 2 ) {
6712
6713 // Both box models exclude margin
6714 if ( box === "margin" ) {
6715 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
6716 }
6717
6718 // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
6719 if ( !isBorderBox ) {
6720
6721 // Add padding
6722 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6723
6724 // For "border" or "margin", add border
6725 if ( box !== "padding" ) {
6726 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6727
6728 // But still keep track of it otherwise
6729 } else {
6730 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6731 }
6732
6733 // If we get here with a border-box (content + padding + border), we're seeking "content" or
6734 // "padding" or "margin"
6735 } else {
6736
6737 // For "content", subtract padding
6738 if ( box === "content" ) {
6739 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6740 }
6741
6742 // For "content" or "padding", subtract border
6743 if ( box !== "margin" ) {
6744 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6745 }
6746 }
6747 }
6748
6749 // Account for positive content-box scroll gutter when requested by providing computedVal
6750 if ( !isBorderBox && computedVal >= 0 ) {
6751
6752 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
6753 // Assuming integer scroll gutter, subtract the rest and round down
6754 delta += Math.max( 0, Math.ceil(
6755 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
6756 computedVal -
6757 delta -
6758 extra -
6759 0.5
6760
6761 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
6762 // Use an explicit zero to avoid NaN (gh-3964)
6763 ) ) || 0;
6764 }
6765
6766 return delta;
6767 }
6768
6769 function getWidthOrHeight( elem, dimension, extra ) {
6770
6771 // Start with computed style
6772 var styles = getStyles( elem ),
6773
6774 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
6775 // Fake content-box until we know it's needed to know the true value.
6776 boxSizingNeeded = !support.boxSizingReliable() || extra,
6777 isBorderBox = boxSizingNeeded &&
6778 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6779 valueIsBorderBox = isBorderBox,
6780
6781 val = curCSS( elem, dimension, styles ),
6782 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
6783
6784 // Support: Firefox <=54
6785 // Return a confounding non-pixel value or feign ignorance, as appropriate.
6786 if ( rnumnonpx.test( val ) ) {
6787 if ( !extra ) {
6788 return val;
6789 }
6790 val = "auto";
6791 }
6792
6793
6794 // Support: IE 9 - 11 only
6795 // Use offsetWidth/offsetHeight for when box sizing is unreliable.
6796 // In those cases, the computed value can be trusted to be border-box.
6797 if ( ( !support.boxSizingReliable() && isBorderBox ||
6798
6799 // Support: IE 10 - 11+, Edge 15 - 18+
6800 // IE/Edge misreport `getComputedStyle` of table rows with width/height
6801 // set in CSS while `offset*` properties report correct values.
6802 // Interestingly, in some cases IE 9 doesn't suffer from this issue.
6803 !support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
6804
6805 // Fall back to offsetWidth/offsetHeight when value is "auto"
6806 // This happens for inline elements with no explicit setting (gh-3571)
6807 val === "auto" ||
6808
6809 // Support: Android <=4.1 - 4.3 only
6810 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
6811 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
6812
6813 // Make sure the element is visible & connected
6814 elem.getClientRects().length ) {
6815
6816 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6817
6818 // Where available, offsetWidth/offsetHeight approximate border box dimensions.
6819 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
6820 // retrieved value as a content box dimension.
6821 valueIsBorderBox = offsetProp in elem;
6822 if ( valueIsBorderBox ) {
6823 val = elem[ offsetProp ];
6824 }
6825 }
6826
6827 // Normalize "" and auto
6828 val = parseFloat( val ) || 0;
6829
6830 // Adjust for the element's box model
6831 return ( val +
6832 boxModelAdjustment(
6833 elem,
6834 dimension,
6835 extra || ( isBorderBox ? "border" : "content" ),
6836 valueIsBorderBox,
6837 styles,
6838
6839 // Provide the current computed size to request scroll gutter calculation (gh-3589)
6840 val
6841 )
6842 ) + "px";
6843 }
6844
6845 jQuery.extend( {
6846
6847 // Add in style property hooks for overriding the default
6848 // behavior of getting and setting a style property
6849 cssHooks: {
6850 opacity: {
6851 get: function( elem, computed ) {
6852 if ( computed ) {
6853
6854 // We should always get a number back from opacity
6855 var ret = curCSS( elem, "opacity" );
6856 return ret === "" ? "1" : ret;
6857 }
6858 }
6859 }
6860 },
6861
6862 // Don't automatically add "px" to these possibly-unitless properties
6863 cssNumber: {
6864 "animationIterationCount": true,
6865 "columnCount": true,
6866 "fillOpacity": true,
6867 "flexGrow": true,
6868 "flexShrink": true,
6869 "fontWeight": true,
6870 "gridArea": true,
6871 "gridColumn": true,
6872 "gridColumnEnd": true,
6873 "gridColumnStart": true,
6874 "gridRow": true,
6875 "gridRowEnd": true,
6876 "gridRowStart": true,
6877 "lineHeight": true,
6878 "opacity": true,
6879 "order": true,
6880 "orphans": true,
6881 "widows": true,
6882 "zIndex": true,
6883 "zoom": true
6884 },
6885
6886 // Add in properties whose names you wish to fix before
6887 // setting or getting the value
6888 cssProps: {},
6889
6890 // Get and set the style property on a DOM Node
6891 style: function( elem, name, value, extra ) {
6892
6893 // Don't set styles on text and comment nodes
6894 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6895 return;
6896 }
6897
6898 // Make sure that we're working with the right name
6899 var ret, type, hooks,
6900 origName = camelCase( name ),
6901 isCustomProp = rcustomProp.test( name ),
6902 style = elem.style;
6903
6904 // Make sure that we're working with the right name. We don't
6905 // want to query the value if it is a CSS custom property
6906 // since they are user-defined.
6907 if ( !isCustomProp ) {
6908 name = finalPropName( origName );
6909 }
6910
6911 // Gets hook for the prefixed version, then unprefixed version
6912 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6913
6914 // Check if we're setting a value
6915 if ( value !== undefined ) {
6916 type = typeof value;
6917
6918 // Convert "+=" or "-=" to relative numbers (#7345)
6919 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6920 value = adjustCSS( elem, name, ret );
6921
6922 // Fixes bug #9237
6923 type = "number";
6924 }
6925
6926 // Make sure that null and NaN values aren't set (#7116)
6927 if ( value == null || value !== value ) {
6928 return;
6929 }
6930
6931 // If a number was passed in, add the unit (except for certain CSS properties)
6932 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
6933 // "px" to a few hardcoded values.
6934 if ( type === "number" && !isCustomProp ) {
6935 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6936 }
6937
6938 // background-* props affect original clone's values
6939 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6940 style[ name ] = "inherit";
6941 }
6942
6943 // If a hook was provided, use that value, otherwise just set the specified value
6944 if ( !hooks || !( "set" in hooks ) ||
6945 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6946
6947 if ( isCustomProp ) {
6948 style.setProperty( name, value );
6949 } else {
6950 style[ name ] = value;
6951 }
6952 }
6953
6954 } else {
6955
6956 // If a hook was provided get the non-computed value from there
6957 if ( hooks && "get" in hooks &&
6958 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6959
6960 return ret;
6961 }
6962
6963 // Otherwise just get the value from the style object
6964 return style[ name ];
6965 }
6966 },
6967
6968 css: function( elem, name, extra, styles ) {
6969 var val, num, hooks,
6970 origName = camelCase( name ),
6971 isCustomProp = rcustomProp.test( name );
6972
6973 // Make sure that we're working with the right name. We don't
6974 // want to modify the value if it is a CSS custom property
6975 // since they are user-defined.
6976 if ( !isCustomProp ) {
6977 name = finalPropName( origName );
6978 }
6979
6980 // Try prefixed name followed by the unprefixed name
6981 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6982
6983 // If a hook was provided get the computed value from there
6984 if ( hooks && "get" in hooks ) {
6985 val = hooks.get( elem, true, extra );
6986 }
6987
6988 // Otherwise, if a way to get the computed value exists, use that
6989 if ( val === undefined ) {
6990 val = curCSS( elem, name, styles );
6991 }
6992
6993 // Convert "normal" to computed value
6994 if ( val === "normal" && name in cssNormalTransform ) {
6995 val = cssNormalTransform[ name ];
6996 }
6997
6998 // Make numeric if forced or a qualifier was provided and val looks numeric
6999 if ( extra === "" || extra ) {
7000 num = parseFloat( val );
7001 return extra === true || isFinite( num ) ? num || 0 : val;
7002 }
7003
7004 return val;
7005 }
7006 } );
7007
7008 jQuery.each( [ "height", "width" ], function( _i, dimension ) {
7009 jQuery.cssHooks[ dimension ] = {
7010 get: function( elem, computed, extra ) {
7011 if ( computed ) {
7012
7013 // Certain elements can have dimension info if we invisibly show them
7014 // but it must have a current display style that would benefit
7015 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7016
7017 // Support: Safari 8+
7018 // Table columns in Safari have non-zero offsetWidth & zero
7019 // getBoundingClientRect().width unless display is changed.
7020 // Support: IE <=11 only
7021 // Running getBoundingClientRect on a disconnected node
7022 // in IE throws an error.
7023 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
7024 swap( elem, cssShow, function() {
7025 return getWidthOrHeight( elem, dimension, extra );
7026 } ) :
7027 getWidthOrHeight( elem, dimension, extra );
7028 }
7029 },
7030
7031 set: function( elem, value, extra ) {
7032 var matches,
7033 styles = getStyles( elem ),
7034
7035 // Only read styles.position if the test has a chance to fail
7036 // to avoid forcing a reflow.
7037 scrollboxSizeBuggy = !support.scrollboxSize() &&
7038 styles.position === "absolute",
7039
7040 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
7041 boxSizingNeeded = scrollboxSizeBuggy || extra,
7042 isBorderBox = boxSizingNeeded &&
7043 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7044 subtract = extra ?
7045 boxModelAdjustment(
7046 elem,
7047 dimension,
7048 extra,
7049 isBorderBox,
7050 styles
7051 ) :
7052 0;
7053
7054 // Account for unreliable border-box dimensions by comparing offset* to computed and
7055 // faking a content-box to get border and padding (gh-3699)
7056 if ( isBorderBox && scrollboxSizeBuggy ) {
7057 subtract -= Math.ceil(
7058 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
7059 parseFloat( styles[ dimension ] ) -
7060 boxModelAdjustment( elem, dimension, "border", false, styles ) -
7061 0.5
7062 );
7063 }
7064
7065 // Convert to pixels if value adjustment is needed
7066 if ( subtract && ( matches = rcssNum.exec( value ) ) &&
7067 ( matches[ 3 ] || "px" ) !== "px" ) {
7068
7069 elem.style[ dimension ] = value;
7070 value = jQuery.css( elem, dimension );
7071 }
7072
7073 return setPositiveNumber( elem, value, subtract );
7074 }
7075 };
7076 } );
7077
7078 jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7079 function( elem, computed ) {
7080 if ( computed ) {
7081 return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
7082 elem.getBoundingClientRect().left -
7083 swap( elem, { marginLeft: 0 }, function() {
7084 return elem.getBoundingClientRect().left;
7085 } )
7086 ) + "px";
7087 }
7088 }
7089 );
7090
7091 // These hooks are used by animate to expand properties
7092 jQuery.each( {
7093 margin: "",
7094 padding: "",
7095 border: "Width"
7096 }, function( prefix, suffix ) {
7097 jQuery.cssHooks[ prefix + suffix ] = {
7098 expand: function( value ) {
7099 var i = 0,
7100 expanded = {},
7101
7102 // Assumes a single number if not a string
7103 parts = typeof value === "string" ? value.split( " " ) : [ value ];
7104
7105 for ( ; i < 4; i++ ) {
7106 expanded[ prefix + cssExpand[ i ] + suffix ] =
7107 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7108 }
7109
7110 return expanded;
7111 }
7112 };
7113
7114 if ( prefix !== "margin" ) {
7115 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7116 }
7117 } );
7118
7119 jQuery.fn.extend( {
7120 css: function( name, value ) {
7121 return access( this, function( elem, name, value ) {
7122 var styles, len,
7123 map = {},
7124 i = 0;
7125
7126 if ( Array.isArray( name ) ) {
7127 styles = getStyles( elem );
7128 len = name.length;
7129
7130 for ( ; i < len; i++ ) {
7131 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7132 }
7133
7134 return map;
7135 }
7136
7137 return value !== undefined ?
7138 jQuery.style( elem, name, value ) :
7139 jQuery.css( elem, name );
7140 }, name, value, arguments.length > 1 );
7141 }
7142 } );
7143
7144
7145 function Tween( elem, options, prop, end, easing ) {
7146 return new Tween.prototype.init( elem, options, prop, end, easing );
7147 }
7148 jQuery.Tween = Tween;
7149
7150 Tween.prototype = {
7151 constructor: Tween,
7152 init: function( elem, options, prop, end, easing, unit ) {
7153 this.elem = elem;
7154 this.prop = prop;
7155 this.easing = easing || jQuery.easing._default;
7156 this.options = options;
7157 this.start = this.now = this.cur();
7158 this.end = end;
7159 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7160 },
7161 cur: function() {
7162 var hooks = Tween.propHooks[ this.prop ];
7163
7164 return hooks && hooks.get ?
7165 hooks.get( this ) :
7166 Tween.propHooks._default.get( this );
7167 },
7168 run: function( percent ) {
7169 var eased,
7170 hooks = Tween.propHooks[ this.prop ];
7171
7172 if ( this.options.duration ) {
7173 this.pos = eased = jQuery.easing[ this.easing ](
7174 percent, this.options.duration * percent, 0, 1, this.options.duration
7175 );
7176 } else {
7177 this.pos = eased = percent;
7178 }
7179 this.now = ( this.end - this.start ) * eased + this.start;
7180
7181 if ( this.options.step ) {
7182 this.options.step.call( this.elem, this.now, this );
7183 }
7184
7185 if ( hooks && hooks.set ) {
7186 hooks.set( this );
7187 } else {
7188 Tween.propHooks._default.set( this );
7189 }
7190 return this;
7191 }
7192 };
7193
7194 Tween.prototype.init.prototype = Tween.prototype;
7195
7196 Tween.propHooks = {
7197 _default: {
7198 get: function( tween ) {
7199 var result;
7200
7201 // Use a property on the element directly when it is not a DOM element,
7202 // or when there is no matching style property that exists.
7203 if ( tween.elem.nodeType !== 1 ||
7204 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7205 return tween.elem[ tween.prop ];
7206 }
7207
7208 // Passing an empty string as a 3rd parameter to .css will automatically
7209 // attempt a parseFloat and fallback to a string if the parse fails.
7210 // Simple values such as "10px" are parsed to Float;
7211 // complex values such as "rotate(1rad)" are returned as-is.
7212 result = jQuery.css( tween.elem, tween.prop, "" );
7213
7214 // Empty strings, null, undefined and "auto" are converted to 0.
7215 return !result || result === "auto" ? 0 : result;
7216 },
7217 set: function( tween ) {
7218
7219 // Use step hook for back compat.
7220 // Use cssHook if its there.
7221 // Use .style if available and use plain properties where available.
7222 if ( jQuery.fx.step[ tween.prop ] ) {
7223 jQuery.fx.step[ tween.prop ]( tween );
7224 } else if ( tween.elem.nodeType === 1 && (
7225 jQuery.cssHooks[ tween.prop ] ||
7226 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
7227 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7228 } else {
7229 tween.elem[ tween.prop ] = tween.now;
7230 }
7231 }
7232 }
7233 };
7234
7235 // Support: IE <=9 only
7236 // Panic based approach to setting things on disconnected nodes
7237 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7238 set: function( tween ) {
7239 if ( tween.elem.nodeType && tween.elem.parentNode ) {
7240 tween.elem[ tween.prop ] = tween.now;
7241 }
7242 }
7243 };
7244
7245 jQuery.easing = {
7246 linear: function( p ) {
7247 return p;
7248 },
7249 swing: function( p ) {
7250 return 0.5 - Math.cos( p * Math.PI ) / 2;
7251 },
7252 _default: "swing"
7253 };
7254
7255 jQuery.fx = Tween.prototype.init;
7256
7257 // Back compat <1.8 extension point
7258 jQuery.fx.step = {};
7259
7260
7261
7262
7263 var
7264 fxNow, inProgress,
7265 rfxtypes = /^(?:toggle|show|hide)$/,
7266 rrun = /queueHooks$/;
7267
7268 function schedule() {
7269 if ( inProgress ) {
7270 if ( document.hidden === false && window.requestAnimationFrame ) {
7271 window.requestAnimationFrame( schedule );
7272 } else {
7273 window.setTimeout( schedule, jQuery.fx.interval );
7274 }
7275
7276 jQuery.fx.tick();
7277 }
7278 }
7279
7280 // Animations created synchronously will run synchronously
7281 function createFxNow() {
7282 window.setTimeout( function() {
7283 fxNow = undefined;
7284 } );
7285 return ( fxNow = Date.now() );
7286 }
7287
7288 // Generate parameters to create a standard animation
7289 function genFx( type, includeWidth ) {
7290 var which,
7291 i = 0,
7292 attrs = { height: type };
7293
7294 // If we include width, step value is 1 to do all cssExpand values,
7295 // otherwise step value is 2 to skip over Left and Right
7296 includeWidth = includeWidth ? 1 : 0;
7297 for ( ; i < 4; i += 2 - includeWidth ) {
7298 which = cssExpand[ i ];
7299 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7300 }
7301
7302 if ( includeWidth ) {
7303 attrs.opacity = attrs.width = type;
7304 }
7305
7306 return attrs;
7307 }
7308
7309 function createTween( value, prop, animation ) {
7310 var tween,
7311 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7312 index = 0,
7313 length = collection.length;
7314 for ( ; index < length; index++ ) {
7315 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7316
7317 // We're done with this property
7318 return tween;
7319 }
7320 }
7321 }
7322
7323 function defaultPrefilter( elem, props, opts ) {
7324 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
7325 isBox = "width" in props || "height" in props,
7326 anim = this,
7327 orig = {},
7328 style = elem.style,
7329 hidden = elem.nodeType && isHiddenWithinTree( elem ),
7330 dataShow = dataPriv.get( elem, "fxshow" );
7331
7332 // Queue-skipping animations hijack the fx hooks
7333 if ( !opts.queue ) {
7334 hooks = jQuery._queueHooks( elem, "fx" );
7335 if ( hooks.unqueued == null ) {
7336 hooks.unqueued = 0;
7337 oldfire = hooks.empty.fire;
7338 hooks.empty.fire = function() {
7339 if ( !hooks.unqueued ) {
7340 oldfire();
7341 }
7342 };
7343 }
7344 hooks.unqueued++;
7345
7346 anim.always( function() {
7347
7348 // Ensure the complete handler is called before this completes
7349 anim.always( function() {
7350 hooks.unqueued--;
7351 if ( !jQuery.queue( elem, "fx" ).length ) {
7352 hooks.empty.fire();
7353 }
7354 } );
7355 } );
7356 }
7357
7358 // Detect show/hide animations
7359 for ( prop in props ) {
7360 value = props[ prop ];
7361 if ( rfxtypes.test( value ) ) {
7362 delete props[ prop ];
7363 toggle = toggle || value === "toggle";
7364 if ( value === ( hidden ? "hide" : "show" ) ) {
7365
7366 // Pretend to be hidden if this is a "show" and
7367 // there is still data from a stopped show/hide
7368 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7369 hidden = true;
7370
7371 // Ignore all other no-op show/hide data
7372 } else {
7373 continue;
7374 }
7375 }
7376 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7377 }
7378 }
7379
7380 // Bail out if this is a no-op like .hide().hide()
7381 propTween = !jQuery.isEmptyObject( props );
7382 if ( !propTween && jQuery.isEmptyObject( orig ) ) {
7383 return;
7384 }
7385
7386 // Restrict "overflow" and "display" styles during box animations
7387 if ( isBox && elem.nodeType === 1 ) {
7388
7389 // Support: IE <=9 - 11, Edge 12 - 15
7390 // Record all 3 overflow attributes because IE does not infer the shorthand
7391 // from identically-valued overflowX and overflowY and Edge just mirrors
7392 // the overflowX value there.
7393 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7394
7395 // Identify a display type, preferring old show/hide data over the CSS cascade
7396 restoreDisplay = dataShow && dataShow.display;
7397 if ( restoreDisplay == null ) {
7398 restoreDisplay = dataPriv.get( elem, "display" );
7399 }
7400 display = jQuery.css( elem, "display" );
7401 if ( display === "none" ) {
7402 if ( restoreDisplay ) {
7403 display = restoreDisplay;
7404 } else {
7405
7406 // Get nonempty value(s) by temporarily forcing visibility
7407 showHide( [ elem ], true );
7408 restoreDisplay = elem.style.display || restoreDisplay;
7409 display = jQuery.css( elem, "display" );
7410 showHide( [ elem ] );
7411 }
7412 }
7413
7414 // Animate inline elements as inline-block
7415 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
7416 if ( jQuery.css( elem, "float" ) === "none" ) {
7417
7418 // Restore the original display value at the end of pure show/hide animations
7419 if ( !propTween ) {
7420 anim.done( function() {
7421 style.display = restoreDisplay;
7422 } );
7423 if ( restoreDisplay == null ) {
7424 display = style.display;
7425 restoreDisplay = display === "none" ? "" : display;
7426 }
7427 }
7428 style.display = "inline-block";
7429 }
7430 }
7431 }
7432
7433 if ( opts.overflow ) {
7434 style.overflow = "hidden";
7435 anim.always( function() {
7436 style.overflow = opts.overflow[ 0 ];
7437 style.overflowX = opts.overflow[ 1 ];
7438 style.overflowY = opts.overflow[ 2 ];
7439 } );
7440 }
7441
7442 // Implement show/hide animations
7443 propTween = false;
7444 for ( prop in orig ) {
7445
7446 // General show/hide setup for this element animation
7447 if ( !propTween ) {
7448 if ( dataShow ) {
7449 if ( "hidden" in dataShow ) {
7450 hidden = dataShow.hidden;
7451 }
7452 } else {
7453 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
7454 }
7455
7456 // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
7457 if ( toggle ) {
7458 dataShow.hidden = !hidden;
7459 }
7460
7461 // Show elements before animating them
7462 if ( hidden ) {
7463 showHide( [ elem ], true );
7464 }
7465
7466 /* eslint-disable no-loop-func */
7467
7468 anim.done( function() {
7469
7470 /* eslint-enable no-loop-func */
7471
7472 // The final step of a "hide" animation is actually hiding the element
7473 if ( !hidden ) {
7474 showHide( [ elem ] );
7475 }
7476 dataPriv.remove( elem, "fxshow" );
7477 for ( prop in orig ) {
7478 jQuery.style( elem, prop, orig[ prop ] );
7479 }
7480 } );
7481 }
7482
7483 // Per-property setup
7484 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7485 if ( !( prop in dataShow ) ) {
7486 dataShow[ prop ] = propTween.start;
7487 if ( hidden ) {
7488 propTween.end = propTween.start;
7489 propTween.start = 0;
7490 }
7491 }
7492 }
7493 }
7494
7495 function propFilter( props, specialEasing ) {
7496 var index, name, easing, value, hooks;
7497
7498 // camelCase, specialEasing and expand cssHook pass
7499 for ( index in props ) {
7500 name = camelCase( index );
7501 easing = specialEasing[ name ];
7502 value = props[ index ];
7503 if ( Array.isArray( value ) ) {
7504 easing = value[ 1 ];
7505 value = props[ index ] = value[ 0 ];
7506 }
7507
7508 if ( index !== name ) {
7509 props[ name ] = value;
7510 delete props[ index ];
7511 }
7512
7513 hooks = jQuery.cssHooks[ name ];
7514 if ( hooks && "expand" in hooks ) {
7515 value = hooks.expand( value );
7516 delete props[ name ];
7517
7518 // Not quite $.extend, this won't overwrite existing keys.
7519 // Reusing 'index' because we have the correct "name"
7520 for ( index in value ) {
7521 if ( !( index in props ) ) {
7522 props[ index ] = value[ index ];
7523 specialEasing[ index ] = easing;
7524 }
7525 }
7526 } else {
7527 specialEasing[ name ] = easing;
7528 }
7529 }
7530 }
7531
7532 function Animation( elem, properties, options ) {
7533 var result,
7534 stopped,
7535 index = 0,
7536 length = Animation.prefilters.length,
7537 deferred = jQuery.Deferred().always( function() {
7538
7539 // Don't match elem in the :animated selector
7540 delete tick.elem;
7541 } ),
7542 tick = function() {
7543 if ( stopped ) {
7544 return false;
7545 }
7546 var currentTime = fxNow || createFxNow(),
7547 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7548
7549 // Support: Android 2.3 only
7550 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7551 temp = remaining / animation.duration || 0,
7552 percent = 1 - temp,
7553 index = 0,
7554 length = animation.tweens.length;
7555
7556 for ( ; index < length; index++ ) {
7557 animation.tweens[ index ].run( percent );
7558 }
7559
7560 deferred.notifyWith( elem, [ animation, percent, remaining ] );
7561
7562 // If there's more to do, yield
7563 if ( percent < 1 && length ) {
7564 return remaining;
7565 }
7566
7567 // If this was an empty animation, synthesize a final progress notification
7568 if ( !length ) {
7569 deferred.notifyWith( elem, [ animation, 1, 0 ] );
7570 }
7571
7572 // Resolve the animation and report its conclusion
7573 deferred.resolveWith( elem, [ animation ] );
7574 return false;
7575 },
7576 animation = deferred.promise( {
7577 elem: elem,
7578 props: jQuery.extend( {}, properties ),
7579 opts: jQuery.extend( true, {
7580 specialEasing: {},
7581 easing: jQuery.easing._default
7582 }, options ),
7583 originalProperties: properties,
7584 originalOptions: options,
7585 startTime: fxNow || createFxNow(),
7586 duration: options.duration,
7587 tweens: [],
7588 createTween: function( prop, end ) {
7589 var tween = jQuery.Tween( elem, animation.opts, prop, end,
7590 animation.opts.specialEasing[ prop ] || animation.opts.easing );
7591 animation.tweens.push( tween );
7592 return tween;
7593 },
7594 stop: function( gotoEnd ) {
7595 var index = 0,
7596
7597 // If we are going to the end, we want to run all the tweens
7598 // otherwise we skip this part
7599 length = gotoEnd ? animation.tweens.length : 0;
7600 if ( stopped ) {
7601 return this;
7602 }
7603 stopped = true;
7604 for ( ; index < length; index++ ) {
7605 animation.tweens[ index ].run( 1 );
7606 }
7607
7608 // Resolve when we played the last frame; otherwise, reject
7609 if ( gotoEnd ) {
7610 deferred.notifyWith( elem, [ animation, 1, 0 ] );
7611 deferred.resolveWith( elem, [ animation, gotoEnd ] );
7612 } else {
7613 deferred.rejectWith( elem, [ animation, gotoEnd ] );
7614 }
7615 return this;
7616 }
7617 } ),
7618 props = animation.props;
7619
7620 propFilter( props, animation.opts.specialEasing );
7621
7622 for ( ; index < length; index++ ) {
7623 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7624 if ( result ) {
7625 if ( isFunction( result.stop ) ) {
7626 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7627 result.stop.bind( result );
7628 }
7629 return result;
7630 }
7631 }
7632
7633 jQuery.map( props, createTween, animation );
7634
7635 if ( isFunction( animation.opts.start ) ) {
7636 animation.opts.start.call( elem, animation );
7637 }
7638
7639 // Attach callbacks from options
7640 animation
7641 .progress( animation.opts.progress )
7642 .done( animation.opts.done, animation.opts.complete )
7643 .fail( animation.opts.fail )
7644 .always( animation.opts.always );
7645
7646 jQuery.fx.timer(
7647 jQuery.extend( tick, {
7648 elem: elem,
7649 anim: animation,
7650 queue: animation.opts.queue
7651 } )
7652 );
7653
7654 return animation;
7655 }
7656
7657 jQuery.Animation = jQuery.extend( Animation, {
7658
7659 tweeners: {
7660 "*": [ function( prop, value ) {
7661 var tween = this.createTween( prop, value );
7662 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7663 return tween;
7664 } ]
7665 },
7666
7667 tweener: function( props, callback ) {
7668 if ( isFunction( props ) ) {
7669 callback = props;
7670 props = [ "*" ];
7671 } else {
7672 props = props.match( rnothtmlwhite );
7673 }
7674
7675 var prop,
7676 index = 0,
7677 length = props.length;
7678
7679 for ( ; index < length; index++ ) {
7680 prop = props[ index ];
7681 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7682 Animation.tweeners[ prop ].unshift( callback );
7683 }
7684 },
7685
7686 prefilters: [ defaultPrefilter ],
7687
7688 prefilter: function( callback, prepend ) {
7689 if ( prepend ) {
7690 Animation.prefilters.unshift( callback );
7691 } else {
7692 Animation.prefilters.push( callback );
7693 }
7694 }
7695 } );
7696
7697 jQuery.speed = function( speed, easing, fn ) {
7698 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7699 complete: fn || !fn && easing ||
7700 isFunction( speed ) && speed,
7701 duration: speed,
7702 easing: fn && easing || easing && !isFunction( easing ) && easing
7703 };
7704
7705 // Go to the end state if fx are off
7706 if ( jQuery.fx.off ) {
7707 opt.duration = 0;
7708
7709 } else {
7710 if ( typeof opt.duration !== "number" ) {
7711 if ( opt.duration in jQuery.fx.speeds ) {
7712 opt.duration = jQuery.fx.speeds[ opt.duration ];
7713
7714 } else {
7715 opt.duration = jQuery.fx.speeds._default;
7716 }
7717 }
7718 }
7719
7720 // Normalize opt.queue - true/undefined/null -> "fx"
7721 if ( opt.queue == null || opt.queue === true ) {
7722 opt.queue = "fx";
7723 }
7724
7725 // Queueing
7726 opt.old = opt.complete;
7727
7728 opt.complete = function() {
7729 if ( isFunction( opt.old ) ) {
7730 opt.old.call( this );
7731 }
7732
7733 if ( opt.queue ) {
7734 jQuery.dequeue( this, opt.queue );
7735 }
7736 };
7737
7738 return opt;
7739 };
7740
7741 jQuery.fn.extend( {
7742 fadeTo: function( speed, to, easing, callback ) {
7743
7744 // Show any hidden elements after setting opacity to 0
7745 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
7746
7747 // Animate to the value specified
7748 .end().animate( { opacity: to }, speed, easing, callback );
7749 },
7750 animate: function( prop, speed, easing, callback ) {
7751 var empty = jQuery.isEmptyObject( prop ),
7752 optall = jQuery.speed( speed, easing, callback ),
7753 doAnimation = function() {
7754
7755 // Operate on a copy of prop so per-property easing won't be lost
7756 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7757
7758 // Empty animations, or finishing resolves immediately
7759 if ( empty || dataPriv.get( this, "finish" ) ) {
7760 anim.stop( true );
7761 }
7762 };
7763 doAnimation.finish = doAnimation;
7764
7765 return empty || optall.queue === false ?
7766 this.each( doAnimation ) :
7767 this.queue( optall.queue, doAnimation );
7768 },
7769 stop: function( type, clearQueue, gotoEnd ) {
7770 var stopQueue = function( hooks ) {
7771 var stop = hooks.stop;
7772 delete hooks.stop;
7773 stop( gotoEnd );
7774 };
7775
7776 if ( typeof type !== "string" ) {
7777 gotoEnd = clearQueue;
7778 clearQueue = type;
7779 type = undefined;
7780 }
7781 if ( clearQueue ) {
7782 this.queue( type || "fx", [] );
7783 }
7784
7785 return this.each( function() {
7786 var dequeue = true,
7787 index = type != null && type + "queueHooks",
7788 timers = jQuery.timers,
7789 data = dataPriv.get( this );
7790
7791 if ( index ) {
7792 if ( data[ index ] && data[ index ].stop ) {
7793 stopQueue( data[ index ] );
7794 }
7795 } else {
7796 for ( index in data ) {
7797 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7798 stopQueue( data[ index ] );
7799 }
7800 }
7801 }
7802
7803 for ( index = timers.length; index--; ) {
7804 if ( timers[ index ].elem === this &&
7805 ( type == null || timers[ index ].queue === type ) ) {
7806
7807 timers[ index ].anim.stop( gotoEnd );
7808 dequeue = false;
7809 timers.splice( index, 1 );
7810 }
7811 }
7812
7813 // Start the next in the queue if the last step wasn't forced.
7814 // Timers currently will call their complete callbacks, which
7815 // will dequeue but only if they were gotoEnd.
7816 if ( dequeue || !gotoEnd ) {
7817 jQuery.dequeue( this, type );
7818 }
7819 } );
7820 },
7821 finish: function( type ) {
7822 if ( type !== false ) {
7823 type = type || "fx";
7824 }
7825 return this.each( function() {
7826 var index,
7827 data = dataPriv.get( this ),
7828 queue = data[ type + "queue" ],
7829 hooks = data[ type + "queueHooks" ],
7830 timers = jQuery.timers,
7831 length = queue ? queue.length : 0;
7832
7833 // Enable finishing flag on private data
7834 data.finish = true;
7835
7836 // Empty the queue first
7837 jQuery.queue( this, type, [] );
7838
7839 if ( hooks && hooks.stop ) {
7840 hooks.stop.call( this, true );
7841 }
7842
7843 // Look for any active animations, and finish them
7844 for ( index = timers.length; index--; ) {
7845 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7846 timers[ index ].anim.stop( true );
7847 timers.splice( index, 1 );
7848 }
7849 }
7850
7851 // Look for any animations in the old queue and finish them
7852 for ( index = 0; index < length; index++ ) {
7853 if ( queue[ index ] && queue[ index ].finish ) {
7854 queue[ index ].finish.call( this );
7855 }
7856 }
7857
7858 // Turn off finishing flag
7859 delete data.finish;
7860 } );
7861 }
7862 } );
7863
7864 jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
7865 var cssFn = jQuery.fn[ name ];
7866 jQuery.fn[ name ] = function( speed, easing, callback ) {
7867 return speed == null || typeof speed === "boolean" ?
7868 cssFn.apply( this, arguments ) :
7869 this.animate( genFx( name, true ), speed, easing, callback );
7870 };
7871 } );
7872
7873 // Generate shortcuts for custom animations
7874 jQuery.each( {
7875 slideDown: genFx( "show" ),
7876 slideUp: genFx( "hide" ),
7877 slideToggle: genFx( "toggle" ),
7878 fadeIn: { opacity: "show" },
7879 fadeOut: { opacity: "hide" },
7880 fadeToggle: { opacity: "toggle" }
7881 }, function( name, props ) {
7882 jQuery.fn[ name ] = function( speed, easing, callback ) {
7883 return this.animate( props, speed, easing, callback );
7884 };
7885 } );
7886
7887 jQuery.timers = [];
7888 jQuery.fx.tick = function() {
7889 var timer,
7890 i = 0,
7891 timers = jQuery.timers;
7892
7893 fxNow = Date.now();
7894
7895 for ( ; i < timers.length; i++ ) {
7896 timer = timers[ i ];
7897
7898 // Run the timer and safely remove it when done (allowing for external removal)
7899 if ( !timer() && timers[ i ] === timer ) {
7900 timers.splice( i--, 1 );
7901 }
7902 }
7903
7904 if ( !timers.length ) {
7905 jQuery.fx.stop();
7906 }
7907 fxNow = undefined;
7908 };
7909
7910 jQuery.fx.timer = function( timer ) {
7911 jQuery.timers.push( timer );
7912 jQuery.fx.start();
7913 };
7914
7915 jQuery.fx.interval = 13;
7916 jQuery.fx.start = function() {
7917 if ( inProgress ) {
7918 return;
7919 }
7920
7921 inProgress = true;
7922 schedule();
7923 };
7924
7925 jQuery.fx.stop = function() {
7926 inProgress = null;
7927 };
7928
7929 jQuery.fx.speeds = {
7930 slow: 600,
7931 fast: 200,
7932
7933 // Default speed
7934 _default: 400
7935 };
7936
7937
7938 // Based off of the plugin by Clint Helfers, with permission.
7939 // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7940 jQuery.fn.delay = function( time, type ) {
7941 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7942 type = type || "fx";
7943
7944 return this.queue( type, function( next, hooks ) {
7945 var timeout = window.setTimeout( next, time );
7946 hooks.stop = function() {
7947 window.clearTimeout( timeout );
7948 };
7949 } );
7950 };
7951
7952
7953 ( function() {
7954 var input = document.createElement( "input" ),
7955 select = document.createElement( "select" ),
7956 opt = select.appendChild( document.createElement( "option" ) );
7957
7958 input.type = "checkbox";
7959
7960 // Support: Android <=4.3 only
7961 // Default value for a checkbox should be "on"
7962 support.checkOn = input.value !== "";
7963
7964 // Support: IE <=11 only
7965 // Must access selectedIndex to make default options select
7966 support.optSelected = opt.selected;
7967
7968 // Support: IE <=11 only
7969 // An input loses its value after becoming a radio
7970 input = document.createElement( "input" );
7971 input.value = "t";
7972 input.type = "radio";
7973 support.radioValue = input.value === "t";
7974 } )();
7975
7976
7977 var boolHook,
7978 attrHandle = jQuery.expr.attrHandle;
7979
7980 jQuery.fn.extend( {
7981 attr: function( name, value ) {
7982 return access( this, jQuery.attr, name, value, arguments.length > 1 );
7983 },
7984
7985 removeAttr: function( name ) {
7986 return this.each( function() {
7987 jQuery.removeAttr( this, name );
7988 } );
7989 }
7990 } );
7991
7992 jQuery.extend( {
7993 attr: function( elem, name, value ) {
7994 var ret, hooks,
7995 nType = elem.nodeType;
7996
7997 // Don't get/set attributes on text, comment and attribute nodes
7998 if ( nType === 3 || nType === 8 || nType === 2 ) {
7999 return;
8000 }
8001
8002 // Fallback to prop when attributes are not supported
8003 if ( typeof elem.getAttribute === "undefined" ) {
8004 return jQuery.prop( elem, name, value );
8005 }
8006
8007 // Attribute hooks are determined by the lowercase version
8008 // Grab necessary hook if one is defined
8009 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8010 hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
8011 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
8012 }
8013
8014 if ( value !== undefined ) {
8015 if ( value === null ) {
8016 jQuery.removeAttr( elem, name );
8017 return;
8018 }
8019
8020 if ( hooks && "set" in hooks &&
8021 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8022 return ret;
8023 }
8024
8025 elem.setAttribute( name, value + "" );
8026 return value;
8027 }
8028
8029 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8030 return ret;
8031 }
8032
8033 ret = jQuery.find.attr( elem, name );
8034
8035 // Non-existent attributes return null, we normalize to undefined
8036 return ret == null ? undefined : ret;
8037 },
8038
8039 attrHooks: {
8040 type: {
8041 set: function( elem, value ) {
8042 if ( !support.radioValue && value === "radio" &&
8043 nodeName( elem, "input" ) ) {
8044 var val = elem.value;
8045 elem.setAttribute( "type", value );
8046 if ( val ) {
8047 elem.value = val;
8048 }
8049 return value;
8050 }
8051 }
8052 }
8053 },
8054
8055 removeAttr: function( elem, value ) {
8056 var name,
8057 i = 0,
8058
8059 // Attribute names can contain non-HTML whitespace characters
8060 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
8061 attrNames = value && value.match( rnothtmlwhite );
8062
8063 if ( attrNames && elem.nodeType === 1 ) {
8064 while ( ( name = attrNames[ i++ ] ) ) {
8065 elem.removeAttribute( name );
8066 }
8067 }
8068 }
8069 } );
8070
8071 // Hooks for boolean attributes
8072 boolHook = {
8073 set: function( elem, value, name ) {
8074 if ( value === false ) {
8075
8076 // Remove boolean attributes when set to false
8077 jQuery.removeAttr( elem, name );
8078 } else {
8079 elem.setAttribute( name, name );
8080 }
8081 return name;
8082 }
8083 };
8084
8085 jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
8086 var getter = attrHandle[ name ] || jQuery.find.attr;
8087
8088 attrHandle[ name ] = function( elem, name, isXML ) {
8089 var ret, handle,
8090 lowercaseName = name.toLowerCase();
8091
8092 if ( !isXML ) {
8093
8094 // Avoid an infinite loop by temporarily removing this function from the getter
8095 handle = attrHandle[ lowercaseName ];
8096 attrHandle[ lowercaseName ] = ret;
8097 ret = getter( elem, name, isXML ) != null ?
8098 lowercaseName :
8099 null;
8100 attrHandle[ lowercaseName ] = handle;
8101 }
8102 return ret;
8103 };
8104 } );
8105
8106
8107
8108
8109 var rfocusable = /^(?:input|select|textarea|button)$/i,
8110 rclickable = /^(?:a|area)$/i;
8111
8112 jQuery.fn.extend( {
8113 prop: function( name, value ) {
8114 return access( this, jQuery.prop, name, value, arguments.length > 1 );
8115 },
8116
8117 removeProp: function( name ) {
8118 return this.each( function() {
8119 delete this[ jQuery.propFix[ name ] || name ];
8120 } );
8121 }
8122 } );
8123
8124 jQuery.extend( {
8125 prop: function( elem, name, value ) {
8126 var ret, hooks,
8127 nType = elem.nodeType;
8128
8129 // Don't get/set properties on text, comment and attribute nodes
8130 if ( nType === 3 || nType === 8 || nType === 2 ) {
8131 return;
8132 }
8133
8134 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8135
8136 // Fix name and attach hooks
8137 name = jQuery.propFix[ name ] || name;
8138 hooks = jQuery.propHooks[ name ];
8139 }
8140
8141 if ( value !== undefined ) {
8142 if ( hooks && "set" in hooks &&
8143 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8144 return ret;
8145 }
8146
8147 return ( elem[ name ] = value );
8148 }
8149
8150 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8151 return ret;
8152 }
8153
8154 return elem[ name ];
8155 },
8156
8157 propHooks: {
8158 tabIndex: {
8159 get: function( elem ) {
8160
8161 // Support: IE <=9 - 11 only
8162 // elem.tabIndex doesn't always return the
8163 // correct value when it hasn't been explicitly set
8164 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8165 // Use proper attribute retrieval(#12072)
8166 var tabindex = jQuery.find.attr( elem, "tabindex" );
8167
8168 if ( tabindex ) {
8169 return parseInt( tabindex, 10 );
8170 }
8171
8172 if (
8173 rfocusable.test( elem.nodeName ) ||
8174 rclickable.test( elem.nodeName ) &&
8175 elem.href
8176 ) {
8177 return 0;
8178 }
8179
8180 return -1;
8181 }
8182 }
8183 },
8184
8185 propFix: {
8186 "for": "htmlFor",
8187 "class": "className"
8188 }
8189 } );
8190
8191 // Support: IE <=11 only
8192 // Accessing the selectedIndex property
8193 // forces the browser to respect setting selected
8194 // on the option
8195 // The getter ensures a default option is selected
8196 // when in an optgroup
8197 // eslint rule "no-unused-expressions" is disabled for this code
8198 // since it considers such accessions noop
8199 if ( !support.optSelected ) {
8200 jQuery.propHooks.selected = {
8201 get: function( elem ) {
8202
8203 /* eslint no-unused-expressions: "off" */
8204
8205 var parent = elem.parentNode;
8206 if ( parent && parent.parentNode ) {
8207 parent.parentNode.selectedIndex;
8208 }
8209 return null;
8210 },
8211 set: function( elem ) {
8212
8213 /* eslint no-unused-expressions: "off" */
8214
8215 var parent = elem.parentNode;
8216 if ( parent ) {
8217 parent.selectedIndex;
8218
8219 if ( parent.parentNode ) {
8220 parent.parentNode.selectedIndex;
8221 }
8222 }
8223 }
8224 };
8225 }
8226
8227 jQuery.each( [
8228 "tabIndex",
8229 "readOnly",
8230 "maxLength",
8231 "cellSpacing",
8232 "cellPadding",
8233 "rowSpan",
8234 "colSpan",
8235 "useMap",
8236 "frameBorder",
8237 "contentEditable"
8238 ], function() {
8239 jQuery.propFix[ this.toLowerCase() ] = this;
8240 } );
8241
8242
8243
8244
8245 // Strip and collapse whitespace according to HTML spec
8246 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
8247 function stripAndCollapse( value ) {
8248 var tokens = value.match( rnothtmlwhite ) || [];
8249 return tokens.join( " " );
8250 }
8251
8252
8253 function getClass( elem ) {
8254 return elem.getAttribute && elem.getAttribute( "class" ) || "";
8255 }
8256
8257 function classesToArray( value ) {
8258 if ( Array.isArray( value ) ) {
8259 return value;
8260 }
8261 if ( typeof value === "string" ) {
8262 return value.match( rnothtmlwhite ) || [];
8263 }
8264 return [];
8265 }
8266
8267 jQuery.fn.extend( {
8268 addClass: function( value ) {
8269 var classes, elem, cur, curValue, clazz, j, finalValue,
8270 i = 0;
8271
8272 if ( isFunction( value ) ) {
8273 return this.each( function( j ) {
8274 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8275 } );
8276 }
8277
8278 classes = classesToArray( value );
8279
8280 if ( classes.length ) {
8281 while ( ( elem = this[ i++ ] ) ) {
8282 curValue = getClass( elem );
8283 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8284
8285 if ( cur ) {
8286 j = 0;
8287 while ( ( clazz = classes[ j++ ] ) ) {
8288 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8289 cur += clazz + " ";
8290 }
8291 }
8292
8293 // Only assign if different to avoid unneeded rendering.
8294 finalValue = stripAndCollapse( cur );
8295 if ( curValue !== finalValue ) {
8296 elem.setAttribute( "class", finalValue );
8297 }
8298 }
8299 }
8300 }
8301
8302 return this;
8303 },
8304
8305 removeClass: function( value ) {
8306 var classes, elem, cur, curValue, clazz, j, finalValue,
8307 i = 0;
8308
8309 if ( isFunction( value ) ) {
8310 return this.each( function( j ) {
8311 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8312 } );
8313 }
8314
8315 if ( !arguments.length ) {
8316 return this.attr( "class", "" );
8317 }
8318
8319 classes = classesToArray( value );
8320
8321 if ( classes.length ) {
8322 while ( ( elem = this[ i++ ] ) ) {
8323 curValue = getClass( elem );
8324
8325 // This expression is here for better compressibility (see addClass)
8326 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8327
8328 if ( cur ) {
8329 j = 0;
8330 while ( ( clazz = classes[ j++ ] ) ) {
8331
8332 // Remove *all* instances
8333 while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
8334 cur = cur.replace( " " + clazz + " ", " " );
8335 }
8336 }
8337
8338 // Only assign if different to avoid unneeded rendering.
8339 finalValue = stripAndCollapse( cur );
8340 if ( curValue !== finalValue ) {
8341 elem.setAttribute( "class", finalValue );
8342 }
8343 }
8344 }
8345 }
8346
8347 return this;
8348 },
8349
8350 toggleClass: function( value, stateVal ) {
8351 var type = typeof value,
8352 isValidValue = type === "string" || Array.isArray( value );
8353
8354 if ( typeof stateVal === "boolean" && isValidValue ) {
8355 return stateVal ? this.addClass( value ) : this.removeClass( value );
8356 }
8357
8358 if ( isFunction( value ) ) {
8359 return this.each( function( i ) {
8360 jQuery( this ).toggleClass(
8361 value.call( this, i, getClass( this ), stateVal ),
8362 stateVal
8363 );
8364 } );
8365 }
8366
8367 return this.each( function() {
8368 var className, i, self, classNames;
8369
8370 if ( isValidValue ) {
8371
8372 // Toggle individual class names
8373 i = 0;
8374 self = jQuery( this );
8375 classNames = classesToArray( value );
8376
8377 while ( ( className = classNames[ i++ ] ) ) {
8378
8379 // Check each className given, space separated list
8380 if ( self.hasClass( className ) ) {
8381 self.removeClass( className );
8382 } else {
8383 self.addClass( className );
8384 }
8385 }
8386
8387 // Toggle whole class name
8388 } else if ( value === undefined || type === "boolean" ) {
8389 className = getClass( this );
8390 if ( className ) {
8391
8392 // Store className if set
8393 dataPriv.set( this, "__className__", className );
8394 }
8395
8396 // If the element has a class name or if we're passed `false`,
8397 // then remove the whole classname (if there was one, the above saved it).
8398 // Otherwise bring back whatever was previously saved (if anything),
8399 // falling back to the empty string if nothing was stored.
8400 if ( this.setAttribute ) {
8401 this.setAttribute( "class",
8402 className || value === false ?
8403 "" :
8404 dataPriv.get( this, "__className__" ) || ""
8405 );
8406 }
8407 }
8408 } );
8409 },
8410
8411 hasClass: function( selector ) {
8412 var className, elem,
8413 i = 0;
8414
8415 className = " " + selector + " ";
8416 while ( ( elem = this[ i++ ] ) ) {
8417 if ( elem.nodeType === 1 &&
8418 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
8419 return true;
8420 }
8421 }
8422
8423 return false;
8424 }
8425 } );
8426
8427
8428
8429
8430 var rreturn = /\r/g;
8431
8432 jQuery.fn.extend( {
8433 val: function( value ) {
8434 var hooks, ret, valueIsFunction,
8435 elem = this[ 0 ];
8436
8437 if ( !arguments.length ) {
8438 if ( elem ) {
8439 hooks = jQuery.valHooks[ elem.type ] ||
8440 jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8441
8442 if ( hooks &&
8443 "get" in hooks &&
8444 ( ret = hooks.get( elem, "value" ) ) !== undefined
8445 ) {
8446 return ret;
8447 }
8448
8449 ret = elem.value;
8450
8451 // Handle most common string cases
8452 if ( typeof ret === "string" ) {
8453 return ret.replace( rreturn, "" );
8454 }
8455
8456 // Handle cases where value is null/undef or number
8457 return ret == null ? "" : ret;
8458 }
8459
8460 return;
8461 }
8462
8463 valueIsFunction = isFunction( value );
8464
8465 return this.each( function( i ) {
8466 var val;
8467
8468 if ( this.nodeType !== 1 ) {
8469 return;
8470 }
8471
8472 if ( valueIsFunction ) {
8473 val = value.call( this, i, jQuery( this ).val() );
8474 } else {
8475 val = value;
8476 }
8477
8478 // Treat null/undefined as ""; convert numbers to string
8479 if ( val == null ) {
8480 val = "";
8481
8482 } else if ( typeof val === "number" ) {
8483 val += "";
8484
8485 } else if ( Array.isArray( val ) ) {
8486 val = jQuery.map( val, function( value ) {
8487 return value == null ? "" : value + "";
8488 } );
8489 }
8490
8491 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8492
8493 // If set returns undefined, fall back to normal setting
8494 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8495 this.value = val;
8496 }
8497 } );
8498 }
8499 } );
8500
8501 jQuery.extend( {
8502 valHooks: {
8503 option: {
8504 get: function( elem ) {
8505
8506 var val = jQuery.find.attr( elem, "value" );
8507 return val != null ?
8508 val :
8509
8510 // Support: IE <=10 - 11 only
8511 // option.text throws exceptions (#14686, #14858)
8512 // Strip and collapse whitespace
8513 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8514 stripAndCollapse( jQuery.text( elem ) );
8515 }
8516 },
8517 select: {
8518 get: function( elem ) {
8519 var value, option, i,
8520 options = elem.options,
8521 index = elem.selectedIndex,
8522 one = elem.type === "select-one",
8523 values = one ? null : [],
8524 max = one ? index + 1 : options.length;
8525
8526 if ( index < 0 ) {
8527 i = max;
8528
8529 } else {
8530 i = one ? index : 0;
8531 }
8532
8533 // Loop through all the selected options
8534 for ( ; i < max; i++ ) {
8535 option = options[ i ];
8536
8537 // Support: IE <=9 only
8538 // IE8-9 doesn't update selected after form reset (#2551)
8539 if ( ( option.selected || i === index ) &&
8540
8541 // Don't return options that are disabled or in a disabled optgroup
8542 !option.disabled &&
8543 ( !option.parentNode.disabled ||
8544 !nodeName( option.parentNode, "optgroup" ) ) ) {
8545
8546 // Get the specific value for the option
8547 value = jQuery( option ).val();
8548
8549 // We don't need an array for one selects
8550 if ( one ) {
8551 return value;
8552 }
8553
8554 // Multi-Selects return an array
8555 values.push( value );
8556 }
8557 }
8558
8559 return values;
8560 },
8561
8562 set: function( elem, value ) {
8563 var optionSet, option,
8564 options = elem.options,
8565 values = jQuery.makeArray( value ),
8566 i = options.length;
8567
8568 while ( i-- ) {
8569 option = options[ i ];
8570
8571 /* eslint-disable no-cond-assign */
8572
8573 if ( option.selected =
8574 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
8575 ) {
8576 optionSet = true;
8577 }
8578
8579 /* eslint-enable no-cond-assign */
8580 }
8581
8582 // Force browsers to behave consistently when non-matching value is set
8583 if ( !optionSet ) {
8584 elem.selectedIndex = -1;
8585 }
8586 return values;
8587 }
8588 }
8589 }
8590 } );
8591
8592 // Radios and checkboxes getter/setter
8593 jQuery.each( [ "radio", "checkbox" ], function() {
8594 jQuery.valHooks[ this ] = {
8595 set: function( elem, value ) {
8596 if ( Array.isArray( value ) ) {
8597 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8598 }
8599 }
8600 };
8601 if ( !support.checkOn ) {
8602 jQuery.valHooks[ this ].get = function( elem ) {
8603 return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8604 };
8605 }
8606 } );
8607
8608
8609
8610
8611 // Return jQuery for attributes-only inclusion
8612
8613
8614 support.focusin = "onfocusin" in window;
8615
8616
8617 var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
8618 stopPropagationCallback = function( e ) {
8619 e.stopPropagation();
8620 };
8621
8622 jQuery.extend( jQuery.event, {
8623
8624 trigger: function( event, data, elem, onlyHandlers ) {
8625
8626 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
8627 eventPath = [ elem || document ],
8628 type = hasOwn.call( event, "type" ) ? event.type : event,
8629 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
8630
8631 cur = lastElement = tmp = elem = elem || document;
8632
8633 // Don't do events on text and comment nodes
8634 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
8635 return;
8636 }
8637
8638 // focus/blur morphs to focusin/out; ensure we're not firing them right now
8639 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
8640 return;
8641 }
8642
8643 if ( type.indexOf( "." ) > -1 ) {
8644
8645 // Namespaced trigger; create a regexp to match event type in handle()
8646 namespaces = type.split( "." );
8647 type = namespaces.shift();
8648 namespaces.sort();
8649 }
8650 ontype = type.indexOf( ":" ) < 0 && "on" + type;
8651
8652 // Caller can pass in a jQuery.Event object, Object, or just an event type string
8653 event = event[ jQuery.expando ] ?
8654 event :
8655 new jQuery.Event( type, typeof event === "object" && event );
8656
8657 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8658 event.isTrigger = onlyHandlers ? 2 : 3;
8659 event.namespace = namespaces.join( "." );
8660 event.rnamespace = event.namespace ?
8661 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
8662 null;
8663
8664 // Clean up the event in case it is being reused
8665 event.result = undefined;
8666 if ( !event.target ) {
8667 event.target = elem;
8668 }
8669
8670 // Clone any incoming data and prepend the event, creating the handler arg list
8671 data = data == null ?
8672 [ event ] :
8673 jQuery.makeArray( data, [ event ] );
8674
8675 // Allow special events to draw outside the lines
8676 special = jQuery.event.special[ type ] || {};
8677 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
8678 return;
8679 }
8680
8681 // Determine event propagation path in advance, per W3C events spec (#9951)
8682 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
8683 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
8684
8685 bubbleType = special.delegateType || type;
8686 if ( !rfocusMorph.test( bubbleType + type ) ) {
8687 cur = cur.parentNode;
8688 }
8689 for ( ; cur; cur = cur.parentNode ) {
8690 eventPath.push( cur );
8691 tmp = cur;
8692 }
8693
8694 // Only add window if we got to document (e.g., not plain obj or detached DOM)
8695 if ( tmp === ( elem.ownerDocument || document ) ) {
8696 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
8697 }
8698 }
8699
8700 // Fire handlers on the event path
8701 i = 0;
8702 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
8703 lastElement = cur;
8704 event.type = i > 1 ?
8705 bubbleType :
8706 special.bindType || type;
8707
8708 // jQuery handler
8709 handle = (
8710 dataPriv.get( cur, "events" ) || Object.create( null )
8711 )[ event.type ] &&
8712 dataPriv.get( cur, "handle" );
8713 if ( handle ) {
8714 handle.apply( cur, data );
8715 }
8716
8717 // Native handler
8718 handle = ontype && cur[ ontype ];
8719 if ( handle && handle.apply && acceptData( cur ) ) {
8720 event.result = handle.apply( cur, data );
8721 if ( event.result === false ) {
8722 event.preventDefault();
8723 }
8724 }
8725 }
8726 event.type = type;
8727
8728 // If nobody prevented the default action, do it now
8729 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
8730
8731 if ( ( !special._default ||
8732 special._default.apply( eventPath.pop(), data ) === false ) &&
8733 acceptData( elem ) ) {
8734
8735 // Call a native DOM method on the target with the same name as the event.
8736 // Don't do default actions on window, that's where global variables be (#6170)
8737 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
8738
8739 // Don't re-trigger an onFOO event when we call its FOO() method
8740 tmp = elem[ ontype ];
8741
8742 if ( tmp ) {
8743 elem[ ontype ] = null;
8744 }
8745
8746 // Prevent re-triggering of the same event, since we already bubbled it above
8747 jQuery.event.triggered = type;
8748
8749 if ( event.isPropagationStopped() ) {
8750 lastElement.addEventListener( type, stopPropagationCallback );
8751 }
8752
8753 elem[ type ]();
8754
8755 if ( event.isPropagationStopped() ) {
8756 lastElement.removeEventListener( type, stopPropagationCallback );
8757 }
8758
8759 jQuery.event.triggered = undefined;
8760
8761 if ( tmp ) {
8762 elem[ ontype ] = tmp;
8763 }
8764 }
8765 }
8766 }
8767
8768 return event.result;
8769 },
8770
8771 // Piggyback on a donor event to simulate a different one
8772 // Used only for `focus(in | out)` events
8773 simulate: function( type, elem, event ) {
8774 var e = jQuery.extend(
8775 new jQuery.Event(),
8776 event,
8777 {
8778 type: type,
8779 isSimulated: true
8780 }
8781 );
8782
8783 jQuery.event.trigger( e, null, elem );
8784 }
8785
8786 } );
8787
8788 jQuery.fn.extend( {
8789
8790 trigger: function( type, data ) {
8791 return this.each( function() {
8792 jQuery.event.trigger( type, data, this );
8793 } );
8794 },
8795 triggerHandler: function( type, data ) {
8796 var elem = this[ 0 ];
8797 if ( elem ) {
8798 return jQuery.event.trigger( type, data, elem, true );
8799 }
8800 }
8801 } );
8802
8803
8804 // Support: Firefox <=44
8805 // Firefox doesn't have focus(in | out) events
8806 // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
8807 //
8808 // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
8809 // focus(in | out) events fire after focus & blur events,
8810 // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
8811 // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
8812 if ( !support.focusin ) {
8813 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
8814
8815 // Attach a single capturing handler on the document while someone wants focusin/focusout
8816 var handler = function( event ) {
8817 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
8818 };
8819
8820 jQuery.event.special[ fix ] = {
8821 setup: function() {
8822
8823 // Handle: regular nodes (via `this.ownerDocument`), window
8824 // (via `this.document`) & document (via `this`).
8825 var doc = this.ownerDocument || this.document || this,
8826 attaches = dataPriv.access( doc, fix );
8827
8828 if ( !attaches ) {
8829 doc.addEventListener( orig, handler, true );
8830 }
8831 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
8832 },
8833 teardown: function() {
8834 var doc = this.ownerDocument || this.document || this,
8835 attaches = dataPriv.access( doc, fix ) - 1;
8836
8837 if ( !attaches ) {
8838 doc.removeEventListener( orig, handler, true );
8839 dataPriv.remove( doc, fix );
8840
8841 } else {
8842 dataPriv.access( doc, fix, attaches );
8843 }
8844 }
8845 };
8846 } );
8847 }
8848 var location = window.location;
8849
8850 var nonce = { guid: Date.now() };
8851
8852 var rquery = ( /\?/ );
8853
8854
8855
8856 // Cross-browser xml parsing
8857 jQuery.parseXML = function( data ) {
8858 var xml;
8859 if ( !data || typeof data !== "string" ) {
8860 return null;
8861 }
8862
8863 // Support: IE 9 - 11 only
8864 // IE throws on parseFromString with invalid input.
8865 try {
8866 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
8867 } catch ( e ) {
8868 xml = undefined;
8869 }
8870
8871 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
8872 jQuery.error( "Invalid XML: " + data );
8873 }
8874 return xml;
8875 };
8876
8877
8878 var
8879 rbracket = /\[\]$/,
8880 rCRLF = /\r?\n/g,
8881 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8882 rsubmittable = /^(?:input|select|textarea|keygen)/i;
8883
8884 function buildParams( prefix, obj, traditional, add ) {
8885 var name;
8886
8887 if ( Array.isArray( obj ) ) {
8888
8889 // Serialize array item.
8890 jQuery.each( obj, function( i, v ) {
8891 if ( traditional || rbracket.test( prefix ) ) {
8892
8893 // Treat each array item as a scalar.
8894 add( prefix, v );
8895
8896 } else {
8897
8898 // Item is non-scalar (array or object), encode its numeric index.
8899 buildParams(
8900 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8901 v,
8902 traditional,
8903 add
8904 );
8905 }
8906 } );
8907
8908 } else if ( !traditional && toType( obj ) === "object" ) {
8909
8910 // Serialize object item.
8911 for ( name in obj ) {
8912 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8913 }
8914
8915 } else {
8916
8917 // Serialize scalar item.
8918 add( prefix, obj );
8919 }
8920 }
8921
8922 // Serialize an array of form elements or a set of
8923 // key/values into a query string
8924 jQuery.param = function( a, traditional ) {
8925 var prefix,
8926 s = [],
8927 add = function( key, valueOrFunction ) {
8928
8929 // If value is a function, invoke it and use its return value
8930 var value = isFunction( valueOrFunction ) ?
8931 valueOrFunction() :
8932 valueOrFunction;
8933
8934 s[ s.length ] = encodeURIComponent( key ) + "=" +
8935 encodeURIComponent( value == null ? "" : value );
8936 };
8937
8938 if ( a == null ) {
8939 return "";
8940 }
8941
8942 // If an array was passed in, assume that it is an array of form elements.
8943 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8944
8945 // Serialize the form elements
8946 jQuery.each( a, function() {
8947 add( this.name, this.value );
8948 } );
8949
8950 } else {
8951
8952 // If traditional, encode the "old" way (the way 1.3.2 or older
8953 // did it), otherwise encode params recursively.
8954 for ( prefix in a ) {
8955 buildParams( prefix, a[ prefix ], traditional, add );
8956 }
8957 }
8958
8959 // Return the resulting serialization
8960 return s.join( "&" );
8961 };
8962
8963 jQuery.fn.extend( {
8964 serialize: function() {
8965 return jQuery.param( this.serializeArray() );
8966 },
8967 serializeArray: function() {
8968 return this.map( function() {
8969
8970 // Can add propHook for "elements" to filter or add form elements
8971 var elements = jQuery.prop( this, "elements" );
8972 return elements ? jQuery.makeArray( elements ) : this;
8973 } )
8974 .filter( function() {
8975 var type = this.type;
8976
8977 // Use .is( ":disabled" ) so that fieldset[disabled] works
8978 return this.name && !jQuery( this ).is( ":disabled" ) &&
8979 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
8980 ( this.checked || !rcheckableType.test( type ) );
8981 } )
8982 .map( function( _i, elem ) {
8983 var val = jQuery( this ).val();
8984
8985 if ( val == null ) {
8986 return null;
8987 }
8988
8989 if ( Array.isArray( val ) ) {
8990 return jQuery.map( val, function( val ) {
8991 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8992 } );
8993 }
8994
8995 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8996 } ).get();
8997 }
8998 } );
8999
9000
9001 var
9002 r20 = /%20/g,
9003 rhash = /#.*$/,
9004 rantiCache = /([?&])_=[^&]*/,
9005 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
9006
9007 // #7653, #8125, #8152: local protocol detection
9008 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9009 rnoContent = /^(?:GET|HEAD)$/,
9010 rprotocol = /^\/\//,
9011
9012 /* Prefilters
9013 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9014 * 2) These are called:
9015 * - BEFORE asking for a transport
9016 * - AFTER param serialization (s.data is a string if s.processData is true)
9017 * 3) key is the dataType
9018 * 4) the catchall symbol "*" can be used
9019 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9020 */
9021 prefilters = {},
9022
9023 /* Transports bindings
9024 * 1) key is the dataType
9025 * 2) the catchall symbol "*" can be used
9026 * 3) selection will start with transport dataType and THEN go to "*" if needed
9027 */
9028 transports = {},
9029
9030 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
9031 allTypes = "*/".concat( "*" ),
9032
9033 // Anchor tag for parsing the document origin
9034 originAnchor = document.createElement( "a" );
9035 originAnchor.href = location.href;
9036
9037 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9038 function addToPrefiltersOrTransports( structure ) {
9039
9040 // dataTypeExpression is optional and defaults to "*"
9041 return function( dataTypeExpression, func ) {
9042
9043 if ( typeof dataTypeExpression !== "string" ) {
9044 func = dataTypeExpression;
9045 dataTypeExpression = "*";
9046 }
9047
9048 var dataType,
9049 i = 0,
9050 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
9051
9052 if ( isFunction( func ) ) {
9053
9054 // For each dataType in the dataTypeExpression
9055 while ( ( dataType = dataTypes[ i++ ] ) ) {
9056
9057 // Prepend if requested
9058 if ( dataType[ 0 ] === "+" ) {
9059 dataType = dataType.slice( 1 ) || "*";
9060 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9061
9062 // Otherwise append
9063 } else {
9064 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9065 }
9066 }
9067 }
9068 };
9069 }
9070
9071 // Base inspection function for prefilters and transports
9072 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9073
9074 var inspected = {},
9075 seekingTransport = ( structure === transports );
9076
9077 function inspect( dataType ) {
9078 var selected;
9079 inspected[ dataType ] = true;
9080 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9081 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9082 if ( typeof dataTypeOrTransport === "string" &&
9083 !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9084
9085 options.dataTypes.unshift( dataTypeOrTransport );
9086 inspect( dataTypeOrTransport );
9087 return false;
9088 } else if ( seekingTransport ) {
9089 return !( selected = dataTypeOrTransport );
9090 }
9091 } );
9092 return selected;
9093 }
9094
9095 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9096 }
9097
9098 // A special extend for ajax options
9099 // that takes "flat" options (not to be deep extended)
9100 // Fixes #9887
9101 function ajaxExtend( target, src ) {
9102 var key, deep,
9103 flatOptions = jQuery.ajaxSettings.flatOptions || {};
9104
9105 for ( key in src ) {
9106 if ( src[ key ] !== undefined ) {
9107 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9108 }
9109 }
9110 if ( deep ) {
9111 jQuery.extend( true, target, deep );
9112 }
9113
9114 return target;
9115 }
9116
9117 /* Handles responses to an ajax request:
9118 * - finds the right dataType (mediates between content-type and expected dataType)
9119 * - returns the corresponding response
9120 */
9121 function ajaxHandleResponses( s, jqXHR, responses ) {
9122
9123 var ct, type, finalDataType, firstDataType,
9124 contents = s.contents,
9125 dataTypes = s.dataTypes;
9126
9127 // Remove auto dataType and get content-type in the process
9128 while ( dataTypes[ 0 ] === "*" ) {
9129 dataTypes.shift();
9130 if ( ct === undefined ) {
9131 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9132 }
9133 }
9134
9135 // Check if we're dealing with a known content-type
9136 if ( ct ) {
9137 for ( type in contents ) {
9138 if ( contents[ type ] && contents[ type ].test( ct ) ) {
9139 dataTypes.unshift( type );
9140 break;
9141 }
9142 }
9143 }
9144
9145 // Check to see if we have a response for the expected dataType
9146 if ( dataTypes[ 0 ] in responses ) {
9147 finalDataType = dataTypes[ 0 ];
9148 } else {
9149
9150 // Try convertible dataTypes
9151 for ( type in responses ) {
9152 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9153 finalDataType = type;
9154 break;
9155 }
9156 if ( !firstDataType ) {
9157 firstDataType = type;
9158 }
9159 }
9160
9161 // Or just use first one
9162 finalDataType = finalDataType || firstDataType;
9163 }
9164
9165 // If we found a dataType
9166 // We add the dataType to the list if needed
9167 // and return the corresponding response
9168 if ( finalDataType ) {
9169 if ( finalDataType !== dataTypes[ 0 ] ) {
9170 dataTypes.unshift( finalDataType );
9171 }
9172 return responses[ finalDataType ];
9173 }
9174 }
9175
9176 /* Chain conversions given the request and the original response
9177 * Also sets the responseXXX fields on the jqXHR instance
9178 */
9179 function ajaxConvert( s, response, jqXHR, isSuccess ) {
9180 var conv2, current, conv, tmp, prev,
9181 converters = {},
9182
9183 // Work with a copy of dataTypes in case we need to modify it for conversion
9184 dataTypes = s.dataTypes.slice();
9185
9186 // Create converters map with lowercased keys
9187 if ( dataTypes[ 1 ] ) {
9188 for ( conv in s.converters ) {
9189 converters[ conv.toLowerCase() ] = s.converters[ conv ];
9190 }
9191 }
9192
9193 current = dataTypes.shift();
9194
9195 // Convert to each sequential dataType
9196 while ( current ) {
9197
9198 if ( s.responseFields[ current ] ) {
9199 jqXHR[ s.responseFields[ current ] ] = response;
9200 }
9201
9202 // Apply the dataFilter if provided
9203 if ( !prev && isSuccess && s.dataFilter ) {
9204 response = s.dataFilter( response, s.dataType );
9205 }
9206
9207 prev = current;
9208 current = dataTypes.shift();
9209
9210 if ( current ) {
9211
9212 // There's only work to do if current dataType is non-auto
9213 if ( current === "*" ) {
9214
9215 current = prev;
9216
9217 // Convert response if prev dataType is non-auto and differs from current
9218 } else if ( prev !== "*" && prev !== current ) {
9219
9220 // Seek a direct converter
9221 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9222
9223 // If none found, seek a pair
9224 if ( !conv ) {
9225 for ( conv2 in converters ) {
9226
9227 // If conv2 outputs current
9228 tmp = conv2.split( " " );
9229 if ( tmp[ 1 ] === current ) {
9230
9231 // If prev can be converted to accepted input
9232 conv = converters[ prev + " " + tmp[ 0 ] ] ||
9233 converters[ "* " + tmp[ 0 ] ];
9234 if ( conv ) {
9235
9236 // Condense equivalence converters
9237 if ( conv === true ) {
9238 conv = converters[ conv2 ];
9239
9240 // Otherwise, insert the intermediate dataType
9241 } else if ( converters[ conv2 ] !== true ) {
9242 current = tmp[ 0 ];
9243 dataTypes.unshift( tmp[ 1 ] );
9244 }
9245 break;
9246 }
9247 }
9248 }
9249 }
9250
9251 // Apply converter (if not an equivalence)
9252 if ( conv !== true ) {
9253
9254 // Unless errors are allowed to bubble, catch and return them
9255 if ( conv && s.throws ) {
9256 response = conv( response );
9257 } else {
9258 try {
9259 response = conv( response );
9260 } catch ( e ) {
9261 return {
9262 state: "parsererror",
9263 error: conv ? e : "No conversion from " + prev + " to " + current
9264 };
9265 }
9266 }
9267 }
9268 }
9269 }
9270 }
9271
9272 return { state: "success", data: response };
9273 }
9274
9275 jQuery.extend( {
9276
9277 // Counter for holding the number of active queries
9278 active: 0,
9279
9280 // Last-Modified header cache for next request
9281 lastModified: {},
9282 etag: {},
9283
9284 ajaxSettings: {
9285 url: location.href,
9286 type: "GET",
9287 isLocal: rlocalProtocol.test( location.protocol ),
9288 global: true,
9289 processData: true,
9290 async: true,
9291 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9292
9293 /*
9294 timeout: 0,
9295 data: null,
9296 dataType: null,
9297 username: null,
9298 password: null,
9299 cache: null,
9300 throws: false,
9301 traditional: false,
9302 headers: {},
9303 */
9304
9305 accepts: {
9306 "*": allTypes,
9307 text: "text/plain",
9308 html: "text/html",
9309 xml: "application/xml, text/xml",
9310 json: "application/json, text/javascript"
9311 },
9312
9313 contents: {
9314 xml: /\bxml\b/,
9315 html: /\bhtml/,
9316 json: /\bjson\b/
9317 },
9318
9319 responseFields: {
9320 xml: "responseXML",
9321 text: "responseText",
9322 json: "responseJSON"
9323 },
9324
9325 // Data converters
9326 // Keys separate source (or catchall "*") and destination types with a single space
9327 converters: {
9328
9329 // Convert anything to text
9330 "* text": String,
9331
9332 // Text to html (true = no transformation)
9333 "text html": true,
9334
9335 // Evaluate text as a json expression
9336 "text json": JSON.parse,
9337
9338 // Parse text as xml
9339 "text xml": jQuery.parseXML
9340 },
9341
9342 // For options that shouldn't be deep extended:
9343 // you can add your own custom options here if
9344 // and when you create one that shouldn't be
9345 // deep extended (see ajaxExtend)
9346 flatOptions: {
9347 url: true,
9348 context: true
9349 }
9350 },
9351
9352 // Creates a full fledged settings object into target
9353 // with both ajaxSettings and settings fields.
9354 // If target is omitted, writes into ajaxSettings.
9355 ajaxSetup: function( target, settings ) {
9356 return settings ?
9357
9358 // Building a settings object
9359 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9360
9361 // Extending ajaxSettings
9362 ajaxExtend( jQuery.ajaxSettings, target );
9363 },
9364
9365 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9366 ajaxTransport: addToPrefiltersOrTransports( transports ),
9367
9368 // Main method
9369 ajax: function( url, options ) {
9370
9371 // If url is an object, simulate pre-1.5 signature
9372 if ( typeof url === "object" ) {
9373 options = url;
9374 url = undefined;
9375 }
9376
9377 // Force options to be an object
9378 options = options || {};
9379
9380 var transport,
9381
9382 // URL without anti-cache param
9383 cacheURL,
9384
9385 // Response headers
9386 responseHeadersString,
9387 responseHeaders,
9388
9389 // timeout handle
9390 timeoutTimer,
9391
9392 // Url cleanup var
9393 urlAnchor,
9394
9395 // Request state (becomes false upon send and true upon completion)
9396 completed,
9397
9398 // To know if global events are to be dispatched
9399 fireGlobals,
9400
9401 // Loop variable
9402 i,
9403
9404 // uncached part of the url
9405 uncached,
9406
9407 // Create the final options object
9408 s = jQuery.ajaxSetup( {}, options ),
9409
9410 // Callbacks context
9411 callbackContext = s.context || s,
9412
9413 // Context for global events is callbackContext if it is a DOM node or jQuery collection
9414 globalEventContext = s.context &&
9415 ( callbackContext.nodeType || callbackContext.jquery ) ?
9416 jQuery( callbackContext ) :
9417 jQuery.event,
9418
9419 // Deferreds
9420 deferred = jQuery.Deferred(),
9421 completeDeferred = jQuery.Callbacks( "once memory" ),
9422
9423 // Status-dependent callbacks
9424 statusCode = s.statusCode || {},
9425
9426 // Headers (they are sent all at once)
9427 requestHeaders = {},
9428 requestHeadersNames = {},
9429
9430 // Default abort message
9431 strAbort = "canceled",
9432
9433 // Fake xhr
9434 jqXHR = {
9435 readyState: 0,
9436
9437 // Builds headers hashtable if needed
9438 getResponseHeader: function( key ) {
9439 var match;
9440 if ( completed ) {
9441 if ( !responseHeaders ) {
9442 responseHeaders = {};
9443 while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9444 responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
9445 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
9446 .concat( match[ 2 ] );
9447 }
9448 }
9449 match = responseHeaders[ key.toLowerCase() + " " ];
9450 }
9451 return match == null ? null : match.join( ", " );
9452 },
9453
9454 // Raw string
9455 getAllResponseHeaders: function() {
9456 return completed ? responseHeadersString : null;
9457 },
9458
9459 // Caches the header
9460 setRequestHeader: function( name, value ) {
9461 if ( completed == null ) {
9462 name = requestHeadersNames[ name.toLowerCase() ] =
9463 requestHeadersNames[ name.toLowerCase() ] || name;
9464 requestHeaders[ name ] = value;
9465 }
9466 return this;
9467 },
9468
9469 // Overrides response content-type header
9470 overrideMimeType: function( type ) {
9471 if ( completed == null ) {
9472 s.mimeType = type;
9473 }
9474 return this;
9475 },
9476
9477 // Status-dependent callbacks
9478 statusCode: function( map ) {
9479 var code;
9480 if ( map ) {
9481 if ( completed ) {
9482
9483 // Execute the appropriate callbacks
9484 jqXHR.always( map[ jqXHR.status ] );
9485 } else {
9486
9487 // Lazy-add the new callbacks in a way that preserves old ones
9488 for ( code in map ) {
9489 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9490 }
9491 }
9492 }
9493 return this;
9494 },
9495
9496 // Cancel the request
9497 abort: function( statusText ) {
9498 var finalText = statusText || strAbort;
9499 if ( transport ) {
9500 transport.abort( finalText );
9501 }
9502 done( 0, finalText );
9503 return this;
9504 }
9505 };
9506
9507 // Attach deferreds
9508 deferred.promise( jqXHR );
9509
9510 // Add protocol if not provided (prefilters might expect it)
9511 // Handle falsy url in the settings object (#10093: consistency with old signature)
9512 // We also use the url parameter if available
9513 s.url = ( ( url || s.url || location.href ) + "" )
9514 .replace( rprotocol, location.protocol + "//" );
9515
9516 // Alias method option to type as per ticket #12004
9517 s.type = options.method || options.type || s.method || s.type;
9518
9519 // Extract dataTypes list
9520 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
9521
9522 // A cross-domain request is in order when the origin doesn't match the current origin.
9523 if ( s.crossDomain == null ) {
9524 urlAnchor = document.createElement( "a" );
9525
9526 // Support: IE <=8 - 11, Edge 12 - 15
9527 // IE throws exception on accessing the href property if url is malformed,
9528 // e.g. http://example.com:80x/
9529 try {
9530 urlAnchor.href = s.url;
9531
9532 // Support: IE <=8 - 11 only
9533 // Anchor's host property isn't correctly set when s.url is relative
9534 urlAnchor.href = urlAnchor.href;
9535 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9536 urlAnchor.protocol + "//" + urlAnchor.host;
9537 } catch ( e ) {
9538
9539 // If there is an error parsing the URL, assume it is crossDomain,
9540 // it can be rejected by the transport if it is invalid
9541 s.crossDomain = true;
9542 }
9543 }
9544
9545 // Convert data if not already a string
9546 if ( s.data && s.processData && typeof s.data !== "string" ) {
9547 s.data = jQuery.param( s.data, s.traditional );
9548 }
9549
9550 // Apply prefilters
9551 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9552
9553 // If request was aborted inside a prefilter, stop there
9554 if ( completed ) {
9555 return jqXHR;
9556 }
9557
9558 // We can fire global events as of now if asked to
9559 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9560 fireGlobals = jQuery.event && s.global;
9561
9562 // Watch for a new set of requests
9563 if ( fireGlobals && jQuery.active++ === 0 ) {
9564 jQuery.event.trigger( "ajaxStart" );
9565 }
9566
9567 // Uppercase the type
9568 s.type = s.type.toUpperCase();
9569
9570 // Determine if request has content
9571 s.hasContent = !rnoContent.test( s.type );
9572
9573 // Save the URL in case we're toying with the If-Modified-Since
9574 // and/or If-None-Match header later on
9575 // Remove hash to simplify url manipulation
9576 cacheURL = s.url.replace( rhash, "" );
9577
9578 // More options handling for requests with no content
9579 if ( !s.hasContent ) {
9580
9581 // Remember the hash so we can put it back
9582 uncached = s.url.slice( cacheURL.length );
9583
9584 // If data is available and should be processed, append data to url
9585 if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
9586 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
9587
9588 // #9682: remove data so that it's not used in an eventual retry
9589 delete s.data;
9590 }
9591
9592 // Add or update anti-cache param if needed
9593 if ( s.cache === false ) {
9594 cacheURL = cacheURL.replace( rantiCache, "$1" );
9595 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
9596 uncached;
9597 }
9598
9599 // Put hash and anti-cache on the URL that will be requested (gh-1732)
9600 s.url = cacheURL + uncached;
9601
9602 // Change '%20' to '+' if this is encoded form body content (gh-2658)
9603 } else if ( s.data && s.processData &&
9604 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
9605 s.data = s.data.replace( r20, "+" );
9606 }
9607
9608 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9609 if ( s.ifModified ) {
9610 if ( jQuery.lastModified[ cacheURL ] ) {
9611 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9612 }
9613 if ( jQuery.etag[ cacheURL ] ) {
9614 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9615 }
9616 }
9617
9618 // Set the correct header, if data is being sent
9619 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9620 jqXHR.setRequestHeader( "Content-Type", s.contentType );
9621 }
9622
9623 // Set the Accepts header for the server, depending on the dataType
9624 jqXHR.setRequestHeader(
9625 "Accept",
9626 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9627 s.accepts[ s.dataTypes[ 0 ] ] +
9628 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9629 s.accepts[ "*" ]
9630 );
9631
9632 // Check for headers option
9633 for ( i in s.headers ) {
9634 jqXHR.setRequestHeader( i, s.headers[ i ] );
9635 }
9636
9637 // Allow custom headers/mimetypes and early abort
9638 if ( s.beforeSend &&
9639 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
9640
9641 // Abort if not done already and return
9642 return jqXHR.abort();
9643 }
9644
9645 // Aborting is no longer a cancellation
9646 strAbort = "abort";
9647
9648 // Install callbacks on deferreds
9649 completeDeferred.add( s.complete );
9650 jqXHR.done( s.success );
9651 jqXHR.fail( s.error );
9652
9653 // Get transport
9654 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9655
9656 // If no transport, we auto-abort
9657 if ( !transport ) {
9658 done( -1, "No Transport" );
9659 } else {
9660 jqXHR.readyState = 1;
9661
9662 // Send global event
9663 if ( fireGlobals ) {
9664 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9665 }
9666
9667 // If request was aborted inside ajaxSend, stop there
9668 if ( completed ) {
9669 return jqXHR;
9670 }
9671
9672 // Timeout
9673 if ( s.async && s.timeout > 0 ) {
9674 timeoutTimer = window.setTimeout( function() {
9675 jqXHR.abort( "timeout" );
9676 }, s.timeout );
9677 }
9678
9679 try {
9680 completed = false;
9681 transport.send( requestHeaders, done );
9682 } catch ( e ) {
9683
9684 // Rethrow post-completion exceptions
9685 if ( completed ) {
9686 throw e;
9687 }
9688
9689 // Propagate others as results
9690 done( -1, e );
9691 }
9692 }
9693
9694 // Callback for when everything is done
9695 function done( status, nativeStatusText, responses, headers ) {
9696 var isSuccess, success, error, response, modified,
9697 statusText = nativeStatusText;
9698
9699 // Ignore repeat invocations
9700 if ( completed ) {
9701 return;
9702 }
9703
9704 completed = true;
9705
9706 // Clear timeout if it exists
9707 if ( timeoutTimer ) {
9708 window.clearTimeout( timeoutTimer );
9709 }
9710
9711 // Dereference transport for early garbage collection
9712 // (no matter how long the jqXHR object will be used)
9713 transport = undefined;
9714
9715 // Cache response headers
9716 responseHeadersString = headers || "";
9717
9718 // Set readyState
9719 jqXHR.readyState = status > 0 ? 4 : 0;
9720
9721 // Determine if successful
9722 isSuccess = status >= 200 && status < 300 || status === 304;
9723
9724 // Get response data
9725 if ( responses ) {
9726 response = ajaxHandleResponses( s, jqXHR, responses );
9727 }
9728
9729 // Use a noop converter for missing script
9730 if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) {
9731 s.converters[ "text script" ] = function() {};
9732 }
9733
9734 // Convert no matter what (that way responseXXX fields are always set)
9735 response = ajaxConvert( s, response, jqXHR, isSuccess );
9736
9737 // If successful, handle type chaining
9738 if ( isSuccess ) {
9739
9740 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9741 if ( s.ifModified ) {
9742 modified = jqXHR.getResponseHeader( "Last-Modified" );
9743 if ( modified ) {
9744 jQuery.lastModified[ cacheURL ] = modified;
9745 }
9746 modified = jqXHR.getResponseHeader( "etag" );
9747 if ( modified ) {
9748 jQuery.etag[ cacheURL ] = modified;
9749 }
9750 }
9751
9752 // if no content
9753 if ( status === 204 || s.type === "HEAD" ) {
9754 statusText = "nocontent";
9755
9756 // if not modified
9757 } else if ( status === 304 ) {
9758 statusText = "notmodified";
9759
9760 // If we have data, let's convert it
9761 } else {
9762 statusText = response.state;
9763 success = response.data;
9764 error = response.error;
9765 isSuccess = !error;
9766 }
9767 } else {
9768
9769 // Extract error from statusText and normalize for non-aborts
9770 error = statusText;
9771 if ( status || !statusText ) {
9772 statusText = "error";
9773 if ( status < 0 ) {
9774 status = 0;
9775 }
9776 }
9777 }
9778
9779 // Set data for the fake xhr object
9780 jqXHR.status = status;
9781 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9782
9783 // Success/Error
9784 if ( isSuccess ) {
9785 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9786 } else {
9787 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9788 }
9789
9790 // Status-dependent callbacks
9791 jqXHR.statusCode( statusCode );
9792 statusCode = undefined;
9793
9794 if ( fireGlobals ) {
9795 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9796 [ jqXHR, s, isSuccess ? success : error ] );
9797 }
9798
9799 // Complete
9800 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9801
9802 if ( fireGlobals ) {
9803 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9804
9805 // Handle the global AJAX counter
9806 if ( !( --jQuery.active ) ) {
9807 jQuery.event.trigger( "ajaxStop" );
9808 }
9809 }
9810 }
9811
9812 return jqXHR;
9813 },
9814
9815 getJSON: function( url, data, callback ) {
9816 return jQuery.get( url, data, callback, "json" );
9817 },
9818
9819 getScript: function( url, callback ) {
9820 return jQuery.get( url, undefined, callback, "script" );
9821 }
9822 } );
9823
9824 jQuery.each( [ "get", "post" ], function( _i, method ) {
9825 jQuery[ method ] = function( url, data, callback, type ) {
9826
9827 // Shift arguments if data argument was omitted
9828 if ( isFunction( data ) ) {
9829 type = type || callback;
9830 callback = data;
9831 data = undefined;
9832 }
9833
9834 // The url can be an options object (which then must have .url)
9835 return jQuery.ajax( jQuery.extend( {
9836 url: url,
9837 type: method,
9838 dataType: type,
9839 data: data,
9840 success: callback
9841 }, jQuery.isPlainObject( url ) && url ) );
9842 };
9843 } );
9844
9845 jQuery.ajaxPrefilter( function( s ) {
9846 var i;
9847 for ( i in s.headers ) {
9848 if ( i.toLowerCase() === "content-type" ) {
9849 s.contentType = s.headers[ i ] || "";
9850 }
9851 }
9852 } );
9853
9854
9855 jQuery._evalUrl = function( url, options, doc ) {
9856 return jQuery.ajax( {
9857 url: url,
9858
9859 // Make this explicit, since user can override this through ajaxSetup (#11264)
9860 type: "GET",
9861 dataType: "script",
9862 cache: true,
9863 async: false,
9864 global: false,
9865
9866 // Only evaluate the response if it is successful (gh-4126)
9867 // dataFilter is not invoked for failure responses, so using it instead
9868 // of the default converter is kludgy but it works.
9869 converters: {
9870 "text script": function() {}
9871 },
9872 dataFilter: function( response ) {
9873 jQuery.globalEval( response, options, doc );
9874 }
9875 } );
9876 };
9877
9878
9879 jQuery.fn.extend( {
9880 wrapAll: function( html ) {
9881 var wrap;
9882
9883 if ( this[ 0 ] ) {
9884 if ( isFunction( html ) ) {
9885 html = html.call( this[ 0 ] );
9886 }
9887
9888 // The elements to wrap the target around
9889 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9890
9891 if ( this[ 0 ].parentNode ) {
9892 wrap.insertBefore( this[ 0 ] );
9893 }
9894
9895 wrap.map( function() {
9896 var elem = this;
9897
9898 while ( elem.firstElementChild ) {
9899 elem = elem.firstElementChild;
9900 }
9901
9902 return elem;
9903 } ).append( this );
9904 }
9905
9906 return this;
9907 },
9908
9909 wrapInner: function( html ) {
9910 if ( isFunction( html ) ) {
9911 return this.each( function( i ) {
9912 jQuery( this ).wrapInner( html.call( this, i ) );
9913 } );
9914 }
9915
9916 return this.each( function() {
9917 var self = jQuery( this ),
9918 contents = self.contents();
9919
9920 if ( contents.length ) {
9921 contents.wrapAll( html );
9922
9923 } else {
9924 self.append( html );
9925 }
9926 } );
9927 },
9928
9929 wrap: function( html ) {
9930 var htmlIsFunction = isFunction( html );
9931
9932 return this.each( function( i ) {
9933 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
9934 } );
9935 },
9936
9937 unwrap: function( selector ) {
9938 this.parent( selector ).not( "body" ).each( function() {
9939 jQuery( this ).replaceWith( this.childNodes );
9940 } );
9941 return this;
9942 }
9943 } );
9944
9945
9946 jQuery.expr.pseudos.hidden = function( elem ) {
9947 return !jQuery.expr.pseudos.visible( elem );
9948 };
9949 jQuery.expr.pseudos.visible = function( elem ) {
9950 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
9951 };
9952
9953
9954
9955
9956 jQuery.ajaxSettings.xhr = function() {
9957 try {
9958 return new window.XMLHttpRequest();
9959 } catch ( e ) {}
9960 };
9961
9962 var xhrSuccessStatus = {
9963
9964 // File protocol always yields status code 0, assume 200
9965 0: 200,
9966
9967 // Support: IE <=9 only
9968 // #1450: sometimes IE returns 1223 when it should be 204
9969 1223: 204
9970 },
9971 xhrSupported = jQuery.ajaxSettings.xhr();
9972
9973 support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9974 support.ajax = xhrSupported = !!xhrSupported;
9975
9976 jQuery.ajaxTransport( function( options ) {
9977 var callback, errorCallback;
9978
9979 // Cross domain only allowed if supported through XMLHttpRequest
9980 if ( support.cors || xhrSupported && !options.crossDomain ) {
9981 return {
9982 send: function( headers, complete ) {
9983 var i,
9984 xhr = options.xhr();
9985
9986 xhr.open(
9987 options.type,
9988 options.url,
9989 options.async,
9990 options.username,
9991 options.password
9992 );
9993
9994 // Apply custom fields if provided
9995 if ( options.xhrFields ) {
9996 for ( i in options.xhrFields ) {
9997 xhr[ i ] = options.xhrFields[ i ];
9998 }
9999 }
10000
10001 // Override mime type if needed
10002 if ( options.mimeType && xhr.overrideMimeType ) {
10003 xhr.overrideMimeType( options.mimeType );
10004 }
10005
10006 // X-Requested-With header
10007 // For cross-domain requests, seeing as conditions for a preflight are
10008 // akin to a jigsaw puzzle, we simply never set it to be sure.
10009 // (it can always be set on a per-request basis or even using ajaxSetup)
10010 // For same-domain requests, won't change header if already provided.
10011 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10012 headers[ "X-Requested-With" ] = "XMLHttpRequest";
10013 }
10014
10015 // Set headers
10016 for ( i in headers ) {
10017 xhr.setRequestHeader( i, headers[ i ] );
10018 }
10019
10020 // Callback
10021 callback = function( type ) {
10022 return function() {
10023 if ( callback ) {
10024 callback = errorCallback = xhr.onload =
10025 xhr.onerror = xhr.onabort = xhr.ontimeout =
10026 xhr.onreadystatechange = null;
10027
10028 if ( type === "abort" ) {
10029 xhr.abort();
10030 } else if ( type === "error" ) {
10031
10032 // Support: IE <=9 only
10033 // On a manual native abort, IE9 throws
10034 // errors on any property access that is not readyState
10035 if ( typeof xhr.status !== "number" ) {
10036 complete( 0, "error" );
10037 } else {
10038 complete(
10039
10040 // File: protocol always yields status 0; see #8605, #14207
10041 xhr.status,
10042 xhr.statusText
10043 );
10044 }
10045 } else {
10046 complete(
10047 xhrSuccessStatus[ xhr.status ] || xhr.status,
10048 xhr.statusText,
10049
10050 // Support: IE <=9 only
10051 // IE9 has no XHR2 but throws on binary (trac-11426)
10052 // For XHR2 non-text, let the caller handle it (gh-2498)
10053 ( xhr.responseType || "text" ) !== "text" ||
10054 typeof xhr.responseText !== "string" ?
10055 { binary: xhr.response } :
10056 { text: xhr.responseText },
10057 xhr.getAllResponseHeaders()
10058 );
10059 }
10060 }
10061 };
10062 };
10063
10064 // Listen to events
10065 xhr.onload = callback();
10066 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
10067
10068 // Support: IE 9 only
10069 // Use onreadystatechange to replace onabort
10070 // to handle uncaught aborts
10071 if ( xhr.onabort !== undefined ) {
10072 xhr.onabort = errorCallback;
10073 } else {
10074 xhr.onreadystatechange = function() {
10075
10076 // Check readyState before timeout as it changes
10077 if ( xhr.readyState === 4 ) {
10078
10079 // Allow onerror to be called first,
10080 // but that will not handle a native abort
10081 // Also, save errorCallback to a variable
10082 // as xhr.onerror cannot be accessed
10083 window.setTimeout( function() {
10084 if ( callback ) {
10085 errorCallback();
10086 }
10087 } );
10088 }
10089 };
10090 }
10091
10092 // Create the abort callback
10093 callback = callback( "abort" );
10094
10095 try {
10096
10097 // Do send the request (this may raise an exception)
10098 xhr.send( options.hasContent && options.data || null );
10099 } catch ( e ) {
10100
10101 // #14683: Only rethrow if this hasn't been notified as an error yet
10102 if ( callback ) {
10103 throw e;
10104 }
10105 }
10106 },
10107
10108 abort: function() {
10109 if ( callback ) {
10110 callback();
10111 }
10112 }
10113 };
10114 }
10115 } );
10116
10117
10118
10119
10120 // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
10121 jQuery.ajaxPrefilter( function( s ) {
10122 if ( s.crossDomain ) {
10123 s.contents.script = false;
10124 }
10125 } );
10126
10127 // Install script dataType
10128 jQuery.ajaxSetup( {
10129 accepts: {
10130 script: "text/javascript, application/javascript, " +
10131 "application/ecmascript, application/x-ecmascript"
10132 },
10133 contents: {
10134 script: /\b(?:java|ecma)script\b/
10135 },
10136 converters: {
10137 "text script": function( text ) {
10138 jQuery.globalEval( text );
10139 return text;
10140 }
10141 }
10142 } );
10143
10144 // Handle cache's special case and crossDomain
10145 jQuery.ajaxPrefilter( "script", function( s ) {
10146 if ( s.cache === undefined ) {
10147 s.cache = false;
10148 }
10149 if ( s.crossDomain ) {
10150 s.type = "GET";
10151 }
10152 } );
10153
10154 // Bind script tag hack transport
10155 jQuery.ajaxTransport( "script", function( s ) {
10156
10157 // This transport only deals with cross domain or forced-by-attrs requests
10158 if ( s.crossDomain || s.scriptAttrs ) {
10159 var script, callback;
10160 return {
10161 send: function( _, complete ) {
10162 script = jQuery( "<script>" )
10163 .attr( s.scriptAttrs || {} )
10164 .prop( { charset: s.scriptCharset, src: s.url } )
10165 .on( "load error", callback = function( evt ) {
10166 script.remove();
10167 callback = null;
10168 if ( evt ) {
10169 complete( evt.type === "error" ? 404 : 200, evt.type );
10170 }
10171 } );
10172
10173 // Use native DOM manipulation to avoid our domManip AJAX trickery
10174 document.head.appendChild( script[ 0 ] );
10175 },
10176 abort: function() {
10177 if ( callback ) {
10178 callback();
10179 }
10180 }
10181 };
10182 }
10183 } );
10184
10185
10186
10187
10188 var oldCallbacks = [],
10189 rjsonp = /(=)\?(?=&|$)|\?\?/;
10190
10191 // Default jsonp settings
10192 jQuery.ajaxSetup( {
10193 jsonp: "callback",
10194 jsonpCallback: function() {
10195 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
10196 this[ callback ] = true;
10197 return callback;
10198 }
10199 } );
10200
10201 // Detect, normalize options and install callbacks for jsonp requests
10202 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10203
10204 var callbackName, overwritten, responseContainer,
10205 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10206 "url" :
10207 typeof s.data === "string" &&
10208 ( s.contentType || "" )
10209 .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10210 rjsonp.test( s.data ) && "data"
10211 );
10212
10213 // Handle iff the expected data type is "jsonp" or we have a parameter to set
10214 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10215
10216 // Get callback name, remembering preexisting value associated with it
10217 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
10218 s.jsonpCallback() :
10219 s.jsonpCallback;
10220
10221 // Insert callback into url or form data
10222 if ( jsonProp ) {
10223 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10224 } else if ( s.jsonp !== false ) {
10225 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10226 }
10227
10228 // Use data converter to retrieve json after script execution
10229 s.converters[ "script json" ] = function() {
10230 if ( !responseContainer ) {
10231 jQuery.error( callbackName + " was not called" );
10232 }
10233 return responseContainer[ 0 ];
10234 };
10235
10236 // Force json dataType
10237 s.dataTypes[ 0 ] = "json";
10238
10239 // Install callback
10240 overwritten = window[ callbackName ];
10241 window[ callbackName ] = function() {
10242 responseContainer = arguments;
10243 };
10244
10245 // Clean-up function (fires after converters)
10246 jqXHR.always( function() {
10247
10248 // If previous value didn't exist - remove it
10249 if ( overwritten === undefined ) {
10250 jQuery( window ).removeProp( callbackName );
10251
10252 // Otherwise restore preexisting value
10253 } else {
10254 window[ callbackName ] = overwritten;
10255 }
10256
10257 // Save back as free
10258 if ( s[ callbackName ] ) {
10259
10260 // Make sure that re-using the options doesn't screw things around
10261 s.jsonpCallback = originalSettings.jsonpCallback;
10262
10263 // Save the callback name for future use
10264 oldCallbacks.push( callbackName );
10265 }
10266
10267 // Call if it was a function and we have a response
10268 if ( responseContainer && isFunction( overwritten ) ) {
10269 overwritten( responseContainer[ 0 ] );
10270 }
10271
10272 responseContainer = overwritten = undefined;
10273 } );
10274
10275 // Delegate to script
10276 return "script";
10277 }
10278 } );
10279
10280
10281
10282
10283 // Support: Safari 8 only
10284 // In Safari 8 documents created via document.implementation.createHTMLDocument
10285 // collapse sibling forms: the second one becomes a child of the first one.
10286 // Because of that, this security measure has to be disabled in Safari 8.
10287 // https://bugs.webkit.org/show_bug.cgi?id=137337
10288 support.createHTMLDocument = ( function() {
10289 var body = document.implementation.createHTMLDocument( "" ).body;
10290 body.innerHTML = "<form></form><form></form>";
10291 return body.childNodes.length === 2;
10292 } )();
10293
10294
10295 // Argument "data" should be string of html
10296 // context (optional): If specified, the fragment will be created in this context,
10297 // defaults to document
10298 // keepScripts (optional): If true, will include scripts passed in the html string
10299 jQuery.parseHTML = function( data, context, keepScripts ) {
10300 if ( typeof data !== "string" ) {
10301 return [];
10302 }
10303 if ( typeof context === "boolean" ) {
10304 keepScripts = context;
10305 context = false;
10306 }
10307
10308 var base, parsed, scripts;
10309
10310 if ( !context ) {
10311
10312 // Stop scripts or inline event handlers from being executed immediately
10313 // by using document.implementation
10314 if ( support.createHTMLDocument ) {
10315 context = document.implementation.createHTMLDocument( "" );
10316
10317 // Set the base href for the created document
10318 // so any parsed elements with URLs
10319 // are based on the document's URL (gh-2965)
10320 base = context.createElement( "base" );
10321 base.href = document.location.href;
10322 context.head.appendChild( base );
10323 } else {
10324 context = document;
10325 }
10326 }
10327
10328 parsed = rsingleTag.exec( data );
10329 scripts = !keepScripts && [];
10330
10331 // Single tag
10332 if ( parsed ) {
10333 return [ context.createElement( parsed[ 1 ] ) ];
10334 }
10335
10336 parsed = buildFragment( [ data ], context, scripts );
10337
10338 if ( scripts && scripts.length ) {
10339 jQuery( scripts ).remove();
10340 }
10341
10342 return jQuery.merge( [], parsed.childNodes );
10343 };
10344
10345
10346 /**
10347 * Load a url into a page
10348 */
10349 jQuery.fn.load = function( url, params, callback ) {
10350 var selector, type, response,
10351 self = this,
10352 off = url.indexOf( " " );
10353
10354 if ( off > -1 ) {
10355 selector = stripAndCollapse( url.slice( off ) );
10356 url = url.slice( 0, off );
10357 }
10358
10359 // If it's a function
10360 if ( isFunction( params ) ) {
10361
10362 // We assume that it's the callback
10363 callback = params;
10364 params = undefined;
10365
10366 // Otherwise, build a param string
10367 } else if ( params && typeof params === "object" ) {
10368 type = "POST";
10369 }
10370
10371 // If we have elements to modify, make the request
10372 if ( self.length > 0 ) {
10373 jQuery.ajax( {
10374 url: url,
10375
10376 // If "type" variable is undefined, then "GET" method will be used.
10377 // Make value of this field explicit since
10378 // user can override it through ajaxSetup method
10379 type: type || "GET",
10380 dataType: "html",
10381 data: params
10382 } ).done( function( responseText ) {
10383
10384 // Save response for use in complete callback
10385 response = arguments;
10386
10387 self.html( selector ?
10388
10389 // If a selector was specified, locate the right elements in a dummy div
10390 // Exclude scripts to avoid IE 'Permission Denied' errors
10391 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10392
10393 // Otherwise use the full result
10394 responseText );
10395
10396 // If the request succeeds, this function gets "data", "status", "jqXHR"
10397 // but they are ignored because response was set above.
10398 // If it fails, this function gets "jqXHR", "status", "error"
10399 } ).always( callback && function( jqXHR, status ) {
10400 self.each( function() {
10401 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10402 } );
10403 } );
10404 }
10405
10406 return this;
10407 };
10408
10409
10410
10411
10412 jQuery.expr.pseudos.animated = function( elem ) {
10413 return jQuery.grep( jQuery.timers, function( fn ) {
10414 return elem === fn.elem;
10415 } ).length;
10416 };
10417
10418
10419
10420
10421 jQuery.offset = {
10422 setOffset: function( elem, options, i ) {
10423 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10424 position = jQuery.css( elem, "position" ),
10425 curElem = jQuery( elem ),
10426 props = {};
10427
10428 // Set position first, in-case top/left are set even on static elem
10429 if ( position === "static" ) {
10430 elem.style.position = "relative";
10431 }
10432
10433 curOffset = curElem.offset();
10434 curCSSTop = jQuery.css( elem, "top" );
10435 curCSSLeft = jQuery.css( elem, "left" );
10436 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10437 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
10438
10439 // Need to be able to calculate position if either
10440 // top or left is auto and position is either absolute or fixed
10441 if ( calculatePosition ) {
10442 curPosition = curElem.position();
10443 curTop = curPosition.top;
10444 curLeft = curPosition.left;
10445
10446 } else {
10447 curTop = parseFloat( curCSSTop ) || 0;
10448 curLeft = parseFloat( curCSSLeft ) || 0;
10449 }
10450
10451 if ( isFunction( options ) ) {
10452
10453 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10454 options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10455 }
10456
10457 if ( options.top != null ) {
10458 props.top = ( options.top - curOffset.top ) + curTop;
10459 }
10460 if ( options.left != null ) {
10461 props.left = ( options.left - curOffset.left ) + curLeft;
10462 }
10463
10464 if ( "using" in options ) {
10465 options.using.call( elem, props );
10466
10467 } else {
10468 if ( typeof props.top === "number" ) {
10469 props.top += "px";
10470 }
10471 if ( typeof props.left === "number" ) {
10472 props.left += "px";
10473 }
10474 curElem.css( props );
10475 }
10476 }
10477 };
10478
10479 jQuery.fn.extend( {
10480
10481 // offset() relates an element's border box to the document origin
10482 offset: function( options ) {
10483
10484 // Preserve chaining for setter
10485 if ( arguments.length ) {
10486 return options === undefined ?
10487 this :
10488 this.each( function( i ) {
10489 jQuery.offset.setOffset( this, options, i );
10490 } );
10491 }
10492
10493 var rect, win,
10494 elem = this[ 0 ];
10495
10496 if ( !elem ) {
10497 return;
10498 }
10499
10500 // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
10501 // Support: IE <=11 only
10502 // Running getBoundingClientRect on a
10503 // disconnected node in IE throws an error
10504 if ( !elem.getClientRects().length ) {
10505 return { top: 0, left: 0 };
10506 }
10507
10508 // Get document-relative position by adding viewport scroll to viewport-relative gBCR
10509 rect = elem.getBoundingClientRect();
10510 win = elem.ownerDocument.defaultView;
10511 return {
10512 top: rect.top + win.pageYOffset,
10513 left: rect.left + win.pageXOffset
10514 };
10515 },
10516
10517 // position() relates an element's margin box to its offset parent's padding box
10518 // This corresponds to the behavior of CSS absolute positioning
10519 position: function() {
10520 if ( !this[ 0 ] ) {
10521 return;
10522 }
10523
10524 var offsetParent, offset, doc,
10525 elem = this[ 0 ],
10526 parentOffset = { top: 0, left: 0 };
10527
10528 // position:fixed elements are offset from the viewport, which itself always has zero offset
10529 if ( jQuery.css( elem, "position" ) === "fixed" ) {
10530
10531 // Assume position:fixed implies availability of getBoundingClientRect
10532 offset = elem.getBoundingClientRect();
10533
10534 } else {
10535 offset = this.offset();
10536
10537 // Account for the *real* offset parent, which can be the document or its root element
10538 // when a statically positioned element is identified
10539 doc = elem.ownerDocument;
10540 offsetParent = elem.offsetParent || doc.documentElement;
10541 while ( offsetParent &&
10542 ( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
10543 jQuery.css( offsetParent, "position" ) === "static" ) {
10544
10545 offsetParent = offsetParent.parentNode;
10546 }
10547 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
10548
10549 // Incorporate borders into its offset, since they are outside its content origin
10550 parentOffset = jQuery( offsetParent ).offset();
10551 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
10552 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
10553 }
10554 }
10555
10556 // Subtract parent offsets and element margins
10557 return {
10558 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10559 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10560 };
10561 },
10562
10563 // This method will return documentElement in the following cases:
10564 // 1) For the element inside the iframe without offsetParent, this method will return
10565 // documentElement of the parent window
10566 // 2) For the hidden or detached element
10567 // 3) For body or html element, i.e. in case of the html node - it will return itself
10568 //
10569 // but those exceptions were never presented as a real life use-cases
10570 // and might be considered as more preferable results.
10571 //
10572 // This logic, however, is not guaranteed and can change at any point in the future
10573 offsetParent: function() {
10574 return this.map( function() {
10575 var offsetParent = this.offsetParent;
10576
10577 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
10578 offsetParent = offsetParent.offsetParent;
10579 }
10580
10581 return offsetParent || documentElement;
10582 } );
10583 }
10584 } );
10585
10586 // Create scrollLeft and scrollTop methods
10587 jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10588 var top = "pageYOffset" === prop;
10589
10590 jQuery.fn[ method ] = function( val ) {
10591 return access( this, function( elem, method, val ) {
10592
10593 // Coalesce documents and windows
10594 var win;
10595 if ( isWindow( elem ) ) {
10596 win = elem;
10597 } else if ( elem.nodeType === 9 ) {
10598 win = elem.defaultView;
10599 }
10600
10601 if ( val === undefined ) {
10602 return win ? win[ prop ] : elem[ method ];
10603 }
10604
10605 if ( win ) {
10606 win.scrollTo(
10607 !top ? val : win.pageXOffset,
10608 top ? val : win.pageYOffset
10609 );
10610
10611 } else {
10612 elem[ method ] = val;
10613 }
10614 }, method, val, arguments.length );
10615 };
10616 } );
10617
10618 // Support: Safari <=7 - 9.1, Chrome <=37 - 49
10619 // Add the top/left cssHooks using jQuery.fn.position
10620 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10621 // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10622 // getComputedStyle returns percent when specified for top/left/bottom/right;
10623 // rather than make the css module depend on the offset module, just check for it here
10624 jQuery.each( [ "top", "left" ], function( _i, prop ) {
10625 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10626 function( elem, computed ) {
10627 if ( computed ) {
10628 computed = curCSS( elem, prop );
10629
10630 // If curCSS returns percentage, fallback to offset
10631 return rnumnonpx.test( computed ) ?
10632 jQuery( elem ).position()[ prop ] + "px" :
10633 computed;
10634 }
10635 }
10636 );
10637 } );
10638
10639
10640 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10641 jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10642 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10643 function( defaultExtra, funcName ) {
10644
10645 // Margin is only for outerHeight, outerWidth
10646 jQuery.fn[ funcName ] = function( margin, value ) {
10647 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10648 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10649
10650 return access( this, function( elem, type, value ) {
10651 var doc;
10652
10653 if ( isWindow( elem ) ) {
10654
10655 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10656 return funcName.indexOf( "outer" ) === 0 ?
10657 elem[ "inner" + name ] :
10658 elem.document.documentElement[ "client" + name ];
10659 }
10660
10661 // Get document width or height
10662 if ( elem.nodeType === 9 ) {
10663 doc = elem.documentElement;
10664
10665 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10666 // whichever is greatest
10667 return Math.max(
10668 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10669 elem.body[ "offset" + name ], doc[ "offset" + name ],
10670 doc[ "client" + name ]
10671 );
10672 }
10673
10674 return value === undefined ?
10675
10676 // Get width or height on the element, requesting but not forcing parseFloat
10677 jQuery.css( elem, type, extra ) :
10678
10679 // Set width or height on the element
10680 jQuery.style( elem, type, value, extra );
10681 }, type, chainable ? margin : undefined, chainable );
10682 };
10683 } );
10684 } );
10685
10686
10687 jQuery.each( [
10688 "ajaxStart",
10689 "ajaxStop",
10690 "ajaxComplete",
10691 "ajaxError",
10692 "ajaxSuccess",
10693 "ajaxSend"
10694 ], function( _i, type ) {
10695 jQuery.fn[ type ] = function( fn ) {
10696 return this.on( type, fn );
10697 };
10698 } );
10699
10700
10701
10702
10703 jQuery.fn.extend( {
10704
10705 bind: function( types, data, fn ) {
10706 return this.on( types, null, data, fn );
10707 },
10708 unbind: function( types, fn ) {
10709 return this.off( types, null, fn );
10710 },
10711
10712 delegate: function( selector, types, data, fn ) {
10713 return this.on( types, selector, data, fn );
10714 },
10715 undelegate: function( selector, types, fn ) {
10716
10717 // ( namespace ) or ( selector, types [, fn] )
10718 return arguments.length === 1 ?
10719 this.off( selector, "**" ) :
10720 this.off( types, selector || "**", fn );
10721 },
10722
10723 hover: function( fnOver, fnOut ) {
10724 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
10725 }
10726 } );
10727
10728 jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
10729 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
10730 "change select submit keydown keypress keyup contextmenu" ).split( " " ),
10731 function( _i, name ) {
10732
10733 // Handle event binding
10734 jQuery.fn[ name ] = function( data, fn ) {
10735 return arguments.length > 0 ?
10736 this.on( name, null, data, fn ) :
10737 this.trigger( name );
10738 };
10739 } );
10740
10741
10742
10743
10744 // Support: Android <=4.0 only
10745 // Make sure we trim BOM and NBSP
10746 var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
10747
10748 // Bind a function to a context, optionally partially applying any
10749 // arguments.
10750 // jQuery.proxy is deprecated to promote standards (specifically Function#bind)
10751 // However, it is not slated for removal any time soon
10752 jQuery.proxy = function( fn, context ) {
10753 var tmp, args, proxy;
10754
10755 if ( typeof context === "string" ) {
10756 tmp = fn[ context ];
10757 context = fn;
10758 fn = tmp;
10759 }
10760
10761 // Quick check to determine if target is callable, in the spec
10762 // this throws a TypeError, but we will just return undefined.
10763 if ( !isFunction( fn ) ) {
10764 return undefined;
10765 }
10766
10767 // Simulated bind
10768 args = slice.call( arguments, 2 );
10769 proxy = function() {
10770 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
10771 };
10772
10773 // Set the guid of unique handler to the same of original handler, so it can be removed
10774 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
10775
10776 return proxy;
10777 };
10778
10779 jQuery.holdReady = function( hold ) {
10780 if ( hold ) {
10781 jQuery.readyWait++;
10782 } else {
10783 jQuery.ready( true );
10784 }
10785 };
10786 jQuery.isArray = Array.isArray;
10787 jQuery.parseJSON = JSON.parse;
10788 jQuery.nodeName = nodeName;
10789 jQuery.isFunction = isFunction;
10790 jQuery.isWindow = isWindow;
10791 jQuery.camelCase = camelCase;
10792 jQuery.type = toType;
10793
10794 jQuery.now = Date.now;
10795
10796 jQuery.isNumeric = function( obj ) {
10797
10798 // As of jQuery 3.0, isNumeric is limited to
10799 // strings and numbers (primitives or objects)
10800 // that can be coerced to finite numbers (gh-2662)
10801 var type = jQuery.type( obj );
10802 return ( type === "number" || type === "string" ) &&
10803
10804 // parseFloat NaNs numeric-cast false positives ("")
10805 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
10806 // subtraction forces infinities to NaN
10807 !isNaN( obj - parseFloat( obj ) );
10808 };
10809
10810 jQuery.trim = function( text ) {
10811 return text == null ?
10812 "" :
10813 ( text + "" ).replace( rtrim, "" );
10814 };
10815
10816
10817
10818 // Register as a named AMD module, since jQuery can be concatenated with other
10819 // files that may use define, but not via a proper concatenation script that
10820 // understands anonymous AMD modules. A named AMD is safest and most robust
10821 // way to register. Lowercase jquery is used because AMD module names are
10822 // derived from file names, and jQuery is normally delivered in a lowercase
10823 // file name. Do this after creating the global so that if an AMD module wants
10824 // to call noConflict to hide this version of jQuery, it will work.
10825
10826 // Note that for maximum portability, libraries that are not jQuery should
10827 // declare themselves as anonymous modules, and avoid setting a global if an
10828 // AMD loader is present. jQuery is a special case. For more information, see
10829 // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10830
10831 if ( typeof define === "function" && define.amd ) {
10832 define( "jquery", [], function() {
10833 return jQuery;
10834 } );
10835 }
10836
10837
10838
10839
10840 var
10841
10842 // Map over jQuery in case of overwrite
10843 _jQuery = window.jQuery,
10844
10845 // Map over the $ in case of overwrite
10846 _$ = window.$;
10847
10848 jQuery.noConflict = function( deep ) {
10849 if ( window.$ === jQuery ) {
10850 window.$ = _$;
10851 }
10852
10853 if ( deep && window.jQuery === jQuery ) {
10854 window.jQuery = _jQuery;
10855 }
10856
10857 return jQuery;
10858 };
10859
10860 // Expose jQuery and $ identifiers, even in AMD
10861 // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10862 // and CommonJS for browser emulators (#13566)
10863 if ( typeof noGlobal === "undefined" ) {
10864 window.jQuery = window.$ = jQuery;
10865 }
10866
10867
10868
10869
10870 return jQuery;
10871 } );
0 /*!
1 * jQuery JavaScript Library v3.6.0
2 * https://jquery.com/
3 *
4 * Includes Sizzle.js
5 * https://sizzlejs.com/
6 *
7 * Copyright OpenJS Foundation and other contributors
8 * Released under the MIT license
9 * https://jquery.org/license
10 *
11 * Date: 2021-03-02T17:08Z
12 */
13 ( function( global, factory ) {
14
15 "use strict";
16
17 if ( typeof module === "object" && typeof module.exports === "object" ) {
18
19 // For CommonJS and CommonJS-like environments where a proper `window`
20 // is present, execute the factory and get jQuery.
21 // For environments that do not have a `window` with a `document`
22 // (such as Node.js), expose a factory as module.exports.
23 // This accentuates the need for the creation of a real `window`.
24 // e.g. var jQuery = require("jquery")(window);
25 // See ticket #14549 for more info.
26 module.exports = global.document ?
27 factory( global, true ) :
28 function( w ) {
29 if ( !w.document ) {
30 throw new Error( "jQuery requires a window with a document" );
31 }
32 return factory( w );
33 };
34 } else {
35 factory( global );
36 }
37
38 // Pass this if window is not defined yet
39 } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
40
41 // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
42 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
43 // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
44 // enough that all such attempts are guarded in a try block.
45 "use strict";
46
47 var arr = [];
48
49 var getProto = Object.getPrototypeOf;
50
51 var slice = arr.slice;
52
53 var flat = arr.flat ? function( array ) {
54 return arr.flat.call( array );
55 } : function( array ) {
56 return arr.concat.apply( [], array );
57 };
58
59
60 var push = arr.push;
61
62 var indexOf = arr.indexOf;
63
64 var class2type = {};
65
66 var toString = class2type.toString;
67
68 var hasOwn = class2type.hasOwnProperty;
69
70 var fnToString = hasOwn.toString;
71
72 var ObjectFunctionString = fnToString.call( Object );
73
74 var support = {};
75
76 var isFunction = function isFunction( obj ) {
77
78 // Support: Chrome <=57, Firefox <=52
79 // In some browsers, typeof returns "function" for HTML <object> elements
80 // (i.e., `typeof document.createElement( "object" ) === "function"`).
81 // We don't want to classify *any* DOM node as a function.
82 // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
83 // Plus for old WebKit, typeof returns "function" for HTML collections
84 // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
85 return typeof obj === "function" && typeof obj.nodeType !== "number" &&
86 typeof obj.item !== "function";
87 };
88
89
90 var isWindow = function isWindow( obj ) {
91 return obj != null && obj === obj.window;
92 };
93
94
95 var document = window.document;
96
97
98
99 var preservedScriptAttributes = {
100 type: true,
101 src: true,
102 nonce: true,
103 noModule: true
104 };
105
106 function DOMEval( code, node, doc ) {
107 doc = doc || document;
108
109 var i, val,
110 script = doc.createElement( "script" );
111
112 script.text = code;
113 if ( node ) {
114 for ( i in preservedScriptAttributes ) {
115
116 // Support: Firefox 64+, Edge 18+
117 // Some browsers don't support the "nonce" property on scripts.
118 // On the other hand, just using `getAttribute` is not enough as
119 // the `nonce` attribute is reset to an empty string whenever it
120 // becomes browsing-context connected.
121 // See https://github.com/whatwg/html/issues/2369
122 // See https://html.spec.whatwg.org/#nonce-attributes
123 // The `node.getAttribute` check was added for the sake of
124 // `jQuery.globalEval` so that it can fake a nonce-containing node
125 // via an object.
126 val = node[ i ] || node.getAttribute && node.getAttribute( i );
127 if ( val ) {
128 script.setAttribute( i, val );
129 }
130 }
131 }
132 doc.head.appendChild( script ).parentNode.removeChild( script );
133 }
134
135
136 function toType( obj ) {
137 if ( obj == null ) {
138 return obj + "";
139 }
140
141 // Support: Android <=2.3 only (functionish RegExp)
142 return typeof obj === "object" || typeof obj === "function" ?
143 class2type[ toString.call( obj ) ] || "object" :
144 typeof obj;
145 }
146 /* global Symbol */
147 // Defining this global in .eslintrc.json would create a danger of using the global
148 // unguarded in another place, it seems safer to define global only for this module
149
150
151
152 var
153 version = "3.6.0",
154
155 // Define a local copy of jQuery
156 jQuery = function( selector, context ) {
157
158 // The jQuery object is actually just the init constructor 'enhanced'
159 // Need init if jQuery is called (just allow error to be thrown if not included)
160 return new jQuery.fn.init( selector, context );
161 };
162
163 jQuery.fn = jQuery.prototype = {
164
165 // The current version of jQuery being used
166 jquery: version,
167
168 constructor: jQuery,
169
170 // The default length of a jQuery object is 0
171 length: 0,
172
173 toArray: function() {
174 return slice.call( this );
175 },
176
177 // Get the Nth element in the matched element set OR
178 // Get the whole matched element set as a clean array
179 get: function( num ) {
180
181 // Return all the elements in a clean array
182 if ( num == null ) {
183 return slice.call( this );
184 }
185
186 // Return just the one element from the set
187 return num < 0 ? this[ num + this.length ] : this[ num ];
188 },
189
190 // Take an array of elements and push it onto the stack
191 // (returning the new matched element set)
192 pushStack: function( elems ) {
193
194 // Build a new jQuery matched element set
195 var ret = jQuery.merge( this.constructor(), elems );
196
197 // Add the old object onto the stack (as a reference)
198 ret.prevObject = this;
199
200 // Return the newly-formed element set
201 return ret;
202 },
203
204 // Execute a callback for every element in the matched set.
205 each: function( callback ) {
206 return jQuery.each( this, callback );
207 },
208
209 map: function( callback ) {
210 return this.pushStack( jQuery.map( this, function( elem, i ) {
211 return callback.call( elem, i, elem );
212 } ) );
213 },
214
215 slice: function() {
216 return this.pushStack( slice.apply( this, arguments ) );
217 },
218
219 first: function() {
220 return this.eq( 0 );
221 },
222
223 last: function() {
224 return this.eq( -1 );
225 },
226
227 even: function() {
228 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
229 return ( i + 1 ) % 2;
230 } ) );
231 },
232
233 odd: function() {
234 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
235 return i % 2;
236 } ) );
237 },
238
239 eq: function( i ) {
240 var len = this.length,
241 j = +i + ( i < 0 ? len : 0 );
242 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
243 },
244
245 end: function() {
246 return this.prevObject || this.constructor();
247 },
248
249 // For internal use only.
250 // Behaves like an Array's method, not like a jQuery method.
251 push: push,
252 sort: arr.sort,
253 splice: arr.splice
254 };
255
256 jQuery.extend = jQuery.fn.extend = function() {
257 var options, name, src, copy, copyIsArray, clone,
258 target = arguments[ 0 ] || {},
259 i = 1,
260 length = arguments.length,
261 deep = false;
262
263 // Handle a deep copy situation
264 if ( typeof target === "boolean" ) {
265 deep = target;
266
267 // Skip the boolean and the target
268 target = arguments[ i ] || {};
269 i++;
270 }
271
272 // Handle case when target is a string or something (possible in deep copy)
273 if ( typeof target !== "object" && !isFunction( target ) ) {
274 target = {};
275 }
276
277 // Extend jQuery itself if only one argument is passed
278 if ( i === length ) {
279 target = this;
280 i--;
281 }
282
283 for ( ; i < length; i++ ) {
284
285 // Only deal with non-null/undefined values
286 if ( ( options = arguments[ i ] ) != null ) {
287
288 // Extend the base object
289 for ( name in options ) {
290 copy = options[ name ];
291
292 // Prevent Object.prototype pollution
293 // Prevent never-ending loop
294 if ( name === "__proto__" || target === copy ) {
295 continue;
296 }
297
298 // Recurse if we're merging plain objects or arrays
299 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
300 ( copyIsArray = Array.isArray( copy ) ) ) ) {
301 src = target[ name ];
302
303 // Ensure proper type for the source value
304 if ( copyIsArray && !Array.isArray( src ) ) {
305 clone = [];
306 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
307 clone = {};
308 } else {
309 clone = src;
310 }
311 copyIsArray = false;
312
313 // Never move original objects, clone them
314 target[ name ] = jQuery.extend( deep, clone, copy );
315
316 // Don't bring in undefined values
317 } else if ( copy !== undefined ) {
318 target[ name ] = copy;
319 }
320 }
321 }
322 }
323
324 // Return the modified object
325 return target;
326 };
327
328 jQuery.extend( {
329
330 // Unique for each copy of jQuery on the page
331 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
332
333 // Assume jQuery is ready without the ready module
334 isReady: true,
335
336 error: function( msg ) {
337 throw new Error( msg );
338 },
339
340 noop: function() {},
341
342 isPlainObject: function( obj ) {
343 var proto, Ctor;
344
345 // Detect obvious negatives
346 // Use toString instead of jQuery.type to catch host objects
347 if ( !obj || toString.call( obj ) !== "[object Object]" ) {
348 return false;
349 }
350
351 proto = getProto( obj );
352
353 // Objects with no prototype (e.g., `Object.create( null )`) are plain
354 if ( !proto ) {
355 return true;
356 }
357
358 // Objects with prototype are plain iff they were constructed by a global Object function
359 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
360 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
361 },
362
363 isEmptyObject: function( obj ) {
364 var name;
365
366 for ( name in obj ) {
367 return false;
368 }
369 return true;
370 },
371
372 // Evaluates a script in a provided context; falls back to the global one
373 // if not specified.
374 globalEval: function( code, options, doc ) {
375 DOMEval( code, { nonce: options && options.nonce }, doc );
376 },
377
378 each: function( obj, callback ) {
379 var length, i = 0;
380
381 if ( isArrayLike( obj ) ) {
382 length = obj.length;
383 for ( ; i < length; i++ ) {
384 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
385 break;
386 }
387 }
388 } else {
389 for ( i in obj ) {
390 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
391 break;
392 }
393 }
394 }
395
396 return obj;
397 },
398
399 // results is for internal usage only
400 makeArray: function( arr, results ) {
401 var ret = results || [];
402
403 if ( arr != null ) {
404 if ( isArrayLike( Object( arr ) ) ) {
405 jQuery.merge( ret,
406 typeof arr === "string" ?
407 [ arr ] : arr
408 );
409 } else {
410 push.call( ret, arr );
411 }
412 }
413
414 return ret;
415 },
416
417 inArray: function( elem, arr, i ) {
418 return arr == null ? -1 : indexOf.call( arr, elem, i );
419 },
420
421 // Support: Android <=4.0 only, PhantomJS 1 only
422 // push.apply(_, arraylike) throws on ancient WebKit
423 merge: function( first, second ) {
424 var len = +second.length,
425 j = 0,
426 i = first.length;
427
428 for ( ; j < len; j++ ) {
429 first[ i++ ] = second[ j ];
430 }
431
432 first.length = i;
433
434 return first;
435 },
436
437 grep: function( elems, callback, invert ) {
438 var callbackInverse,
439 matches = [],
440 i = 0,
441 length = elems.length,
442 callbackExpect = !invert;
443
444 // Go through the array, only saving the items
445 // that pass the validator function
446 for ( ; i < length; i++ ) {
447 callbackInverse = !callback( elems[ i ], i );
448 if ( callbackInverse !== callbackExpect ) {
449 matches.push( elems[ i ] );
450 }
451 }
452
453 return matches;
454 },
455
456 // arg is for internal usage only
457 map: function( elems, callback, arg ) {
458 var length, value,
459 i = 0,
460 ret = [];
461
462 // Go through the array, translating each of the items to their new values
463 if ( isArrayLike( elems ) ) {
464 length = elems.length;
465 for ( ; i < length; i++ ) {
466 value = callback( elems[ i ], i, arg );
467
468 if ( value != null ) {
469 ret.push( value );
470 }
471 }
472
473 // Go through every key on the object,
474 } else {
475 for ( i in elems ) {
476 value = callback( elems[ i ], i, arg );
477
478 if ( value != null ) {
479 ret.push( value );
480 }
481 }
482 }
483
484 // Flatten any nested arrays
485 return flat( ret );
486 },
487
488 // A global GUID counter for objects
489 guid: 1,
490
491 // jQuery.support is not used in Core but other projects attach their
492 // properties to it so it needs to exist.
493 support: support
494 } );
495
496 if ( typeof Symbol === "function" ) {
497 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
498 }
499
500 // Populate the class2type map
501 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
502 function( _i, name ) {
503 class2type[ "[object " + name + "]" ] = name.toLowerCase();
504 } );
505
506 function isArrayLike( obj ) {
507
508 // Support: real iOS 8.2 only (not reproducible in simulator)
509 // `in` check used to prevent JIT error (gh-2145)
510 // hasOwn isn't used here due to false negatives
511 // regarding Nodelist length in IE
512 var length = !!obj && "length" in obj && obj.length,
513 type = toType( obj );
514
515 if ( isFunction( obj ) || isWindow( obj ) ) {
516 return false;
517 }
518
519 return type === "array" || length === 0 ||
520 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
521 }
522 var Sizzle =
523 /*!
524 * Sizzle CSS Selector Engine v2.3.6
525 * https://sizzlejs.com/
526 *
527 * Copyright JS Foundation and other contributors
528 * Released under the MIT license
529 * https://js.foundation/
530 *
531 * Date: 2021-02-16
532 */
533 ( function( window ) {
534 var i,
535 support,
536 Expr,
537 getText,
538 isXML,
539 tokenize,
540 compile,
541 select,
542 outermostContext,
543 sortInput,
544 hasDuplicate,
545
546 // Local document vars
547 setDocument,
548 document,
549 docElem,
550 documentIsHTML,
551 rbuggyQSA,
552 rbuggyMatches,
553 matches,
554 contains,
555
556 // Instance-specific data
557 expando = "sizzle" + 1 * new Date(),
558 preferredDoc = window.document,
559 dirruns = 0,
560 done = 0,
561 classCache = createCache(),
562 tokenCache = createCache(),
563 compilerCache = createCache(),
564 nonnativeSelectorCache = createCache(),
565 sortOrder = function( a, b ) {
566 if ( a === b ) {
567 hasDuplicate = true;
568 }
569 return 0;
570 },
571
572 // Instance methods
573 hasOwn = ( {} ).hasOwnProperty,
574 arr = [],
575 pop = arr.pop,
576 pushNative = arr.push,
577 push = arr.push,
578 slice = arr.slice,
579
580 // Use a stripped-down indexOf as it's faster than native
581 // https://jsperf.com/thor-indexof-vs-for/5
582 indexOf = function( list, elem ) {
583 var i = 0,
584 len = list.length;
585 for ( ; i < len; i++ ) {
586 if ( list[ i ] === elem ) {
587 return i;
588 }
589 }
590 return -1;
591 },
592
593 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
594 "ismap|loop|multiple|open|readonly|required|scoped",
595
596 // Regular expressions
597
598 // http://www.w3.org/TR/css3-selectors/#whitespace
599 whitespace = "[\\x20\\t\\r\\n\\f]",
600
601 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
602 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
603 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
604
605 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
606 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
607
608 // Operator (capture 2)
609 "*([*^$|!~]?=)" + whitespace +
610
611 // "Attribute values must be CSS identifiers [capture 5]
612 // or strings [capture 3 or capture 4]"
613 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
614 whitespace + "*\\]",
615
616 pseudos = ":(" + identifier + ")(?:\\((" +
617
618 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
619 // 1. quoted (capture 3; capture 4 or capture 5)
620 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
621
622 // 2. simple (capture 6)
623 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
624
625 // 3. anything else (capture 2)
626 ".*" +
627 ")\\)|)",
628
629 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
630 rwhitespace = new RegExp( whitespace + "+", "g" ),
631 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
632 whitespace + "+$", "g" ),
633
634 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
635 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
636 "*" ),
637 rdescend = new RegExp( whitespace + "|>" ),
638
639 rpseudo = new RegExp( pseudos ),
640 ridentifier = new RegExp( "^" + identifier + "$" ),
641
642 matchExpr = {
643 "ID": new RegExp( "^#(" + identifier + ")" ),
644 "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
645 "TAG": new RegExp( "^(" + identifier + "|[*])" ),
646 "ATTR": new RegExp( "^" + attributes ),
647 "PSEUDO": new RegExp( "^" + pseudos ),
648 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
649 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
650 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
651 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
652
653 // For use in libraries implementing .is()
654 // We use this for POS matching in `select`
655 "needsContext": new RegExp( "^" + whitespace +
656 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
657 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
658 },
659
660 rhtml = /HTML$/i,
661 rinputs = /^(?:input|select|textarea|button)$/i,
662 rheader = /^h\d$/i,
663
664 rnative = /^[^{]+\{\s*\[native \w/,
665
666 // Easily-parseable/retrievable ID or TAG or CLASS selectors
667 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
668
669 rsibling = /[+~]/,
670
671 // CSS escapes
672 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
673 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
674 funescape = function( escape, nonHex ) {
675 var high = "0x" + escape.slice( 1 ) - 0x10000;
676
677 return nonHex ?
678
679 // Strip the backslash prefix from a non-hex escape sequence
680 nonHex :
681
682 // Replace a hexadecimal escape sequence with the encoded Unicode code point
683 // Support: IE <=11+
684 // For values outside the Basic Multilingual Plane (BMP), manually construct a
685 // surrogate pair
686 high < 0 ?
687 String.fromCharCode( high + 0x10000 ) :
688 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
689 },
690
691 // CSS string/identifier serialization
692 // https://drafts.csswg.org/cssom/#common-serializing-idioms
693 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
694 fcssescape = function( ch, asCodePoint ) {
695 if ( asCodePoint ) {
696
697 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
698 if ( ch === "\0" ) {
699 return "\uFFFD";
700 }
701
702 // Control characters and (dependent upon position) numbers get escaped as code points
703 return ch.slice( 0, -1 ) + "\\" +
704 ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
705 }
706
707 // Other potentially-special ASCII characters get backslash-escaped
708 return "\\" + ch;
709 },
710
711 // Used for iframes
712 // See setDocument()
713 // Removing the function wrapper causes a "Permission Denied"
714 // error in IE
715 unloadHandler = function() {
716 setDocument();
717 },
718
719 inDisabledFieldset = addCombinator(
720 function( elem ) {
721 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
722 },
723 { dir: "parentNode", next: "legend" }
724 );
725
726 // Optimize for push.apply( _, NodeList )
727 try {
728 push.apply(
729 ( arr = slice.call( preferredDoc.childNodes ) ),
730 preferredDoc.childNodes
731 );
732
733 // Support: Android<4.0
734 // Detect silently failing push.apply
735 // eslint-disable-next-line no-unused-expressions
736 arr[ preferredDoc.childNodes.length ].nodeType;
737 } catch ( e ) {
738 push = { apply: arr.length ?
739
740 // Leverage slice if possible
741 function( target, els ) {
742 pushNative.apply( target, slice.call( els ) );
743 } :
744
745 // Support: IE<9
746 // Otherwise append directly
747 function( target, els ) {
748 var j = target.length,
749 i = 0;
750
751 // Can't trust NodeList.length
752 while ( ( target[ j++ ] = els[ i++ ] ) ) {}
753 target.length = j - 1;
754 }
755 };
756 }
757
758 function Sizzle( selector, context, results, seed ) {
759 var m, i, elem, nid, match, groups, newSelector,
760 newContext = context && context.ownerDocument,
761
762 // nodeType defaults to 9, since context defaults to document
763 nodeType = context ? context.nodeType : 9;
764
765 results = results || [];
766
767 // Return early from calls with invalid selector or context
768 if ( typeof selector !== "string" || !selector ||
769 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
770
771 return results;
772 }
773
774 // Try to shortcut find operations (as opposed to filters) in HTML documents
775 if ( !seed ) {
776 setDocument( context );
777 context = context || document;
778
779 if ( documentIsHTML ) {
780
781 // If the selector is sufficiently simple, try using a "get*By*" DOM method
782 // (excepting DocumentFragment context, where the methods don't exist)
783 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
784
785 // ID selector
786 if ( ( m = match[ 1 ] ) ) {
787
788 // Document context
789 if ( nodeType === 9 ) {
790 if ( ( elem = context.getElementById( m ) ) ) {
791
792 // Support: IE, Opera, Webkit
793 // TODO: identify versions
794 // getElementById can match elements by name instead of ID
795 if ( elem.id === m ) {
796 results.push( elem );
797 return results;
798 }
799 } else {
800 return results;
801 }
802
803 // Element context
804 } else {
805
806 // Support: IE, Opera, Webkit
807 // TODO: identify versions
808 // getElementById can match elements by name instead of ID
809 if ( newContext && ( elem = newContext.getElementById( m ) ) &&
810 contains( context, elem ) &&
811 elem.id === m ) {
812
813 results.push( elem );
814 return results;
815 }
816 }
817
818 // Type selector
819 } else if ( match[ 2 ] ) {
820 push.apply( results, context.getElementsByTagName( selector ) );
821 return results;
822
823 // Class selector
824 } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
825 context.getElementsByClassName ) {
826
827 push.apply( results, context.getElementsByClassName( m ) );
828 return results;
829 }
830 }
831
832 // Take advantage of querySelectorAll
833 if ( support.qsa &&
834 !nonnativeSelectorCache[ selector + " " ] &&
835 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
836
837 // Support: IE 8 only
838 // Exclude object elements
839 ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
840
841 newSelector = selector;
842 newContext = context;
843
844 // qSA considers elements outside a scoping root when evaluating child or
845 // descendant combinators, which is not what we want.
846 // In such cases, we work around the behavior by prefixing every selector in the
847 // list with an ID selector referencing the scope context.
848 // The technique has to be used as well when a leading combinator is used
849 // as such selectors are not recognized by querySelectorAll.
850 // Thanks to Andrew Dupont for this technique.
851 if ( nodeType === 1 &&
852 ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
853
854 // Expand context for sibling selectors
855 newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
856 context;
857
858 // We can use :scope instead of the ID hack if the browser
859 // supports it & if we're not changing the context.
860 if ( newContext !== context || !support.scope ) {
861
862 // Capture the context ID, setting it first if necessary
863 if ( ( nid = context.getAttribute( "id" ) ) ) {
864 nid = nid.replace( rcssescape, fcssescape );
865 } else {
866 context.setAttribute( "id", ( nid = expando ) );
867 }
868 }
869
870 // Prefix every selector in the list
871 groups = tokenize( selector );
872 i = groups.length;
873 while ( i-- ) {
874 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
875 toSelector( groups[ i ] );
876 }
877 newSelector = groups.join( "," );
878 }
879
880 try {
881 push.apply( results,
882 newContext.querySelectorAll( newSelector )
883 );
884 return results;
885 } catch ( qsaError ) {
886 nonnativeSelectorCache( selector, true );
887 } finally {
888 if ( nid === expando ) {
889 context.removeAttribute( "id" );
890 }
891 }
892 }
893 }
894 }
895
896 // All others
897 return select( selector.replace( rtrim, "$1" ), context, results, seed );
898 }
899
900 /**
901 * Create key-value caches of limited size
902 * @returns {function(string, object)} Returns the Object data after storing it on itself with
903 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
904 * deleting the oldest entry
905 */
906 function createCache() {
907 var keys = [];
908
909 function cache( key, value ) {
910
911 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
912 if ( keys.push( key + " " ) > Expr.cacheLength ) {
913
914 // Only keep the most recent entries
915 delete cache[ keys.shift() ];
916 }
917 return ( cache[ key + " " ] = value );
918 }
919 return cache;
920 }
921
922 /**
923 * Mark a function for special use by Sizzle
924 * @param {Function} fn The function to mark
925 */
926 function markFunction( fn ) {
927 fn[ expando ] = true;
928 return fn;
929 }
930
931 /**
932 * Support testing using an element
933 * @param {Function} fn Passed the created element and returns a boolean result
934 */
935 function assert( fn ) {
936 var el = document.createElement( "fieldset" );
937
938 try {
939 return !!fn( el );
940 } catch ( e ) {
941 return false;
942 } finally {
943
944 // Remove from its parent by default
945 if ( el.parentNode ) {
946 el.parentNode.removeChild( el );
947 }
948
949 // release memory in IE
950 el = null;
951 }
952 }
953
954 /**
955 * Adds the same handler for all of the specified attrs
956 * @param {String} attrs Pipe-separated list of attributes
957 * @param {Function} handler The method that will be applied
958 */
959 function addHandle( attrs, handler ) {
960 var arr = attrs.split( "|" ),
961 i = arr.length;
962
963 while ( i-- ) {
964 Expr.attrHandle[ arr[ i ] ] = handler;
965 }
966 }
967
968 /**
969 * Checks document order of two siblings
970 * @param {Element} a
971 * @param {Element} b
972 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
973 */
974 function siblingCheck( a, b ) {
975 var cur = b && a,
976 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
977 a.sourceIndex - b.sourceIndex;
978
979 // Use IE sourceIndex if available on both nodes
980 if ( diff ) {
981 return diff;
982 }
983
984 // Check if b follows a
985 if ( cur ) {
986 while ( ( cur = cur.nextSibling ) ) {
987 if ( cur === b ) {
988 return -1;
989 }
990 }
991 }
992
993 return a ? 1 : -1;
994 }
995
996 /**
997 * Returns a function to use in pseudos for input types
998 * @param {String} type
999 */
1000 function createInputPseudo( type ) {
1001 return function( elem ) {
1002 var name = elem.nodeName.toLowerCase();
1003 return name === "input" && elem.type === type;
1004 };
1005 }
1006
1007 /**
1008 * Returns a function to use in pseudos for buttons
1009 * @param {String} type
1010 */
1011 function createButtonPseudo( type ) {
1012 return function( elem ) {
1013 var name = elem.nodeName.toLowerCase();
1014 return ( name === "input" || name === "button" ) && elem.type === type;
1015 };
1016 }
1017
1018 /**
1019 * Returns a function to use in pseudos for :enabled/:disabled
1020 * @param {Boolean} disabled true for :disabled; false for :enabled
1021 */
1022 function createDisabledPseudo( disabled ) {
1023
1024 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1025 return function( elem ) {
1026
1027 // Only certain elements can match :enabled or :disabled
1028 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1029 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1030 if ( "form" in elem ) {
1031
1032 // Check for inherited disabledness on relevant non-disabled elements:
1033 // * listed form-associated elements in a disabled fieldset
1034 // https://html.spec.whatwg.org/multipage/forms.html#category-listed
1035 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1036 // * option elements in a disabled optgroup
1037 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1038 // All such elements have a "form" property.
1039 if ( elem.parentNode && elem.disabled === false ) {
1040
1041 // Option elements defer to a parent optgroup if present
1042 if ( "label" in elem ) {
1043 if ( "label" in elem.parentNode ) {
1044 return elem.parentNode.disabled === disabled;
1045 } else {
1046 return elem.disabled === disabled;
1047 }
1048 }
1049
1050 // Support: IE 6 - 11
1051 // Use the isDisabled shortcut property to check for disabled fieldset ancestors
1052 return elem.isDisabled === disabled ||
1053
1054 // Where there is no isDisabled, check manually
1055 /* jshint -W018 */
1056 elem.isDisabled !== !disabled &&
1057 inDisabledFieldset( elem ) === disabled;
1058 }
1059
1060 return elem.disabled === disabled;
1061
1062 // Try to winnow out elements that can't be disabled before trusting the disabled property.
1063 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1064 // even exist on them, let alone have a boolean value.
1065 } else if ( "label" in elem ) {
1066 return elem.disabled === disabled;
1067 }
1068
1069 // Remaining elements are neither :enabled nor :disabled
1070 return false;
1071 };
1072 }
1073
1074 /**
1075 * Returns a function to use in pseudos for positionals
1076 * @param {Function} fn
1077 */
1078 function createPositionalPseudo( fn ) {
1079 return markFunction( function( argument ) {
1080 argument = +argument;
1081 return markFunction( function( seed, matches ) {
1082 var j,
1083 matchIndexes = fn( [], seed.length, argument ),
1084 i = matchIndexes.length;
1085
1086 // Match elements found at the specified indexes
1087 while ( i-- ) {
1088 if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
1089 seed[ j ] = !( matches[ j ] = seed[ j ] );
1090 }
1091 }
1092 } );
1093 } );
1094 }
1095
1096 /**
1097 * Checks a node for validity as a Sizzle context
1098 * @param {Element|Object=} context
1099 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1100 */
1101 function testContext( context ) {
1102 return context && typeof context.getElementsByTagName !== "undefined" && context;
1103 }
1104
1105 // Expose support vars for convenience
1106 support = Sizzle.support = {};
1107
1108 /**
1109 * Detects XML nodes
1110 * @param {Element|Object} elem An element or a document
1111 * @returns {Boolean} True iff elem is a non-HTML XML node
1112 */
1113 isXML = Sizzle.isXML = function( elem ) {
1114 var namespace = elem && elem.namespaceURI,
1115 docElem = elem && ( elem.ownerDocument || elem ).documentElement;
1116
1117 // Support: IE <=8
1118 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
1119 // https://bugs.jquery.com/ticket/4833
1120 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
1121 };
1122
1123 /**
1124 * Sets document-related variables once based on the current document
1125 * @param {Element|Object} [doc] An element or document object to use to set the document
1126 * @returns {Object} Returns the current document
1127 */
1128 setDocument = Sizzle.setDocument = function( node ) {
1129 var hasCompare, subWindow,
1130 doc = node ? node.ownerDocument || node : preferredDoc;
1131
1132 // Return early if doc is invalid or already selected
1133 // Support: IE 11+, Edge 17 - 18+
1134 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1135 // two documents; shallow comparisons work.
1136 // eslint-disable-next-line eqeqeq
1137 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
1138 return document;
1139 }
1140
1141 // Update global variables
1142 document = doc;
1143 docElem = document.documentElement;
1144 documentIsHTML = !isXML( document );
1145
1146 // Support: IE 9 - 11+, Edge 12 - 18+
1147 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1148 // Support: IE 11+, Edge 17 - 18+
1149 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1150 // two documents; shallow comparisons work.
1151 // eslint-disable-next-line eqeqeq
1152 if ( preferredDoc != document &&
1153 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
1154
1155 // Support: IE 11, Edge
1156 if ( subWindow.addEventListener ) {
1157 subWindow.addEventListener( "unload", unloadHandler, false );
1158
1159 // Support: IE 9 - 10 only
1160 } else if ( subWindow.attachEvent ) {
1161 subWindow.attachEvent( "onunload", unloadHandler );
1162 }
1163 }
1164
1165 // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
1166 // Safari 4 - 5 only, Opera <=11.6 - 12.x only
1167 // IE/Edge & older browsers don't support the :scope pseudo-class.
1168 // Support: Safari 6.0 only
1169 // Safari 6.0 supports :scope but it's an alias of :root there.
1170 support.scope = assert( function( el ) {
1171 docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
1172 return typeof el.querySelectorAll !== "undefined" &&
1173 !el.querySelectorAll( ":scope fieldset div" ).length;
1174 } );
1175
1176 /* Attributes
1177 ---------------------------------------------------------------------- */
1178
1179 // Support: IE<8
1180 // Verify that getAttribute really returns attributes and not properties
1181 // (excepting IE8 booleans)
1182 support.attributes = assert( function( el ) {
1183 el.className = "i";
1184 return !el.getAttribute( "className" );
1185 } );
1186
1187 /* getElement(s)By*
1188 ---------------------------------------------------------------------- */
1189
1190 // Check if getElementsByTagName("*") returns only elements
1191 support.getElementsByTagName = assert( function( el ) {
1192 el.appendChild( document.createComment( "" ) );
1193 return !el.getElementsByTagName( "*" ).length;
1194 } );
1195
1196 // Support: IE<9
1197 support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1198
1199 // Support: IE<10
1200 // Check if getElementById returns elements by name
1201 // The broken getElementById methods don't pick up programmatically-set names,
1202 // so use a roundabout getElementsByName test
1203 support.getById = assert( function( el ) {
1204 docElem.appendChild( el ).id = expando;
1205 return !document.getElementsByName || !document.getElementsByName( expando ).length;
1206 } );
1207
1208 // ID filter and find
1209 if ( support.getById ) {
1210 Expr.filter[ "ID" ] = function( id ) {
1211 var attrId = id.replace( runescape, funescape );
1212 return function( elem ) {
1213 return elem.getAttribute( "id" ) === attrId;
1214 };
1215 };
1216 Expr.find[ "ID" ] = function( id, context ) {
1217 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1218 var elem = context.getElementById( id );
1219 return elem ? [ elem ] : [];
1220 }
1221 };
1222 } else {
1223 Expr.filter[ "ID" ] = function( id ) {
1224 var attrId = id.replace( runescape, funescape );
1225 return function( elem ) {
1226 var node = typeof elem.getAttributeNode !== "undefined" &&
1227 elem.getAttributeNode( "id" );
1228 return node && node.value === attrId;
1229 };
1230 };
1231
1232 // Support: IE 6 - 7 only
1233 // getElementById is not reliable as a find shortcut
1234 Expr.find[ "ID" ] = function( id, context ) {
1235 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1236 var node, i, elems,
1237 elem = context.getElementById( id );
1238
1239 if ( elem ) {
1240
1241 // Verify the id attribute
1242 node = elem.getAttributeNode( "id" );
1243 if ( node && node.value === id ) {
1244 return [ elem ];
1245 }
1246
1247 // Fall back on getElementsByName
1248 elems = context.getElementsByName( id );
1249 i = 0;
1250 while ( ( elem = elems[ i++ ] ) ) {
1251 node = elem.getAttributeNode( "id" );
1252 if ( node && node.value === id ) {
1253 return [ elem ];
1254 }
1255 }
1256 }
1257
1258 return [];
1259 }
1260 };
1261 }
1262
1263 // Tag
1264 Expr.find[ "TAG" ] = support.getElementsByTagName ?
1265 function( tag, context ) {
1266 if ( typeof context.getElementsByTagName !== "undefined" ) {
1267 return context.getElementsByTagName( tag );
1268
1269 // DocumentFragment nodes don't have gEBTN
1270 } else if ( support.qsa ) {
1271 return context.querySelectorAll( tag );
1272 }
1273 } :
1274
1275 function( tag, context ) {
1276 var elem,
1277 tmp = [],
1278 i = 0,
1279
1280 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1281 results = context.getElementsByTagName( tag );
1282
1283 // Filter out possible comments
1284 if ( tag === "*" ) {
1285 while ( ( elem = results[ i++ ] ) ) {
1286 if ( elem.nodeType === 1 ) {
1287 tmp.push( elem );
1288 }
1289 }
1290
1291 return tmp;
1292 }
1293 return results;
1294 };
1295
1296 // Class
1297 Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
1298 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1299 return context.getElementsByClassName( className );
1300 }
1301 };
1302
1303 /* QSA/matchesSelector
1304 ---------------------------------------------------------------------- */
1305
1306 // QSA and matchesSelector support
1307
1308 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1309 rbuggyMatches = [];
1310
1311 // qSa(:focus) reports false when true (Chrome 21)
1312 // We allow this because of a bug in IE8/9 that throws an error
1313 // whenever `document.activeElement` is accessed on an iframe
1314 // So, we allow :focus to pass through QSA all the time to avoid the IE error
1315 // See https://bugs.jquery.com/ticket/13378
1316 rbuggyQSA = [];
1317
1318 if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
1319
1320 // Build QSA regex
1321 // Regex strategy adopted from Diego Perini
1322 assert( function( el ) {
1323
1324 var input;
1325
1326 // Select is set to empty string on purpose
1327 // This is to test IE's treatment of not explicitly
1328 // setting a boolean content attribute,
1329 // since its presence should be enough
1330 // https://bugs.jquery.com/ticket/12359
1331 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
1332 "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1333 "<option selected=''></option></select>";
1334
1335 // Support: IE8, Opera 11-12.16
1336 // Nothing should be selected when empty strings follow ^= or $= or *=
1337 // The test attribute must be unknown in Opera but "safe" for WinRT
1338 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1339 if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
1340 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1341 }
1342
1343 // Support: IE8
1344 // Boolean attributes and "value" are not treated correctly
1345 if ( !el.querySelectorAll( "[selected]" ).length ) {
1346 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1347 }
1348
1349 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1350 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1351 rbuggyQSA.push( "~=" );
1352 }
1353
1354 // Support: IE 11+, Edge 15 - 18+
1355 // IE 11/Edge don't find elements on a `[name='']` query in some cases.
1356 // Adding a temporary attribute to the document before the selection works
1357 // around the issue.
1358 // Interestingly, IE 10 & older don't seem to have the issue.
1359 input = document.createElement( "input" );
1360 input.setAttribute( "name", "" );
1361 el.appendChild( input );
1362 if ( !el.querySelectorAll( "[name='']" ).length ) {
1363 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
1364 whitespace + "*(?:''|\"\")" );
1365 }
1366
1367 // Webkit/Opera - :checked should return selected option elements
1368 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1369 // IE8 throws error here and will not see later tests
1370 if ( !el.querySelectorAll( ":checked" ).length ) {
1371 rbuggyQSA.push( ":checked" );
1372 }
1373
1374 // Support: Safari 8+, iOS 8+
1375 // https://bugs.webkit.org/show_bug.cgi?id=136851
1376 // In-page `selector#id sibling-combinator selector` fails
1377 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
1378 rbuggyQSA.push( ".#.+[+~]" );
1379 }
1380
1381 // Support: Firefox <=3.6 - 5 only
1382 // Old Firefox doesn't throw on a badly-escaped identifier.
1383 el.querySelectorAll( "\\\f" );
1384 rbuggyQSA.push( "[\\r\\n\\f]" );
1385 } );
1386
1387 assert( function( el ) {
1388 el.innerHTML = "<a href='' disabled='disabled'></a>" +
1389 "<select disabled='disabled'><option/></select>";
1390
1391 // Support: Windows 8 Native Apps
1392 // The type and name attributes are restricted during .innerHTML assignment
1393 var input = document.createElement( "input" );
1394 input.setAttribute( "type", "hidden" );
1395 el.appendChild( input ).setAttribute( "name", "D" );
1396
1397 // Support: IE8
1398 // Enforce case-sensitivity of name attribute
1399 if ( el.querySelectorAll( "[name=d]" ).length ) {
1400 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1401 }
1402
1403 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1404 // IE8 throws error here and will not see later tests
1405 if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
1406 rbuggyQSA.push( ":enabled", ":disabled" );
1407 }
1408
1409 // Support: IE9-11+
1410 // IE's :disabled selector does not pick up the children of disabled fieldsets
1411 docElem.appendChild( el ).disabled = true;
1412 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
1413 rbuggyQSA.push( ":enabled", ":disabled" );
1414 }
1415
1416 // Support: Opera 10 - 11 only
1417 // Opera 10-11 does not throw on post-comma invalid pseudos
1418 el.querySelectorAll( "*,:x" );
1419 rbuggyQSA.push( ",.*:" );
1420 } );
1421 }
1422
1423 if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
1424 docElem.webkitMatchesSelector ||
1425 docElem.mozMatchesSelector ||
1426 docElem.oMatchesSelector ||
1427 docElem.msMatchesSelector ) ) ) ) {
1428
1429 assert( function( el ) {
1430
1431 // Check to see if it's possible to do matchesSelector
1432 // on a disconnected node (IE 9)
1433 support.disconnectedMatch = matches.call( el, "*" );
1434
1435 // This should fail with an exception
1436 // Gecko does not error, returns false instead
1437 matches.call( el, "[s!='']:x" );
1438 rbuggyMatches.push( "!=", pseudos );
1439 } );
1440 }
1441
1442 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
1443 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
1444
1445 /* Contains
1446 ---------------------------------------------------------------------- */
1447 hasCompare = rnative.test( docElem.compareDocumentPosition );
1448
1449 // Element contains another
1450 // Purposefully self-exclusive
1451 // As in, an element does not contain itself
1452 contains = hasCompare || rnative.test( docElem.contains ) ?
1453 function( a, b ) {
1454 var adown = a.nodeType === 9 ? a.documentElement : a,
1455 bup = b && b.parentNode;
1456 return a === bup || !!( bup && bup.nodeType === 1 && (
1457 adown.contains ?
1458 adown.contains( bup ) :
1459 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1460 ) );
1461 } :
1462 function( a, b ) {
1463 if ( b ) {
1464 while ( ( b = b.parentNode ) ) {
1465 if ( b === a ) {
1466 return true;
1467 }
1468 }
1469 }
1470 return false;
1471 };
1472
1473 /* Sorting
1474 ---------------------------------------------------------------------- */
1475
1476 // Document order sorting
1477 sortOrder = hasCompare ?
1478 function( a, b ) {
1479
1480 // Flag for duplicate removal
1481 if ( a === b ) {
1482 hasDuplicate = true;
1483 return 0;
1484 }
1485
1486 // Sort on method existence if only one input has compareDocumentPosition
1487 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1488 if ( compare ) {
1489 return compare;
1490 }
1491
1492 // Calculate position if both inputs belong to the same document
1493 // Support: IE 11+, Edge 17 - 18+
1494 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1495 // two documents; shallow comparisons work.
1496 // eslint-disable-next-line eqeqeq
1497 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
1498 a.compareDocumentPosition( b ) :
1499
1500 // Otherwise we know they are disconnected
1501 1;
1502
1503 // Disconnected nodes
1504 if ( compare & 1 ||
1505 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
1506
1507 // Choose the first element that is related to our preferred document
1508 // Support: IE 11+, Edge 17 - 18+
1509 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1510 // two documents; shallow comparisons work.
1511 // eslint-disable-next-line eqeqeq
1512 if ( a == document || a.ownerDocument == preferredDoc &&
1513 contains( preferredDoc, a ) ) {
1514 return -1;
1515 }
1516
1517 // Support: IE 11+, Edge 17 - 18+
1518 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1519 // two documents; shallow comparisons work.
1520 // eslint-disable-next-line eqeqeq
1521 if ( b == document || b.ownerDocument == preferredDoc &&
1522 contains( preferredDoc, b ) ) {
1523 return 1;
1524 }
1525
1526 // Maintain original order
1527 return sortInput ?
1528 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1529 0;
1530 }
1531
1532 return compare & 4 ? -1 : 1;
1533 } :
1534 function( a, b ) {
1535
1536 // Exit early if the nodes are identical
1537 if ( a === b ) {
1538 hasDuplicate = true;
1539 return 0;
1540 }
1541
1542 var cur,
1543 i = 0,
1544 aup = a.parentNode,
1545 bup = b.parentNode,
1546 ap = [ a ],
1547 bp = [ b ];
1548
1549 // Parentless nodes are either documents or disconnected
1550 if ( !aup || !bup ) {
1551
1552 // Support: IE 11+, Edge 17 - 18+
1553 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1554 // two documents; shallow comparisons work.
1555 /* eslint-disable eqeqeq */
1556 return a == document ? -1 :
1557 b == document ? 1 :
1558 /* eslint-enable eqeqeq */
1559 aup ? -1 :
1560 bup ? 1 :
1561 sortInput ?
1562 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1563 0;
1564
1565 // If the nodes are siblings, we can do a quick check
1566 } else if ( aup === bup ) {
1567 return siblingCheck( a, b );
1568 }
1569
1570 // Otherwise we need full lists of their ancestors for comparison
1571 cur = a;
1572 while ( ( cur = cur.parentNode ) ) {
1573 ap.unshift( cur );
1574 }
1575 cur = b;
1576 while ( ( cur = cur.parentNode ) ) {
1577 bp.unshift( cur );
1578 }
1579
1580 // Walk down the tree looking for a discrepancy
1581 while ( ap[ i ] === bp[ i ] ) {
1582 i++;
1583 }
1584
1585 return i ?
1586
1587 // Do a sibling check if the nodes have a common ancestor
1588 siblingCheck( ap[ i ], bp[ i ] ) :
1589
1590 // Otherwise nodes in our document sort first
1591 // Support: IE 11+, Edge 17 - 18+
1592 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1593 // two documents; shallow comparisons work.
1594 /* eslint-disable eqeqeq */
1595 ap[ i ] == preferredDoc ? -1 :
1596 bp[ i ] == preferredDoc ? 1 :
1597 /* eslint-enable eqeqeq */
1598 0;
1599 };
1600
1601 return document;
1602 };
1603
1604 Sizzle.matches = function( expr, elements ) {
1605 return Sizzle( expr, null, null, elements );
1606 };
1607
1608 Sizzle.matchesSelector = function( elem, expr ) {
1609 setDocument( elem );
1610
1611 if ( support.matchesSelector && documentIsHTML &&
1612 !nonnativeSelectorCache[ expr + " " ] &&
1613 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1614 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1615
1616 try {
1617 var ret = matches.call( elem, expr );
1618
1619 // IE 9's matchesSelector returns false on disconnected nodes
1620 if ( ret || support.disconnectedMatch ||
1621
1622 // As well, disconnected nodes are said to be in a document
1623 // fragment in IE 9
1624 elem.document && elem.document.nodeType !== 11 ) {
1625 return ret;
1626 }
1627 } catch ( e ) {
1628 nonnativeSelectorCache( expr, true );
1629 }
1630 }
1631
1632 return Sizzle( expr, document, null, [ elem ] ).length > 0;
1633 };
1634
1635 Sizzle.contains = function( context, elem ) {
1636
1637 // Set document vars if needed
1638 // Support: IE 11+, Edge 17 - 18+
1639 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1640 // two documents; shallow comparisons work.
1641 // eslint-disable-next-line eqeqeq
1642 if ( ( context.ownerDocument || context ) != document ) {
1643 setDocument( context );
1644 }
1645 return contains( context, elem );
1646 };
1647
1648 Sizzle.attr = function( elem, name ) {
1649
1650 // Set document vars if needed
1651 // Support: IE 11+, Edge 17 - 18+
1652 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1653 // two documents; shallow comparisons work.
1654 // eslint-disable-next-line eqeqeq
1655 if ( ( elem.ownerDocument || elem ) != document ) {
1656 setDocument( elem );
1657 }
1658
1659 var fn = Expr.attrHandle[ name.toLowerCase() ],
1660
1661 // Don't get fooled by Object.prototype properties (jQuery #13807)
1662 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1663 fn( elem, name, !documentIsHTML ) :
1664 undefined;
1665
1666 return val !== undefined ?
1667 val :
1668 support.attributes || !documentIsHTML ?
1669 elem.getAttribute( name ) :
1670 ( val = elem.getAttributeNode( name ) ) && val.specified ?
1671 val.value :
1672 null;
1673 };
1674
1675 Sizzle.escape = function( sel ) {
1676 return ( sel + "" ).replace( rcssescape, fcssescape );
1677 };
1678
1679 Sizzle.error = function( msg ) {
1680 throw new Error( "Syntax error, unrecognized expression: " + msg );
1681 };
1682
1683 /**
1684 * Document sorting and removing duplicates
1685 * @param {ArrayLike} results
1686 */
1687 Sizzle.uniqueSort = function( results ) {
1688 var elem,
1689 duplicates = [],
1690 j = 0,
1691 i = 0;
1692
1693 // Unless we *know* we can detect duplicates, assume their presence
1694 hasDuplicate = !support.detectDuplicates;
1695 sortInput = !support.sortStable && results.slice( 0 );
1696 results.sort( sortOrder );
1697
1698 if ( hasDuplicate ) {
1699 while ( ( elem = results[ i++ ] ) ) {
1700 if ( elem === results[ i ] ) {
1701 j = duplicates.push( i );
1702 }
1703 }
1704 while ( j-- ) {
1705 results.splice( duplicates[ j ], 1 );
1706 }
1707 }
1708
1709 // Clear input after sorting to release objects
1710 // See https://github.com/jquery/sizzle/pull/225
1711 sortInput = null;
1712
1713 return results;
1714 };
1715
1716 /**
1717 * Utility function for retrieving the text value of an array of DOM nodes
1718 * @param {Array|Element} elem
1719 */
1720 getText = Sizzle.getText = function( elem ) {
1721 var node,
1722 ret = "",
1723 i = 0,
1724 nodeType = elem.nodeType;
1725
1726 if ( !nodeType ) {
1727
1728 // If no nodeType, this is expected to be an array
1729 while ( ( node = elem[ i++ ] ) ) {
1730
1731 // Do not traverse comment nodes
1732 ret += getText( node );
1733 }
1734 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1735
1736 // Use textContent for elements
1737 // innerText usage removed for consistency of new lines (jQuery #11153)
1738 if ( typeof elem.textContent === "string" ) {
1739 return elem.textContent;
1740 } else {
1741
1742 // Traverse its children
1743 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1744 ret += getText( elem );
1745 }
1746 }
1747 } else if ( nodeType === 3 || nodeType === 4 ) {
1748 return elem.nodeValue;
1749 }
1750
1751 // Do not include comment or processing instruction nodes
1752
1753 return ret;
1754 };
1755
1756 Expr = Sizzle.selectors = {
1757
1758 // Can be adjusted by the user
1759 cacheLength: 50,
1760
1761 createPseudo: markFunction,
1762
1763 match: matchExpr,
1764
1765 attrHandle: {},
1766
1767 find: {},
1768
1769 relative: {
1770 ">": { dir: "parentNode", first: true },
1771 " ": { dir: "parentNode" },
1772 "+": { dir: "previousSibling", first: true },
1773 "~": { dir: "previousSibling" }
1774 },
1775
1776 preFilter: {
1777 "ATTR": function( match ) {
1778 match[ 1 ] = match[ 1 ].replace( runescape, funescape );
1779
1780 // Move the given value to match[3] whether quoted or unquoted
1781 match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
1782 match[ 5 ] || "" ).replace( runescape, funescape );
1783
1784 if ( match[ 2 ] === "~=" ) {
1785 match[ 3 ] = " " + match[ 3 ] + " ";
1786 }
1787
1788 return match.slice( 0, 4 );
1789 },
1790
1791 "CHILD": function( match ) {
1792
1793 /* matches from matchExpr["CHILD"]
1794 1 type (only|nth|...)
1795 2 what (child|of-type)
1796 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1797 4 xn-component of xn+y argument ([+-]?\d*n|)
1798 5 sign of xn-component
1799 6 x of xn-component
1800 7 sign of y-component
1801 8 y of y-component
1802 */
1803 match[ 1 ] = match[ 1 ].toLowerCase();
1804
1805 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
1806
1807 // nth-* requires argument
1808 if ( !match[ 3 ] ) {
1809 Sizzle.error( match[ 0 ] );
1810 }
1811
1812 // numeric x and y parameters for Expr.filter.CHILD
1813 // remember that false/true cast respectively to 0/1
1814 match[ 4 ] = +( match[ 4 ] ?
1815 match[ 5 ] + ( match[ 6 ] || 1 ) :
1816 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
1817 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
1818
1819 // other types prohibit arguments
1820 } else if ( match[ 3 ] ) {
1821 Sizzle.error( match[ 0 ] );
1822 }
1823
1824 return match;
1825 },
1826
1827 "PSEUDO": function( match ) {
1828 var excess,
1829 unquoted = !match[ 6 ] && match[ 2 ];
1830
1831 if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
1832 return null;
1833 }
1834
1835 // Accept quoted arguments as-is
1836 if ( match[ 3 ] ) {
1837 match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
1838
1839 // Strip excess characters from unquoted arguments
1840 } else if ( unquoted && rpseudo.test( unquoted ) &&
1841
1842 // Get excess from tokenize (recursively)
1843 ( excess = tokenize( unquoted, true ) ) &&
1844
1845 // advance to the next closing parenthesis
1846 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
1847
1848 // excess is a negative index
1849 match[ 0 ] = match[ 0 ].slice( 0, excess );
1850 match[ 2 ] = unquoted.slice( 0, excess );
1851 }
1852
1853 // Return only captures needed by the pseudo filter method (type and argument)
1854 return match.slice( 0, 3 );
1855 }
1856 },
1857
1858 filter: {
1859
1860 "TAG": function( nodeNameSelector ) {
1861 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1862 return nodeNameSelector === "*" ?
1863 function() {
1864 return true;
1865 } :
1866 function( elem ) {
1867 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1868 };
1869 },
1870
1871 "CLASS": function( className ) {
1872 var pattern = classCache[ className + " " ];
1873
1874 return pattern ||
1875 ( pattern = new RegExp( "(^|" + whitespace +
1876 ")" + className + "(" + whitespace + "|$)" ) ) && classCache(
1877 className, function( elem ) {
1878 return pattern.test(
1879 typeof elem.className === "string" && elem.className ||
1880 typeof elem.getAttribute !== "undefined" &&
1881 elem.getAttribute( "class" ) ||
1882 ""
1883 );
1884 } );
1885 },
1886
1887 "ATTR": function( name, operator, check ) {
1888 return function( elem ) {
1889 var result = Sizzle.attr( elem, name );
1890
1891 if ( result == null ) {
1892 return operator === "!=";
1893 }
1894 if ( !operator ) {
1895 return true;
1896 }
1897
1898 result += "";
1899
1900 /* eslint-disable max-len */
1901
1902 return operator === "=" ? result === check :
1903 operator === "!=" ? result !== check :
1904 operator === "^=" ? check && result.indexOf( check ) === 0 :
1905 operator === "*=" ? check && result.indexOf( check ) > -1 :
1906 operator === "$=" ? check && result.slice( -check.length ) === check :
1907 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1908 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1909 false;
1910 /* eslint-enable max-len */
1911
1912 };
1913 },
1914
1915 "CHILD": function( type, what, _argument, first, last ) {
1916 var simple = type.slice( 0, 3 ) !== "nth",
1917 forward = type.slice( -4 ) !== "last",
1918 ofType = what === "of-type";
1919
1920 return first === 1 && last === 0 ?
1921
1922 // Shortcut for :nth-*(n)
1923 function( elem ) {
1924 return !!elem.parentNode;
1925 } :
1926
1927 function( elem, _context, xml ) {
1928 var cache, uniqueCache, outerCache, node, nodeIndex, start,
1929 dir = simple !== forward ? "nextSibling" : "previousSibling",
1930 parent = elem.parentNode,
1931 name = ofType && elem.nodeName.toLowerCase(),
1932 useCache = !xml && !ofType,
1933 diff = false;
1934
1935 if ( parent ) {
1936
1937 // :(first|last|only)-(child|of-type)
1938 if ( simple ) {
1939 while ( dir ) {
1940 node = elem;
1941 while ( ( node = node[ dir ] ) ) {
1942 if ( ofType ?
1943 node.nodeName.toLowerCase() === name :
1944 node.nodeType === 1 ) {
1945
1946 return false;
1947 }
1948 }
1949
1950 // Reverse direction for :only-* (if we haven't yet done so)
1951 start = dir = type === "only" && !start && "nextSibling";
1952 }
1953 return true;
1954 }
1955
1956 start = [ forward ? parent.firstChild : parent.lastChild ];
1957
1958 // non-xml :nth-child(...) stores cache data on `parent`
1959 if ( forward && useCache ) {
1960
1961 // Seek `elem` from a previously-cached index
1962
1963 // ...in a gzip-friendly way
1964 node = parent;
1965 outerCache = node[ expando ] || ( node[ expando ] = {} );
1966
1967 // Support: IE <9 only
1968 // Defend against cloned attroperties (jQuery gh-1709)
1969 uniqueCache = outerCache[ node.uniqueID ] ||
1970 ( outerCache[ node.uniqueID ] = {} );
1971
1972 cache = uniqueCache[ type ] || [];
1973 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1974 diff = nodeIndex && cache[ 2 ];
1975 node = nodeIndex && parent.childNodes[ nodeIndex ];
1976
1977 while ( ( node = ++nodeIndex && node && node[ dir ] ||
1978
1979 // Fallback to seeking `elem` from the start
1980 ( diff = nodeIndex = 0 ) || start.pop() ) ) {
1981
1982 // When found, cache indexes on `parent` and break
1983 if ( node.nodeType === 1 && ++diff && node === elem ) {
1984 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1985 break;
1986 }
1987 }
1988
1989 } else {
1990
1991 // Use previously-cached element index if available
1992 if ( useCache ) {
1993
1994 // ...in a gzip-friendly way
1995 node = elem;
1996 outerCache = node[ expando ] || ( node[ expando ] = {} );
1997
1998 // Support: IE <9 only
1999 // Defend against cloned attroperties (jQuery gh-1709)
2000 uniqueCache = outerCache[ node.uniqueID ] ||
2001 ( outerCache[ node.uniqueID ] = {} );
2002
2003 cache = uniqueCache[ type ] || [];
2004 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2005 diff = nodeIndex;
2006 }
2007
2008 // xml :nth-child(...)
2009 // or :nth-last-child(...) or :nth(-last)?-of-type(...)
2010 if ( diff === false ) {
2011
2012 // Use the same loop as above to seek `elem` from the start
2013 while ( ( node = ++nodeIndex && node && node[ dir ] ||
2014 ( diff = nodeIndex = 0 ) || start.pop() ) ) {
2015
2016 if ( ( ofType ?
2017 node.nodeName.toLowerCase() === name :
2018 node.nodeType === 1 ) &&
2019 ++diff ) {
2020
2021 // Cache the index of each encountered element
2022 if ( useCache ) {
2023 outerCache = node[ expando ] ||
2024 ( node[ expando ] = {} );
2025
2026 // Support: IE <9 only
2027 // Defend against cloned attroperties (jQuery gh-1709)
2028 uniqueCache = outerCache[ node.uniqueID ] ||
2029 ( outerCache[ node.uniqueID ] = {} );
2030
2031 uniqueCache[ type ] = [ dirruns, diff ];
2032 }
2033
2034 if ( node === elem ) {
2035 break;
2036 }
2037 }
2038 }
2039 }
2040 }
2041
2042 // Incorporate the offset, then check against cycle size
2043 diff -= last;
2044 return diff === first || ( diff % first === 0 && diff / first >= 0 );
2045 }
2046 };
2047 },
2048
2049 "PSEUDO": function( pseudo, argument ) {
2050
2051 // pseudo-class names are case-insensitive
2052 // http://www.w3.org/TR/selectors/#pseudo-classes
2053 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2054 // Remember that setFilters inherits from pseudos
2055 var args,
2056 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2057 Sizzle.error( "unsupported pseudo: " + pseudo );
2058
2059 // The user may use createPseudo to indicate that
2060 // arguments are needed to create the filter function
2061 // just as Sizzle does
2062 if ( fn[ expando ] ) {
2063 return fn( argument );
2064 }
2065
2066 // But maintain support for old signatures
2067 if ( fn.length > 1 ) {
2068 args = [ pseudo, pseudo, "", argument ];
2069 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2070 markFunction( function( seed, matches ) {
2071 var idx,
2072 matched = fn( seed, argument ),
2073 i = matched.length;
2074 while ( i-- ) {
2075 idx = indexOf( seed, matched[ i ] );
2076 seed[ idx ] = !( matches[ idx ] = matched[ i ] );
2077 }
2078 } ) :
2079 function( elem ) {
2080 return fn( elem, 0, args );
2081 };
2082 }
2083
2084 return fn;
2085 }
2086 },
2087
2088 pseudos: {
2089
2090 // Potentially complex pseudos
2091 "not": markFunction( function( selector ) {
2092
2093 // Trim the selector passed to compile
2094 // to avoid treating leading and trailing
2095 // spaces as combinators
2096 var input = [],
2097 results = [],
2098 matcher = compile( selector.replace( rtrim, "$1" ) );
2099
2100 return matcher[ expando ] ?
2101 markFunction( function( seed, matches, _context, xml ) {
2102 var elem,
2103 unmatched = matcher( seed, null, xml, [] ),
2104 i = seed.length;
2105
2106 // Match elements unmatched by `matcher`
2107 while ( i-- ) {
2108 if ( ( elem = unmatched[ i ] ) ) {
2109 seed[ i ] = !( matches[ i ] = elem );
2110 }
2111 }
2112 } ) :
2113 function( elem, _context, xml ) {
2114 input[ 0 ] = elem;
2115 matcher( input, null, xml, results );
2116
2117 // Don't keep the element (issue #299)
2118 input[ 0 ] = null;
2119 return !results.pop();
2120 };
2121 } ),
2122
2123 "has": markFunction( function( selector ) {
2124 return function( elem ) {
2125 return Sizzle( selector, elem ).length > 0;
2126 };
2127 } ),
2128
2129 "contains": markFunction( function( text ) {
2130 text = text.replace( runescape, funescape );
2131 return function( elem ) {
2132 return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
2133 };
2134 } ),
2135
2136 // "Whether an element is represented by a :lang() selector
2137 // is based solely on the element's language value
2138 // being equal to the identifier C,
2139 // or beginning with the identifier C immediately followed by "-".
2140 // The matching of C against the element's language value is performed case-insensitively.
2141 // The identifier C does not have to be a valid language name."
2142 // http://www.w3.org/TR/selectors/#lang-pseudo
2143 "lang": markFunction( function( lang ) {
2144
2145 // lang value must be a valid identifier
2146 if ( !ridentifier.test( lang || "" ) ) {
2147 Sizzle.error( "unsupported lang: " + lang );
2148 }
2149 lang = lang.replace( runescape, funescape ).toLowerCase();
2150 return function( elem ) {
2151 var elemLang;
2152 do {
2153 if ( ( elemLang = documentIsHTML ?
2154 elem.lang :
2155 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
2156
2157 elemLang = elemLang.toLowerCase();
2158 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2159 }
2160 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
2161 return false;
2162 };
2163 } ),
2164
2165 // Miscellaneous
2166 "target": function( elem ) {
2167 var hash = window.location && window.location.hash;
2168 return hash && hash.slice( 1 ) === elem.id;
2169 },
2170
2171 "root": function( elem ) {
2172 return elem === docElem;
2173 },
2174
2175 "focus": function( elem ) {
2176 return elem === document.activeElement &&
2177 ( !document.hasFocus || document.hasFocus() ) &&
2178 !!( elem.type || elem.href || ~elem.tabIndex );
2179 },
2180
2181 // Boolean properties
2182 "enabled": createDisabledPseudo( false ),
2183 "disabled": createDisabledPseudo( true ),
2184
2185 "checked": function( elem ) {
2186
2187 // In CSS3, :checked should return both checked and selected elements
2188 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2189 var nodeName = elem.nodeName.toLowerCase();
2190 return ( nodeName === "input" && !!elem.checked ) ||
2191 ( nodeName === "option" && !!elem.selected );
2192 },
2193
2194 "selected": function( elem ) {
2195
2196 // Accessing this property makes selected-by-default
2197 // options in Safari work properly
2198 if ( elem.parentNode ) {
2199 // eslint-disable-next-line no-unused-expressions
2200 elem.parentNode.selectedIndex;
2201 }
2202
2203 return elem.selected === true;
2204 },
2205
2206 // Contents
2207 "empty": function( elem ) {
2208
2209 // http://www.w3.org/TR/selectors/#empty-pseudo
2210 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2211 // but not by others (comment: 8; processing instruction: 7; etc.)
2212 // nodeType < 6 works because attributes (2) do not appear as children
2213 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2214 if ( elem.nodeType < 6 ) {
2215 return false;
2216 }
2217 }
2218 return true;
2219 },
2220
2221 "parent": function( elem ) {
2222 return !Expr.pseudos[ "empty" ]( elem );
2223 },
2224
2225 // Element/input types
2226 "header": function( elem ) {
2227 return rheader.test( elem.nodeName );
2228 },
2229
2230 "input": function( elem ) {
2231 return rinputs.test( elem.nodeName );
2232 },
2233
2234 "button": function( elem ) {
2235 var name = elem.nodeName.toLowerCase();
2236 return name === "input" && elem.type === "button" || name === "button";
2237 },
2238
2239 "text": function( elem ) {
2240 var attr;
2241 return elem.nodeName.toLowerCase() === "input" &&
2242 elem.type === "text" &&
2243
2244 // Support: IE<8
2245 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2246 ( ( attr = elem.getAttribute( "type" ) ) == null ||
2247 attr.toLowerCase() === "text" );
2248 },
2249
2250 // Position-in-collection
2251 "first": createPositionalPseudo( function() {
2252 return [ 0 ];
2253 } ),
2254
2255 "last": createPositionalPseudo( function( _matchIndexes, length ) {
2256 return [ length - 1 ];
2257 } ),
2258
2259 "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
2260 return [ argument < 0 ? argument + length : argument ];
2261 } ),
2262
2263 "even": createPositionalPseudo( function( matchIndexes, length ) {
2264 var i = 0;
2265 for ( ; i < length; i += 2 ) {
2266 matchIndexes.push( i );
2267 }
2268 return matchIndexes;
2269 } ),
2270
2271 "odd": createPositionalPseudo( function( matchIndexes, length ) {
2272 var i = 1;
2273 for ( ; i < length; i += 2 ) {
2274 matchIndexes.push( i );
2275 }
2276 return matchIndexes;
2277 } ),
2278
2279 "lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2280 var i = argument < 0 ?
2281 argument + length :
2282 argument > length ?
2283 length :
2284 argument;
2285 for ( ; --i >= 0; ) {
2286 matchIndexes.push( i );
2287 }
2288 return matchIndexes;
2289 } ),
2290
2291 "gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2292 var i = argument < 0 ? argument + length : argument;
2293 for ( ; ++i < length; ) {
2294 matchIndexes.push( i );
2295 }
2296 return matchIndexes;
2297 } )
2298 }
2299 };
2300
2301 Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
2302
2303 // Add button/input type pseudos
2304 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2305 Expr.pseudos[ i ] = createInputPseudo( i );
2306 }
2307 for ( i in { submit: true, reset: true } ) {
2308 Expr.pseudos[ i ] = createButtonPseudo( i );
2309 }
2310
2311 // Easy API for creating new setFilters
2312 function setFilters() {}
2313 setFilters.prototype = Expr.filters = Expr.pseudos;
2314 Expr.setFilters = new setFilters();
2315
2316 tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2317 var matched, match, tokens, type,
2318 soFar, groups, preFilters,
2319 cached = tokenCache[ selector + " " ];
2320
2321 if ( cached ) {
2322 return parseOnly ? 0 : cached.slice( 0 );
2323 }
2324
2325 soFar = selector;
2326 groups = [];
2327 preFilters = Expr.preFilter;
2328
2329 while ( soFar ) {
2330
2331 // Comma and first run
2332 if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
2333 if ( match ) {
2334
2335 // Don't consume trailing commas as valid
2336 soFar = soFar.slice( match[ 0 ].length ) || soFar;
2337 }
2338 groups.push( ( tokens = [] ) );
2339 }
2340
2341 matched = false;
2342
2343 // Combinators
2344 if ( ( match = rcombinators.exec( soFar ) ) ) {
2345 matched = match.shift();
2346 tokens.push( {
2347 value: matched,
2348
2349 // Cast descendant combinators to space
2350 type: match[ 0 ].replace( rtrim, " " )
2351 } );
2352 soFar = soFar.slice( matched.length );
2353 }
2354
2355 // Filters
2356 for ( type in Expr.filter ) {
2357 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
2358 ( match = preFilters[ type ]( match ) ) ) ) {
2359 matched = match.shift();
2360 tokens.push( {
2361 value: matched,
2362 type: type,
2363 matches: match
2364 } );
2365 soFar = soFar.slice( matched.length );
2366 }
2367 }
2368
2369 if ( !matched ) {
2370 break;
2371 }
2372 }
2373
2374 // Return the length of the invalid excess
2375 // if we're just parsing
2376 // Otherwise, throw an error or return tokens
2377 return parseOnly ?
2378 soFar.length :
2379 soFar ?
2380 Sizzle.error( selector ) :
2381
2382 // Cache the tokens
2383 tokenCache( selector, groups ).slice( 0 );
2384 };
2385
2386 function toSelector( tokens ) {
2387 var i = 0,
2388 len = tokens.length,
2389 selector = "";
2390 for ( ; i < len; i++ ) {
2391 selector += tokens[ i ].value;
2392 }
2393 return selector;
2394 }
2395
2396 function addCombinator( matcher, combinator, base ) {
2397 var dir = combinator.dir,
2398 skip = combinator.next,
2399 key = skip || dir,
2400 checkNonElements = base && key === "parentNode",
2401 doneName = done++;
2402
2403 return combinator.first ?
2404
2405 // Check against closest ancestor/preceding element
2406 function( elem, context, xml ) {
2407 while ( ( elem = elem[ dir ] ) ) {
2408 if ( elem.nodeType === 1 || checkNonElements ) {
2409 return matcher( elem, context, xml );
2410 }
2411 }
2412 return false;
2413 } :
2414
2415 // Check against all ancestor/preceding elements
2416 function( elem, context, xml ) {
2417 var oldCache, uniqueCache, outerCache,
2418 newCache = [ dirruns, doneName ];
2419
2420 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2421 if ( xml ) {
2422 while ( ( elem = elem[ dir ] ) ) {
2423 if ( elem.nodeType === 1 || checkNonElements ) {
2424 if ( matcher( elem, context, xml ) ) {
2425 return true;
2426 }
2427 }
2428 }
2429 } else {
2430 while ( ( elem = elem[ dir ] ) ) {
2431 if ( elem.nodeType === 1 || checkNonElements ) {
2432 outerCache = elem[ expando ] || ( elem[ expando ] = {} );
2433
2434 // Support: IE <9 only
2435 // Defend against cloned attroperties (jQuery gh-1709)
2436 uniqueCache = outerCache[ elem.uniqueID ] ||
2437 ( outerCache[ elem.uniqueID ] = {} );
2438
2439 if ( skip && skip === elem.nodeName.toLowerCase() ) {
2440 elem = elem[ dir ] || elem;
2441 } else if ( ( oldCache = uniqueCache[ key ] ) &&
2442 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2443
2444 // Assign to newCache so results back-propagate to previous elements
2445 return ( newCache[ 2 ] = oldCache[ 2 ] );
2446 } else {
2447
2448 // Reuse newcache so results back-propagate to previous elements
2449 uniqueCache[ key ] = newCache;
2450
2451 // A match means we're done; a fail means we have to keep checking
2452 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
2453 return true;
2454 }
2455 }
2456 }
2457 }
2458 }
2459 return false;
2460 };
2461 }
2462
2463 function elementMatcher( matchers ) {
2464 return matchers.length > 1 ?
2465 function( elem, context, xml ) {
2466 var i = matchers.length;
2467 while ( i-- ) {
2468 if ( !matchers[ i ]( elem, context, xml ) ) {
2469 return false;
2470 }
2471 }
2472 return true;
2473 } :
2474 matchers[ 0 ];
2475 }
2476
2477 function multipleContexts( selector, contexts, results ) {
2478 var i = 0,
2479 len = contexts.length;
2480 for ( ; i < len; i++ ) {
2481 Sizzle( selector, contexts[ i ], results );
2482 }
2483 return results;
2484 }
2485
2486 function condense( unmatched, map, filter, context, xml ) {
2487 var elem,
2488 newUnmatched = [],
2489 i = 0,
2490 len = unmatched.length,
2491 mapped = map != null;
2492
2493 for ( ; i < len; i++ ) {
2494 if ( ( elem = unmatched[ i ] ) ) {
2495 if ( !filter || filter( elem, context, xml ) ) {
2496 newUnmatched.push( elem );
2497 if ( mapped ) {
2498 map.push( i );
2499 }
2500 }
2501 }
2502 }
2503
2504 return newUnmatched;
2505 }
2506
2507 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2508 if ( postFilter && !postFilter[ expando ] ) {
2509 postFilter = setMatcher( postFilter );
2510 }
2511 if ( postFinder && !postFinder[ expando ] ) {
2512 postFinder = setMatcher( postFinder, postSelector );
2513 }
2514 return markFunction( function( seed, results, context, xml ) {
2515 var temp, i, elem,
2516 preMap = [],
2517 postMap = [],
2518 preexisting = results.length,
2519
2520 // Get initial elements from seed or context
2521 elems = seed || multipleContexts(
2522 selector || "*",
2523 context.nodeType ? [ context ] : context,
2524 []
2525 ),
2526
2527 // Prefilter to get matcher input, preserving a map for seed-results synchronization
2528 matcherIn = preFilter && ( seed || !selector ) ?
2529 condense( elems, preMap, preFilter, context, xml ) :
2530 elems,
2531
2532 matcherOut = matcher ?
2533
2534 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2535 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2536
2537 // ...intermediate processing is necessary
2538 [] :
2539
2540 // ...otherwise use results directly
2541 results :
2542 matcherIn;
2543
2544 // Find primary matches
2545 if ( matcher ) {
2546 matcher( matcherIn, matcherOut, context, xml );
2547 }
2548
2549 // Apply postFilter
2550 if ( postFilter ) {
2551 temp = condense( matcherOut, postMap );
2552 postFilter( temp, [], context, xml );
2553
2554 // Un-match failing elements by moving them back to matcherIn
2555 i = temp.length;
2556 while ( i-- ) {
2557 if ( ( elem = temp[ i ] ) ) {
2558 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
2559 }
2560 }
2561 }
2562
2563 if ( seed ) {
2564 if ( postFinder || preFilter ) {
2565 if ( postFinder ) {
2566
2567 // Get the final matcherOut by condensing this intermediate into postFinder contexts
2568 temp = [];
2569 i = matcherOut.length;
2570 while ( i-- ) {
2571 if ( ( elem = matcherOut[ i ] ) ) {
2572
2573 // Restore matcherIn since elem is not yet a final match
2574 temp.push( ( matcherIn[ i ] = elem ) );
2575 }
2576 }
2577 postFinder( null, ( matcherOut = [] ), temp, xml );
2578 }
2579
2580 // Move matched elements from seed to results to keep them synchronized
2581 i = matcherOut.length;
2582 while ( i-- ) {
2583 if ( ( elem = matcherOut[ i ] ) &&
2584 ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
2585
2586 seed[ temp ] = !( results[ temp ] = elem );
2587 }
2588 }
2589 }
2590
2591 // Add elements to results, through postFinder if defined
2592 } else {
2593 matcherOut = condense(
2594 matcherOut === results ?
2595 matcherOut.splice( preexisting, matcherOut.length ) :
2596 matcherOut
2597 );
2598 if ( postFinder ) {
2599 postFinder( null, results, matcherOut, xml );
2600 } else {
2601 push.apply( results, matcherOut );
2602 }
2603 }
2604 } );
2605 }
2606
2607 function matcherFromTokens( tokens ) {
2608 var checkContext, matcher, j,
2609 len = tokens.length,
2610 leadingRelative = Expr.relative[ tokens[ 0 ].type ],
2611 implicitRelative = leadingRelative || Expr.relative[ " " ],
2612 i = leadingRelative ? 1 : 0,
2613
2614 // The foundational matcher ensures that elements are reachable from top-level context(s)
2615 matchContext = addCombinator( function( elem ) {
2616 return elem === checkContext;
2617 }, implicitRelative, true ),
2618 matchAnyContext = addCombinator( function( elem ) {
2619 return indexOf( checkContext, elem ) > -1;
2620 }, implicitRelative, true ),
2621 matchers = [ function( elem, context, xml ) {
2622 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2623 ( checkContext = context ).nodeType ?
2624 matchContext( elem, context, xml ) :
2625 matchAnyContext( elem, context, xml ) );
2626
2627 // Avoid hanging onto element (issue #299)
2628 checkContext = null;
2629 return ret;
2630 } ];
2631
2632 for ( ; i < len; i++ ) {
2633 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
2634 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
2635 } else {
2636 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
2637
2638 // Return special upon seeing a positional matcher
2639 if ( matcher[ expando ] ) {
2640
2641 // Find the next relative operator (if any) for proper handling
2642 j = ++i;
2643 for ( ; j < len; j++ ) {
2644 if ( Expr.relative[ tokens[ j ].type ] ) {
2645 break;
2646 }
2647 }
2648 return setMatcher(
2649 i > 1 && elementMatcher( matchers ),
2650 i > 1 && toSelector(
2651
2652 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2653 tokens
2654 .slice( 0, i - 1 )
2655 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
2656 ).replace( rtrim, "$1" ),
2657 matcher,
2658 i < j && matcherFromTokens( tokens.slice( i, j ) ),
2659 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
2660 j < len && toSelector( tokens )
2661 );
2662 }
2663 matchers.push( matcher );
2664 }
2665 }
2666
2667 return elementMatcher( matchers );
2668 }
2669
2670 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2671 var bySet = setMatchers.length > 0,
2672 byElement = elementMatchers.length > 0,
2673 superMatcher = function( seed, context, xml, results, outermost ) {
2674 var elem, j, matcher,
2675 matchedCount = 0,
2676 i = "0",
2677 unmatched = seed && [],
2678 setMatched = [],
2679 contextBackup = outermostContext,
2680
2681 // We must always have either seed elements or outermost context
2682 elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
2683
2684 // Use integer dirruns iff this is the outermost matcher
2685 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
2686 len = elems.length;
2687
2688 if ( outermost ) {
2689
2690 // Support: IE 11+, Edge 17 - 18+
2691 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2692 // two documents; shallow comparisons work.
2693 // eslint-disable-next-line eqeqeq
2694 outermostContext = context == document || context || outermost;
2695 }
2696
2697 // Add elements passing elementMatchers directly to results
2698 // Support: IE<9, Safari
2699 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2700 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
2701 if ( byElement && elem ) {
2702 j = 0;
2703
2704 // Support: IE 11+, Edge 17 - 18+
2705 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2706 // two documents; shallow comparisons work.
2707 // eslint-disable-next-line eqeqeq
2708 if ( !context && elem.ownerDocument != document ) {
2709 setDocument( elem );
2710 xml = !documentIsHTML;
2711 }
2712 while ( ( matcher = elementMatchers[ j++ ] ) ) {
2713 if ( matcher( elem, context || document, xml ) ) {
2714 results.push( elem );
2715 break;
2716 }
2717 }
2718 if ( outermost ) {
2719 dirruns = dirrunsUnique;
2720 }
2721 }
2722
2723 // Track unmatched elements for set filters
2724 if ( bySet ) {
2725
2726 // They will have gone through all possible matchers
2727 if ( ( elem = !matcher && elem ) ) {
2728 matchedCount--;
2729 }
2730
2731 // Lengthen the array for every element, matched or not
2732 if ( seed ) {
2733 unmatched.push( elem );
2734 }
2735 }
2736 }
2737
2738 // `i` is now the count of elements visited above, and adding it to `matchedCount`
2739 // makes the latter nonnegative.
2740 matchedCount += i;
2741
2742 // Apply set filters to unmatched elements
2743 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2744 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2745 // no element matchers and no seed.
2746 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2747 // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2748 // numerically zero.
2749 if ( bySet && i !== matchedCount ) {
2750 j = 0;
2751 while ( ( matcher = setMatchers[ j++ ] ) ) {
2752 matcher( unmatched, setMatched, context, xml );
2753 }
2754
2755 if ( seed ) {
2756
2757 // Reintegrate element matches to eliminate the need for sorting
2758 if ( matchedCount > 0 ) {
2759 while ( i-- ) {
2760 if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
2761 setMatched[ i ] = pop.call( results );
2762 }
2763 }
2764 }
2765
2766 // Discard index placeholder values to get only actual matches
2767 setMatched = condense( setMatched );
2768 }
2769
2770 // Add matches to results
2771 push.apply( results, setMatched );
2772
2773 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2774 if ( outermost && !seed && setMatched.length > 0 &&
2775 ( matchedCount + setMatchers.length ) > 1 ) {
2776
2777 Sizzle.uniqueSort( results );
2778 }
2779 }
2780
2781 // Override manipulation of globals by nested matchers
2782 if ( outermost ) {
2783 dirruns = dirrunsUnique;
2784 outermostContext = contextBackup;
2785 }
2786
2787 return unmatched;
2788 };
2789
2790 return bySet ?
2791 markFunction( superMatcher ) :
2792 superMatcher;
2793 }
2794
2795 compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2796 var i,
2797 setMatchers = [],
2798 elementMatchers = [],
2799 cached = compilerCache[ selector + " " ];
2800
2801 if ( !cached ) {
2802
2803 // Generate a function of recursive functions that can be used to check each element
2804 if ( !match ) {
2805 match = tokenize( selector );
2806 }
2807 i = match.length;
2808 while ( i-- ) {
2809 cached = matcherFromTokens( match[ i ] );
2810 if ( cached[ expando ] ) {
2811 setMatchers.push( cached );
2812 } else {
2813 elementMatchers.push( cached );
2814 }
2815 }
2816
2817 // Cache the compiled function
2818 cached = compilerCache(
2819 selector,
2820 matcherFromGroupMatchers( elementMatchers, setMatchers )
2821 );
2822
2823 // Save selector and tokenization
2824 cached.selector = selector;
2825 }
2826 return cached;
2827 };
2828
2829 /**
2830 * A low-level selection function that works with Sizzle's compiled
2831 * selector functions
2832 * @param {String|Function} selector A selector or a pre-compiled
2833 * selector function built with Sizzle.compile
2834 * @param {Element} context
2835 * @param {Array} [results]
2836 * @param {Array} [seed] A set of elements to match against
2837 */
2838 select = Sizzle.select = function( selector, context, results, seed ) {
2839 var i, tokens, token, type, find,
2840 compiled = typeof selector === "function" && selector,
2841 match = !seed && tokenize( ( selector = compiled.selector || selector ) );
2842
2843 results = results || [];
2844
2845 // Try to minimize operations if there is only one selector in the list and no seed
2846 // (the latter of which guarantees us context)
2847 if ( match.length === 1 ) {
2848
2849 // Reduce context if the leading compound selector is an ID
2850 tokens = match[ 0 ] = match[ 0 ].slice( 0 );
2851 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
2852 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
2853
2854 context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
2855 .replace( runescape, funescape ), context ) || [] )[ 0 ];
2856 if ( !context ) {
2857 return results;
2858
2859 // Precompiled matchers will still verify ancestry, so step up a level
2860 } else if ( compiled ) {
2861 context = context.parentNode;
2862 }
2863
2864 selector = selector.slice( tokens.shift().value.length );
2865 }
2866
2867 // Fetch a seed set for right-to-left matching
2868 i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
2869 while ( i-- ) {
2870 token = tokens[ i ];
2871
2872 // Abort if we hit a combinator
2873 if ( Expr.relative[ ( type = token.type ) ] ) {
2874 break;
2875 }
2876 if ( ( find = Expr.find[ type ] ) ) {
2877
2878 // Search, expanding context for leading sibling combinators
2879 if ( ( seed = find(
2880 token.matches[ 0 ].replace( runescape, funescape ),
2881 rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
2882 context
2883 ) ) ) {
2884
2885 // If seed is empty or no tokens remain, we can return early
2886 tokens.splice( i, 1 );
2887 selector = seed.length && toSelector( tokens );
2888 if ( !selector ) {
2889 push.apply( results, seed );
2890 return results;
2891 }
2892
2893 break;
2894 }
2895 }
2896 }
2897 }
2898
2899 // Compile and execute a filtering function if one is not provided
2900 // Provide `match` to avoid retokenization if we modified the selector above
2901 ( compiled || compile( selector, match ) )(
2902 seed,
2903 context,
2904 !documentIsHTML,
2905 results,
2906 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2907 );
2908 return results;
2909 };
2910
2911 // One-time assignments
2912
2913 // Sort stability
2914 support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
2915
2916 // Support: Chrome 14-35+
2917 // Always assume duplicates if they aren't passed to the comparison function
2918 support.detectDuplicates = !!hasDuplicate;
2919
2920 // Initialize against the default document
2921 setDocument();
2922
2923 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2924 // Detached nodes confoundingly follow *each other*
2925 support.sortDetached = assert( function( el ) {
2926
2927 // Should return 1, but returns 4 (following)
2928 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
2929 } );
2930
2931 // Support: IE<8
2932 // Prevent attribute/property "interpolation"
2933 // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2934 if ( !assert( function( el ) {
2935 el.innerHTML = "<a href='#'></a>";
2936 return el.firstChild.getAttribute( "href" ) === "#";
2937 } ) ) {
2938 addHandle( "type|href|height|width", function( elem, name, isXML ) {
2939 if ( !isXML ) {
2940 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2941 }
2942 } );
2943 }
2944
2945 // Support: IE<9
2946 // Use defaultValue in place of getAttribute("value")
2947 if ( !support.attributes || !assert( function( el ) {
2948 el.innerHTML = "<input/>";
2949 el.firstChild.setAttribute( "value", "" );
2950 return el.firstChild.getAttribute( "value" ) === "";
2951 } ) ) {
2952 addHandle( "value", function( elem, _name, isXML ) {
2953 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2954 return elem.defaultValue;
2955 }
2956 } );
2957 }
2958
2959 // Support: IE<9
2960 // Use getAttributeNode to fetch booleans when getAttribute lies
2961 if ( !assert( function( el ) {
2962 return el.getAttribute( "disabled" ) == null;
2963 } ) ) {
2964 addHandle( booleans, function( elem, name, isXML ) {
2965 var val;
2966 if ( !isXML ) {
2967 return elem[ name ] === true ? name.toLowerCase() :
2968 ( val = elem.getAttributeNode( name ) ) && val.specified ?
2969 val.value :
2970 null;
2971 }
2972 } );
2973 }
2974
2975 return Sizzle;
2976
2977 } )( window );
2978
2979
2980
2981 jQuery.find = Sizzle;
2982 jQuery.expr = Sizzle.selectors;
2983
2984 // Deprecated
2985 jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2986 jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2987 jQuery.text = Sizzle.getText;
2988 jQuery.isXMLDoc = Sizzle.isXML;
2989 jQuery.contains = Sizzle.contains;
2990 jQuery.escapeSelector = Sizzle.escape;
2991
2992
2993
2994
2995 var dir = function( elem, dir, until ) {
2996 var matched = [],
2997 truncate = until !== undefined;
2998
2999 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
3000 if ( elem.nodeType === 1 ) {
3001 if ( truncate && jQuery( elem ).is( until ) ) {
3002 break;
3003 }
3004 matched.push( elem );
3005 }
3006 }
3007 return matched;
3008 };
3009
3010
3011 var siblings = function( n, elem ) {
3012 var matched = [];
3013
3014 for ( ; n; n = n.nextSibling ) {
3015 if ( n.nodeType === 1 && n !== elem ) {
3016 matched.push( n );
3017 }
3018 }
3019
3020 return matched;
3021 };
3022
3023
3024 var rneedsContext = jQuery.expr.match.needsContext;
3025
3026
3027
3028 function nodeName( elem, name ) {
3029
3030 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
3031
3032 }
3033 var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
3034
3035
3036
3037 // Implement the identical functionality for filter and not
3038 function winnow( elements, qualifier, not ) {
3039 if ( isFunction( qualifier ) ) {
3040 return jQuery.grep( elements, function( elem, i ) {
3041 return !!qualifier.call( elem, i, elem ) !== not;
3042 } );
3043 }
3044
3045 // Single element
3046 if ( qualifier.nodeType ) {
3047 return jQuery.grep( elements, function( elem ) {
3048 return ( elem === qualifier ) !== not;
3049 } );
3050 }
3051
3052 // Arraylike of elements (jQuery, arguments, Array)
3053 if ( typeof qualifier !== "string" ) {
3054 return jQuery.grep( elements, function( elem ) {
3055 return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
3056 } );
3057 }
3058
3059 // Filtered directly for both simple and complex selectors
3060 return jQuery.filter( qualifier, elements, not );
3061 }
3062
3063 jQuery.filter = function( expr, elems, not ) {
3064 var elem = elems[ 0 ];
3065
3066 if ( not ) {
3067 expr = ":not(" + expr + ")";
3068 }
3069
3070 if ( elems.length === 1 && elem.nodeType === 1 ) {
3071 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
3072 }
3073
3074 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
3075 return elem.nodeType === 1;
3076 } ) );
3077 };
3078
3079 jQuery.fn.extend( {
3080 find: function( selector ) {
3081 var i, ret,
3082 len = this.length,
3083 self = this;
3084
3085 if ( typeof selector !== "string" ) {
3086 return this.pushStack( jQuery( selector ).filter( function() {
3087 for ( i = 0; i < len; i++ ) {
3088 if ( jQuery.contains( self[ i ], this ) ) {
3089 return true;
3090 }
3091 }
3092 } ) );
3093 }
3094
3095 ret = this.pushStack( [] );
3096
3097 for ( i = 0; i < len; i++ ) {
3098 jQuery.find( selector, self[ i ], ret );
3099 }
3100
3101 return len > 1 ? jQuery.uniqueSort( ret ) : ret;
3102 },
3103 filter: function( selector ) {
3104 return this.pushStack( winnow( this, selector || [], false ) );
3105 },
3106 not: function( selector ) {
3107 return this.pushStack( winnow( this, selector || [], true ) );
3108 },
3109 is: function( selector ) {
3110 return !!winnow(
3111 this,
3112
3113 // If this is a positional/relative selector, check membership in the returned set
3114 // so $("p:first").is("p:last") won't return true for a doc with two "p".
3115 typeof selector === "string" && rneedsContext.test( selector ) ?
3116 jQuery( selector ) :
3117 selector || [],
3118 false
3119 ).length;
3120 }
3121 } );
3122
3123
3124 // Initialize a jQuery object
3125
3126
3127 // A central reference to the root jQuery(document)
3128 var rootjQuery,
3129
3130 // A simple way to check for HTML strings
3131 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
3132 // Strict HTML recognition (#11290: must start with <)
3133 // Shortcut simple #id case for speed
3134 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
3135
3136 init = jQuery.fn.init = function( selector, context, root ) {
3137 var match, elem;
3138
3139 // HANDLE: $(""), $(null), $(undefined), $(false)
3140 if ( !selector ) {
3141 return this;
3142 }
3143
3144 // Method init() accepts an alternate rootjQuery
3145 // so migrate can support jQuery.sub (gh-2101)
3146 root = root || rootjQuery;
3147
3148 // Handle HTML strings
3149 if ( typeof selector === "string" ) {
3150 if ( selector[ 0 ] === "<" &&
3151 selector[ selector.length - 1 ] === ">" &&
3152 selector.length >= 3 ) {
3153
3154 // Assume that strings that start and end with <> are HTML and skip the regex check
3155 match = [ null, selector, null ];
3156
3157 } else {
3158 match = rquickExpr.exec( selector );
3159 }
3160
3161 // Match html or make sure no context is specified for #id
3162 if ( match && ( match[ 1 ] || !context ) ) {
3163
3164 // HANDLE: $(html) -> $(array)
3165 if ( match[ 1 ] ) {
3166 context = context instanceof jQuery ? context[ 0 ] : context;
3167
3168 // Option to run scripts is true for back-compat
3169 // Intentionally let the error be thrown if parseHTML is not present
3170 jQuery.merge( this, jQuery.parseHTML(
3171 match[ 1 ],
3172 context && context.nodeType ? context.ownerDocument || context : document,
3173 true
3174 ) );
3175
3176 // HANDLE: $(html, props)
3177 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
3178 for ( match in context ) {
3179
3180 // Properties of context are called as methods if possible
3181 if ( isFunction( this[ match ] ) ) {
3182 this[ match ]( context[ match ] );
3183
3184 // ...and otherwise set as attributes
3185 } else {
3186 this.attr( match, context[ match ] );
3187 }
3188 }
3189 }
3190
3191 return this;
3192
3193 // HANDLE: $(#id)
3194 } else {
3195 elem = document.getElementById( match[ 2 ] );
3196
3197 if ( elem ) {
3198
3199 // Inject the element directly into the jQuery object
3200 this[ 0 ] = elem;
3201 this.length = 1;
3202 }
3203 return this;
3204 }
3205
3206 // HANDLE: $(expr, $(...))
3207 } else if ( !context || context.jquery ) {
3208 return ( context || root ).find( selector );
3209
3210 // HANDLE: $(expr, context)
3211 // (which is just equivalent to: $(context).find(expr)
3212 } else {
3213 return this.constructor( context ).find( selector );
3214 }
3215
3216 // HANDLE: $(DOMElement)
3217 } else if ( selector.nodeType ) {
3218 this[ 0 ] = selector;
3219 this.length = 1;
3220 return this;
3221
3222 // HANDLE: $(function)
3223 // Shortcut for document ready
3224 } else if ( isFunction( selector ) ) {
3225 return root.ready !== undefined ?
3226 root.ready( selector ) :
3227
3228 // Execute immediately if ready is not present
3229 selector( jQuery );
3230 }
3231
3232 return jQuery.makeArray( selector, this );
3233 };
3234
3235 // Give the init function the jQuery prototype for later instantiation
3236 init.prototype = jQuery.fn;
3237
3238 // Initialize central reference
3239 rootjQuery = jQuery( document );
3240
3241
3242 var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3243
3244 // Methods guaranteed to produce a unique set when starting from a unique set
3245 guaranteedUnique = {
3246 children: true,
3247 contents: true,
3248 next: true,
3249 prev: true
3250 };
3251
3252 jQuery.fn.extend( {
3253 has: function( target ) {
3254 var targets = jQuery( target, this ),
3255 l = targets.length;
3256
3257 return this.filter( function() {
3258 var i = 0;
3259 for ( ; i < l; i++ ) {
3260 if ( jQuery.contains( this, targets[ i ] ) ) {
3261 return true;
3262 }
3263 }
3264 } );
3265 },
3266
3267 closest: function( selectors, context ) {
3268 var cur,
3269 i = 0,
3270 l = this.length,
3271 matched = [],
3272 targets = typeof selectors !== "string" && jQuery( selectors );
3273
3274 // Positional selectors never match, since there's no _selection_ context
3275 if ( !rneedsContext.test( selectors ) ) {
3276 for ( ; i < l; i++ ) {
3277 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3278
3279 // Always skip document fragments
3280 if ( cur.nodeType < 11 && ( targets ?
3281 targets.index( cur ) > -1 :
3282
3283 // Don't pass non-elements to Sizzle
3284 cur.nodeType === 1 &&
3285 jQuery.find.matchesSelector( cur, selectors ) ) ) {
3286
3287 matched.push( cur );
3288 break;
3289 }
3290 }
3291 }
3292 }
3293
3294 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3295 },
3296
3297 // Determine the position of an element within the set
3298 index: function( elem ) {
3299
3300 // No argument, return index in parent
3301 if ( !elem ) {
3302 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3303 }
3304
3305 // Index in selector
3306 if ( typeof elem === "string" ) {
3307 return indexOf.call( jQuery( elem ), this[ 0 ] );
3308 }
3309
3310 // Locate the position of the desired element
3311 return indexOf.call( this,
3312
3313 // If it receives a jQuery object, the first element is used
3314 elem.jquery ? elem[ 0 ] : elem
3315 );
3316 },
3317
3318 add: function( selector, context ) {
3319 return this.pushStack(
3320 jQuery.uniqueSort(
3321 jQuery.merge( this.get(), jQuery( selector, context ) )
3322 )
3323 );
3324 },
3325
3326 addBack: function( selector ) {
3327 return this.add( selector == null ?
3328 this.prevObject : this.prevObject.filter( selector )
3329 );
3330 }
3331 } );
3332
3333 function sibling( cur, dir ) {
3334 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3335 return cur;
3336 }
3337
3338 jQuery.each( {
3339 parent: function( elem ) {
3340 var parent = elem.parentNode;
3341 return parent && parent.nodeType !== 11 ? parent : null;
3342 },
3343 parents: function( elem ) {
3344 return dir( elem, "parentNode" );
3345 },
3346 parentsUntil: function( elem, _i, until ) {
3347 return dir( elem, "parentNode", until );
3348 },
3349 next: function( elem ) {
3350 return sibling( elem, "nextSibling" );
3351 },
3352 prev: function( elem ) {
3353 return sibling( elem, "previousSibling" );
3354 },
3355 nextAll: function( elem ) {
3356 return dir( elem, "nextSibling" );
3357 },
3358 prevAll: function( elem ) {
3359 return dir( elem, "previousSibling" );
3360 },
3361 nextUntil: function( elem, _i, until ) {
3362 return dir( elem, "nextSibling", until );
3363 },
3364 prevUntil: function( elem, _i, until ) {
3365 return dir( elem, "previousSibling", until );
3366 },
3367 siblings: function( elem ) {
3368 return siblings( ( elem.parentNode || {} ).firstChild, elem );
3369 },
3370 children: function( elem ) {
3371 return siblings( elem.firstChild );
3372 },
3373 contents: function( elem ) {
3374 if ( elem.contentDocument != null &&
3375
3376 // Support: IE 11+
3377 // <object> elements with no `data` attribute has an object
3378 // `contentDocument` with a `null` prototype.
3379 getProto( elem.contentDocument ) ) {
3380
3381 return elem.contentDocument;
3382 }
3383
3384 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3385 // Treat the template element as a regular one in browsers that
3386 // don't support it.
3387 if ( nodeName( elem, "template" ) ) {
3388 elem = elem.content || elem;
3389 }
3390
3391 return jQuery.merge( [], elem.childNodes );
3392 }
3393 }, function( name, fn ) {
3394 jQuery.fn[ name ] = function( until, selector ) {
3395 var matched = jQuery.map( this, fn, until );
3396
3397 if ( name.slice( -5 ) !== "Until" ) {
3398 selector = until;
3399 }
3400
3401 if ( selector && typeof selector === "string" ) {
3402 matched = jQuery.filter( selector, matched );
3403 }
3404
3405 if ( this.length > 1 ) {
3406
3407 // Remove duplicates
3408 if ( !guaranteedUnique[ name ] ) {
3409 jQuery.uniqueSort( matched );
3410 }
3411
3412 // Reverse order for parents* and prev-derivatives
3413 if ( rparentsprev.test( name ) ) {
3414 matched.reverse();
3415 }
3416 }
3417
3418 return this.pushStack( matched );
3419 };
3420 } );
3421 var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
3422
3423
3424
3425 // Convert String-formatted options into Object-formatted ones
3426 function createOptions( options ) {
3427 var object = {};
3428 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
3429 object[ flag ] = true;
3430 } );
3431 return object;
3432 }
3433
3434 /*
3435 * Create a callback list using the following parameters:
3436 *
3437 * options: an optional list of space-separated options that will change how
3438 * the callback list behaves or a more traditional option object
3439 *
3440 * By default a callback list will act like an event callback list and can be
3441 * "fired" multiple times.
3442 *
3443 * Possible options:
3444 *
3445 * once: will ensure the callback list can only be fired once (like a Deferred)
3446 *
3447 * memory: will keep track of previous values and will call any callback added
3448 * after the list has been fired right away with the latest "memorized"
3449 * values (like a Deferred)
3450 *
3451 * unique: will ensure a callback can only be added once (no duplicate in the list)
3452 *
3453 * stopOnFalse: interrupt callings when a callback returns false
3454 *
3455 */
3456 jQuery.Callbacks = function( options ) {
3457
3458 // Convert options from String-formatted to Object-formatted if needed
3459 // (we check in cache first)
3460 options = typeof options === "string" ?
3461 createOptions( options ) :
3462 jQuery.extend( {}, options );
3463
3464 var // Flag to know if list is currently firing
3465 firing,
3466
3467 // Last fire value for non-forgettable lists
3468 memory,
3469
3470 // Flag to know if list was already fired
3471 fired,
3472
3473 // Flag to prevent firing
3474 locked,
3475
3476 // Actual callback list
3477 list = [],
3478
3479 // Queue of execution data for repeatable lists
3480 queue = [],
3481
3482 // Index of currently firing callback (modified by add/remove as needed)
3483 firingIndex = -1,
3484
3485 // Fire callbacks
3486 fire = function() {
3487
3488 // Enforce single-firing
3489 locked = locked || options.once;
3490
3491 // Execute callbacks for all pending executions,
3492 // respecting firingIndex overrides and runtime changes
3493 fired = firing = true;
3494 for ( ; queue.length; firingIndex = -1 ) {
3495 memory = queue.shift();
3496 while ( ++firingIndex < list.length ) {
3497
3498 // Run callback and check for early termination
3499 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3500 options.stopOnFalse ) {
3501
3502 // Jump to end and forget the data so .add doesn't re-fire
3503 firingIndex = list.length;
3504 memory = false;
3505 }
3506 }
3507 }
3508
3509 // Forget the data if we're done with it
3510 if ( !options.memory ) {
3511 memory = false;
3512 }
3513
3514 firing = false;
3515
3516 // Clean up if we're done firing for good
3517 if ( locked ) {
3518
3519 // Keep an empty list if we have data for future add calls
3520 if ( memory ) {
3521 list = [];
3522
3523 // Otherwise, this object is spent
3524 } else {
3525 list = "";
3526 }
3527 }
3528 },
3529
3530 // Actual Callbacks object
3531 self = {
3532
3533 // Add a callback or a collection of callbacks to the list
3534 add: function() {
3535 if ( list ) {
3536
3537 // If we have memory from a past run, we should fire after adding
3538 if ( memory && !firing ) {
3539 firingIndex = list.length - 1;
3540 queue.push( memory );
3541 }
3542
3543 ( function add( args ) {
3544 jQuery.each( args, function( _, arg ) {
3545 if ( isFunction( arg ) ) {
3546 if ( !options.unique || !self.has( arg ) ) {
3547 list.push( arg );
3548 }
3549 } else if ( arg && arg.length && toType( arg ) !== "string" ) {
3550
3551 // Inspect recursively
3552 add( arg );
3553 }
3554 } );
3555 } )( arguments );
3556
3557 if ( memory && !firing ) {
3558 fire();
3559 }
3560 }
3561 return this;
3562 },
3563
3564 // Remove a callback from the list
3565 remove: function() {
3566 jQuery.each( arguments, function( _, arg ) {
3567 var index;
3568 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3569 list.splice( index, 1 );
3570
3571 // Handle firing indexes
3572 if ( index <= firingIndex ) {
3573 firingIndex--;
3574 }
3575 }
3576 } );
3577 return this;
3578 },
3579
3580 // Check if a given callback is in the list.
3581 // If no argument is given, return whether or not list has callbacks attached.
3582 has: function( fn ) {
3583 return fn ?
3584 jQuery.inArray( fn, list ) > -1 :
3585 list.length > 0;
3586 },
3587
3588 // Remove all callbacks from the list
3589 empty: function() {
3590 if ( list ) {
3591 list = [];
3592 }
3593 return this;
3594 },
3595
3596 // Disable .fire and .add
3597 // Abort any current/pending executions
3598 // Clear all callbacks and values
3599 disable: function() {
3600 locked = queue = [];
3601 list = memory = "";
3602 return this;
3603 },
3604 disabled: function() {
3605 return !list;
3606 },
3607
3608 // Disable .fire
3609 // Also disable .add unless we have memory (since it would have no effect)
3610 // Abort any pending executions
3611 lock: function() {
3612 locked = queue = [];
3613 if ( !memory && !firing ) {
3614 list = memory = "";
3615 }
3616 return this;
3617 },
3618 locked: function() {
3619 return !!locked;
3620 },
3621
3622 // Call all callbacks with the given context and arguments
3623 fireWith: function( context, args ) {
3624 if ( !locked ) {
3625 args = args || [];
3626 args = [ context, args.slice ? args.slice() : args ];
3627 queue.push( args );
3628 if ( !firing ) {
3629 fire();
3630 }
3631 }
3632 return this;
3633 },
3634
3635 // Call all the callbacks with the given arguments
3636 fire: function() {
3637 self.fireWith( this, arguments );
3638 return this;
3639 },
3640
3641 // To know if the callbacks have already been called at least once
3642 fired: function() {
3643 return !!fired;
3644 }
3645 };
3646
3647 return self;
3648 };
3649
3650
3651 function Identity( v ) {
3652 return v;
3653 }
3654 function Thrower( ex ) {
3655 throw ex;
3656 }
3657
3658 function adoptValue( value, resolve, reject, noValue ) {
3659 var method;
3660
3661 try {
3662
3663 // Check for promise aspect first to privilege synchronous behavior
3664 if ( value && isFunction( ( method = value.promise ) ) ) {
3665 method.call( value ).done( resolve ).fail( reject );
3666
3667 // Other thenables
3668 } else if ( value && isFunction( ( method = value.then ) ) ) {
3669 method.call( value, resolve, reject );
3670
3671 // Other non-thenables
3672 } else {
3673
3674 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3675 // * false: [ value ].slice( 0 ) => resolve( value )
3676 // * true: [ value ].slice( 1 ) => resolve()
3677 resolve.apply( undefined, [ value ].slice( noValue ) );
3678 }
3679
3680 // For Promises/A+, convert exceptions into rejections
3681 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3682 // Deferred#then to conditionally suppress rejection.
3683 } catch ( value ) {
3684
3685 // Support: Android 4.0 only
3686 // Strict mode functions invoked without .call/.apply get global-object context
3687 reject.apply( undefined, [ value ] );
3688 }
3689 }
3690
3691 jQuery.extend( {
3692
3693 Deferred: function( func ) {
3694 var tuples = [
3695
3696 // action, add listener, callbacks,
3697 // ... .then handlers, argument index, [final state]
3698 [ "notify", "progress", jQuery.Callbacks( "memory" ),
3699 jQuery.Callbacks( "memory" ), 2 ],
3700 [ "resolve", "done", jQuery.Callbacks( "once memory" ),
3701 jQuery.Callbacks( "once memory" ), 0, "resolved" ],
3702 [ "reject", "fail", jQuery.Callbacks( "once memory" ),
3703 jQuery.Callbacks( "once memory" ), 1, "rejected" ]
3704 ],
3705 state = "pending",
3706 promise = {
3707 state: function() {
3708 return state;
3709 },
3710 always: function() {
3711 deferred.done( arguments ).fail( arguments );
3712 return this;
3713 },
3714 "catch": function( fn ) {
3715 return promise.then( null, fn );
3716 },
3717
3718 // Keep pipe for back-compat
3719 pipe: function( /* fnDone, fnFail, fnProgress */ ) {
3720 var fns = arguments;
3721
3722 return jQuery.Deferred( function( newDefer ) {
3723 jQuery.each( tuples, function( _i, tuple ) {
3724
3725 // Map tuples (progress, done, fail) to arguments (done, fail, progress)
3726 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
3727
3728 // deferred.progress(function() { bind to newDefer or newDefer.notify })
3729 // deferred.done(function() { bind to newDefer or newDefer.resolve })
3730 // deferred.fail(function() { bind to newDefer or newDefer.reject })
3731 deferred[ tuple[ 1 ] ]( function() {
3732 var returned = fn && fn.apply( this, arguments );
3733 if ( returned && isFunction( returned.promise ) ) {
3734 returned.promise()
3735 .progress( newDefer.notify )
3736 .done( newDefer.resolve )
3737 .fail( newDefer.reject );
3738 } else {
3739 newDefer[ tuple[ 0 ] + "With" ](
3740 this,
3741 fn ? [ returned ] : arguments
3742 );
3743 }
3744 } );
3745 } );
3746 fns = null;
3747 } ).promise();
3748 },
3749 then: function( onFulfilled, onRejected, onProgress ) {
3750 var maxDepth = 0;
3751 function resolve( depth, deferred, handler, special ) {
3752 return function() {
3753 var that = this,
3754 args = arguments,
3755 mightThrow = function() {
3756 var returned, then;
3757
3758 // Support: Promises/A+ section 2.3.3.3.3
3759 // https://promisesaplus.com/#point-59
3760 // Ignore double-resolution attempts
3761 if ( depth < maxDepth ) {
3762 return;
3763 }
3764
3765 returned = handler.apply( that, args );
3766
3767 // Support: Promises/A+ section 2.3.1
3768 // https://promisesaplus.com/#point-48
3769 if ( returned === deferred.promise() ) {
3770 throw new TypeError( "Thenable self-resolution" );
3771 }
3772
3773 // Support: Promises/A+ sections 2.3.3.1, 3.5
3774 // https://promisesaplus.com/#point-54
3775 // https://promisesaplus.com/#point-75
3776 // Retrieve `then` only once
3777 then = returned &&
3778
3779 // Support: Promises/A+ section 2.3.4
3780 // https://promisesaplus.com/#point-64
3781 // Only check objects and functions for thenability
3782 ( typeof returned === "object" ||
3783 typeof returned === "function" ) &&
3784 returned.then;
3785
3786 // Handle a returned thenable
3787 if ( isFunction( then ) ) {
3788
3789 // Special processors (notify) just wait for resolution
3790 if ( special ) {
3791 then.call(
3792 returned,
3793 resolve( maxDepth, deferred, Identity, special ),
3794 resolve( maxDepth, deferred, Thrower, special )
3795 );
3796
3797 // Normal processors (resolve) also hook into progress
3798 } else {
3799
3800 // ...and disregard older resolution values
3801 maxDepth++;
3802
3803 then.call(
3804 returned,
3805 resolve( maxDepth, deferred, Identity, special ),
3806 resolve( maxDepth, deferred, Thrower, special ),
3807 resolve( maxDepth, deferred, Identity,
3808 deferred.notifyWith )
3809 );
3810 }
3811
3812 // Handle all other returned values
3813 } else {
3814
3815 // Only substitute handlers pass on context
3816 // and multiple values (non-spec behavior)
3817 if ( handler !== Identity ) {
3818 that = undefined;
3819 args = [ returned ];
3820 }
3821
3822 // Process the value(s)
3823 // Default process is resolve
3824 ( special || deferred.resolveWith )( that, args );
3825 }
3826 },
3827
3828 // Only normal processors (resolve) catch and reject exceptions
3829 process = special ?
3830 mightThrow :
3831 function() {
3832 try {
3833 mightThrow();
3834 } catch ( e ) {
3835
3836 if ( jQuery.Deferred.exceptionHook ) {
3837 jQuery.Deferred.exceptionHook( e,
3838 process.stackTrace );
3839 }
3840
3841 // Support: Promises/A+ section 2.3.3.3.4.1
3842 // https://promisesaplus.com/#point-61
3843 // Ignore post-resolution exceptions
3844 if ( depth + 1 >= maxDepth ) {
3845
3846 // Only substitute handlers pass on context
3847 // and multiple values (non-spec behavior)
3848 if ( handler !== Thrower ) {
3849 that = undefined;
3850 args = [ e ];
3851 }
3852
3853 deferred.rejectWith( that, args );
3854 }
3855 }
3856 };
3857
3858 // Support: Promises/A+ section 2.3.3.3.1
3859 // https://promisesaplus.com/#point-57
3860 // Re-resolve promises immediately to dodge false rejection from
3861 // subsequent errors
3862 if ( depth ) {
3863 process();
3864 } else {
3865
3866 // Call an optional hook to record the stack, in case of exception
3867 // since it's otherwise lost when execution goes async
3868 if ( jQuery.Deferred.getStackHook ) {
3869 process.stackTrace = jQuery.Deferred.getStackHook();
3870 }
3871 window.setTimeout( process );
3872 }
3873 };
3874 }
3875
3876 return jQuery.Deferred( function( newDefer ) {
3877
3878 // progress_handlers.add( ... )
3879 tuples[ 0 ][ 3 ].add(
3880 resolve(
3881 0,
3882 newDefer,
3883 isFunction( onProgress ) ?
3884 onProgress :
3885 Identity,
3886 newDefer.notifyWith
3887 )
3888 );
3889
3890 // fulfilled_handlers.add( ... )
3891 tuples[ 1 ][ 3 ].add(
3892 resolve(
3893 0,
3894 newDefer,
3895 isFunction( onFulfilled ) ?
3896 onFulfilled :
3897 Identity
3898 )
3899 );
3900
3901 // rejected_handlers.add( ... )
3902 tuples[ 2 ][ 3 ].add(
3903 resolve(
3904 0,
3905 newDefer,
3906 isFunction( onRejected ) ?
3907 onRejected :
3908 Thrower
3909 )
3910 );
3911 } ).promise();
3912 },
3913
3914 // Get a promise for this deferred
3915 // If obj is provided, the promise aspect is added to the object
3916 promise: function( obj ) {
3917 return obj != null ? jQuery.extend( obj, promise ) : promise;
3918 }
3919 },
3920 deferred = {};
3921
3922 // Add list-specific methods
3923 jQuery.each( tuples, function( i, tuple ) {
3924 var list = tuple[ 2 ],
3925 stateString = tuple[ 5 ];
3926
3927 // promise.progress = list.add
3928 // promise.done = list.add
3929 // promise.fail = list.add
3930 promise[ tuple[ 1 ] ] = list.add;
3931
3932 // Handle state
3933 if ( stateString ) {
3934 list.add(
3935 function() {
3936
3937 // state = "resolved" (i.e., fulfilled)
3938 // state = "rejected"
3939 state = stateString;
3940 },
3941
3942 // rejected_callbacks.disable
3943 // fulfilled_callbacks.disable
3944 tuples[ 3 - i ][ 2 ].disable,
3945
3946 // rejected_handlers.disable
3947 // fulfilled_handlers.disable
3948 tuples[ 3 - i ][ 3 ].disable,
3949
3950 // progress_callbacks.lock
3951 tuples[ 0 ][ 2 ].lock,
3952
3953 // progress_handlers.lock
3954 tuples[ 0 ][ 3 ].lock
3955 );
3956 }
3957
3958 // progress_handlers.fire
3959 // fulfilled_handlers.fire
3960 // rejected_handlers.fire
3961 list.add( tuple[ 3 ].fire );
3962
3963 // deferred.notify = function() { deferred.notifyWith(...) }
3964 // deferred.resolve = function() { deferred.resolveWith(...) }
3965 // deferred.reject = function() { deferred.rejectWith(...) }
3966 deferred[ tuple[ 0 ] ] = function() {
3967 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
3968 return this;
3969 };
3970
3971 // deferred.notifyWith = list.fireWith
3972 // deferred.resolveWith = list.fireWith
3973 // deferred.rejectWith = list.fireWith
3974 deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3975 } );
3976
3977 // Make the deferred a promise
3978 promise.promise( deferred );
3979
3980 // Call given func if any
3981 if ( func ) {
3982 func.call( deferred, deferred );
3983 }
3984
3985 // All done!
3986 return deferred;
3987 },
3988
3989 // Deferred helper
3990 when: function( singleValue ) {
3991 var
3992
3993 // count of uncompleted subordinates
3994 remaining = arguments.length,
3995
3996 // count of unprocessed arguments
3997 i = remaining,
3998
3999 // subordinate fulfillment data
4000 resolveContexts = Array( i ),
4001 resolveValues = slice.call( arguments ),
4002
4003 // the primary Deferred
4004 primary = jQuery.Deferred(),
4005
4006 // subordinate callback factory
4007 updateFunc = function( i ) {
4008 return function( value ) {
4009 resolveContexts[ i ] = this;
4010 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
4011 if ( !( --remaining ) ) {
4012 primary.resolveWith( resolveContexts, resolveValues );
4013 }
4014 };
4015 };
4016
4017 // Single- and empty arguments are adopted like Promise.resolve
4018 if ( remaining <= 1 ) {
4019 adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
4020 !remaining );
4021
4022 // Use .then() to unwrap secondary thenables (cf. gh-3000)
4023 if ( primary.state() === "pending" ||
4024 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
4025
4026 return primary.then();
4027 }
4028 }
4029
4030 // Multiple arguments are aggregated like Promise.all array elements
4031 while ( i-- ) {
4032 adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
4033 }
4034
4035 return primary.promise();
4036 }
4037 } );
4038
4039
4040 // These usually indicate a programmer mistake during development,
4041 // warn about them ASAP rather than swallowing them by default.
4042 var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
4043
4044 jQuery.Deferred.exceptionHook = function( error, stack ) {
4045
4046 // Support: IE 8 - 9 only
4047 // Console exists when dev tools are open, which can happen at any time
4048 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
4049 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
4050 }
4051 };
4052
4053
4054
4055
4056 jQuery.readyException = function( error ) {
4057 window.setTimeout( function() {
4058 throw error;
4059 } );
4060 };
4061
4062
4063
4064
4065 // The deferred used on DOM ready
4066 var readyList = jQuery.Deferred();
4067
4068 jQuery.fn.ready = function( fn ) {
4069
4070 readyList
4071 .then( fn )
4072
4073 // Wrap jQuery.readyException in a function so that the lookup
4074 // happens at the time of error handling instead of callback
4075 // registration.
4076 .catch( function( error ) {
4077 jQuery.readyException( error );
4078 } );
4079
4080 return this;
4081 };
4082
4083 jQuery.extend( {
4084
4085 // Is the DOM ready to be used? Set to true once it occurs.
4086 isReady: false,
4087
4088 // A counter to track how many items to wait for before
4089 // the ready event fires. See #6781
4090 readyWait: 1,
4091
4092 // Handle when the DOM is ready
4093 ready: function( wait ) {
4094
4095 // Abort if there are pending holds or we're already ready
4096 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
4097 return;
4098 }
4099
4100 // Remember that the DOM is ready
4101 jQuery.isReady = true;
4102
4103 // If a normal DOM Ready event fired, decrement, and wait if need be
4104 if ( wait !== true && --jQuery.readyWait > 0 ) {
4105 return;
4106 }
4107
4108 // If there are functions bound, to execute
4109 readyList.resolveWith( document, [ jQuery ] );
4110 }
4111 } );
4112
4113 jQuery.ready.then = readyList.then;
4114
4115 // The ready event handler and self cleanup method
4116 function completed() {
4117 document.removeEventListener( "DOMContentLoaded", completed );
4118 window.removeEventListener( "load", completed );
4119 jQuery.ready();
4120 }
4121
4122 // Catch cases where $(document).ready() is called
4123 // after the browser event has already occurred.
4124 // Support: IE <=9 - 10 only
4125 // Older IE sometimes signals "interactive" too soon
4126 if ( document.readyState === "complete" ||
4127 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
4128
4129 // Handle it asynchronously to allow scripts the opportunity to delay ready
4130 window.setTimeout( jQuery.ready );
4131
4132 } else {
4133
4134 // Use the handy event callback
4135 document.addEventListener( "DOMContentLoaded", completed );
4136
4137 // A fallback to window.onload, that will always work
4138 window.addEventListener( "load", completed );
4139 }
4140
4141
4142
4143
4144 // Multifunctional method to get and set values of a collection
4145 // The value/s can optionally be executed if it's a function
4146 var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4147 var i = 0,
4148 len = elems.length,
4149 bulk = key == null;
4150
4151 // Sets many values
4152 if ( toType( key ) === "object" ) {
4153 chainable = true;
4154 for ( i in key ) {
4155 access( elems, fn, i, key[ i ], true, emptyGet, raw );
4156 }
4157
4158 // Sets one value
4159 } else if ( value !== undefined ) {
4160 chainable = true;
4161
4162 if ( !isFunction( value ) ) {
4163 raw = true;
4164 }
4165
4166 if ( bulk ) {
4167
4168 // Bulk operations run against the entire set
4169 if ( raw ) {
4170 fn.call( elems, value );
4171 fn = null;
4172
4173 // ...except when executing function values
4174 } else {
4175 bulk = fn;
4176 fn = function( elem, _key, value ) {
4177 return bulk.call( jQuery( elem ), value );
4178 };
4179 }
4180 }
4181
4182 if ( fn ) {
4183 for ( ; i < len; i++ ) {
4184 fn(
4185 elems[ i ], key, raw ?
4186 value :
4187 value.call( elems[ i ], i, fn( elems[ i ], key ) )
4188 );
4189 }
4190 }
4191 }
4192
4193 if ( chainable ) {
4194 return elems;
4195 }
4196
4197 // Gets
4198 if ( bulk ) {
4199 return fn.call( elems );
4200 }
4201
4202 return len ? fn( elems[ 0 ], key ) : emptyGet;
4203 };
4204
4205
4206 // Matches dashed string for camelizing
4207 var rmsPrefix = /^-ms-/,
4208 rdashAlpha = /-([a-z])/g;
4209
4210 // Used by camelCase as callback to replace()
4211 function fcamelCase( _all, letter ) {
4212 return letter.toUpperCase();
4213 }
4214
4215 // Convert dashed to camelCase; used by the css and data modules
4216 // Support: IE <=9 - 11, Edge 12 - 15
4217 // Microsoft forgot to hump their vendor prefix (#9572)
4218 function camelCase( string ) {
4219 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
4220 }
4221 var acceptData = function( owner ) {
4222
4223 // Accepts only:
4224 // - Node
4225 // - Node.ELEMENT_NODE
4226 // - Node.DOCUMENT_NODE
4227 // - Object
4228 // - Any
4229 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
4230 };
4231
4232
4233
4234
4235 function Data() {
4236 this.expando = jQuery.expando + Data.uid++;
4237 }
4238
4239 Data.uid = 1;
4240
4241 Data.prototype = {
4242
4243 cache: function( owner ) {
4244
4245 // Check if the owner object already has a cache
4246 var value = owner[ this.expando ];
4247
4248 // If not, create one
4249 if ( !value ) {
4250 value = {};
4251
4252 // We can accept data for non-element nodes in modern browsers,
4253 // but we should not, see #8335.
4254 // Always return an empty object.
4255 if ( acceptData( owner ) ) {
4256
4257 // If it is a node unlikely to be stringify-ed or looped over
4258 // use plain assignment
4259 if ( owner.nodeType ) {
4260 owner[ this.expando ] = value;
4261
4262 // Otherwise secure it in a non-enumerable property
4263 // configurable must be true to allow the property to be
4264 // deleted when data is removed
4265 } else {
4266 Object.defineProperty( owner, this.expando, {
4267 value: value,
4268 configurable: true
4269 } );
4270 }
4271 }
4272 }
4273
4274 return value;
4275 },
4276 set: function( owner, data, value ) {
4277 var prop,
4278 cache = this.cache( owner );
4279
4280 // Handle: [ owner, key, value ] args
4281 // Always use camelCase key (gh-2257)
4282 if ( typeof data === "string" ) {
4283 cache[ camelCase( data ) ] = value;
4284
4285 // Handle: [ owner, { properties } ] args
4286 } else {
4287
4288 // Copy the properties one-by-one to the cache object
4289 for ( prop in data ) {
4290 cache[ camelCase( prop ) ] = data[ prop ];
4291 }
4292 }
4293 return cache;
4294 },
4295 get: function( owner, key ) {
4296 return key === undefined ?
4297 this.cache( owner ) :
4298
4299 // Always use camelCase key (gh-2257)
4300 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
4301 },
4302 access: function( owner, key, value ) {
4303
4304 // In cases where either:
4305 //
4306 // 1. No key was specified
4307 // 2. A string key was specified, but no value provided
4308 //
4309 // Take the "read" path and allow the get method to determine
4310 // which value to return, respectively either:
4311 //
4312 // 1. The entire cache object
4313 // 2. The data stored at the key
4314 //
4315 if ( key === undefined ||
4316 ( ( key && typeof key === "string" ) && value === undefined ) ) {
4317
4318 return this.get( owner, key );
4319 }
4320
4321 // When the key is not a string, or both a key and value
4322 // are specified, set or extend (existing objects) with either:
4323 //
4324 // 1. An object of properties
4325 // 2. A key and value
4326 //
4327 this.set( owner, key, value );
4328
4329 // Since the "set" path can have two possible entry points
4330 // return the expected data based on which path was taken[*]
4331 return value !== undefined ? value : key;
4332 },
4333 remove: function( owner, key ) {
4334 var i,
4335 cache = owner[ this.expando ];
4336
4337 if ( cache === undefined ) {
4338 return;
4339 }
4340
4341 if ( key !== undefined ) {
4342
4343 // Support array or space separated string of keys
4344 if ( Array.isArray( key ) ) {
4345
4346 // If key is an array of keys...
4347 // We always set camelCase keys, so remove that.
4348 key = key.map( camelCase );
4349 } else {
4350 key = camelCase( key );
4351
4352 // If a key with the spaces exists, use it.
4353 // Otherwise, create an array by matching non-whitespace
4354 key = key in cache ?
4355 [ key ] :
4356 ( key.match( rnothtmlwhite ) || [] );
4357 }
4358
4359 i = key.length;
4360
4361 while ( i-- ) {
4362 delete cache[ key[ i ] ];
4363 }
4364 }
4365
4366 // Remove the expando if there's no more data
4367 if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4368
4369 // Support: Chrome <=35 - 45
4370 // Webkit & Blink performance suffers when deleting properties
4371 // from DOM nodes, so set to undefined instead
4372 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4373 if ( owner.nodeType ) {
4374 owner[ this.expando ] = undefined;
4375 } else {
4376 delete owner[ this.expando ];
4377 }
4378 }
4379 },
4380 hasData: function( owner ) {
4381 var cache = owner[ this.expando ];
4382 return cache !== undefined && !jQuery.isEmptyObject( cache );
4383 }
4384 };
4385 var dataPriv = new Data();
4386
4387 var dataUser = new Data();
4388
4389
4390
4391 // Implementation Summary
4392 //
4393 // 1. Enforce API surface and semantic compatibility with 1.9.x branch
4394 // 2. Improve the module's maintainability by reducing the storage
4395 // paths to a single mechanism.
4396 // 3. Use the same single mechanism to support "private" and "user" data.
4397 // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4398 // 5. Avoid exposing implementation details on user objects (eg. expando properties)
4399 // 6. Provide a clear path for implementation upgrade to WeakMap in 2014
4400
4401 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4402 rmultiDash = /[A-Z]/g;
4403
4404 function getData( data ) {
4405 if ( data === "true" ) {
4406 return true;
4407 }
4408
4409 if ( data === "false" ) {
4410 return false;
4411 }
4412
4413 if ( data === "null" ) {
4414 return null;
4415 }
4416
4417 // Only convert to a number if it doesn't change the string
4418 if ( data === +data + "" ) {
4419 return +data;
4420 }
4421
4422 if ( rbrace.test( data ) ) {
4423 return JSON.parse( data );
4424 }
4425
4426 return data;
4427 }
4428
4429 function dataAttr( elem, key, data ) {
4430 var name;
4431
4432 // If nothing was found internally, try to fetch any
4433 // data from the HTML5 data-* attribute
4434 if ( data === undefined && elem.nodeType === 1 ) {
4435 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
4436 data = elem.getAttribute( name );
4437
4438 if ( typeof data === "string" ) {
4439 try {
4440 data = getData( data );
4441 } catch ( e ) {}
4442
4443 // Make sure we set the data so it isn't changed later
4444 dataUser.set( elem, key, data );
4445 } else {
4446 data = undefined;
4447 }
4448 }
4449 return data;
4450 }
4451
4452 jQuery.extend( {
4453 hasData: function( elem ) {
4454 return dataUser.hasData( elem ) || dataPriv.hasData( elem );
4455 },
4456
4457 data: function( elem, name, data ) {
4458 return dataUser.access( elem, name, data );
4459 },
4460
4461 removeData: function( elem, name ) {
4462 dataUser.remove( elem, name );
4463 },
4464
4465 // TODO: Now that all calls to _data and _removeData have been replaced
4466 // with direct calls to dataPriv methods, these can be deprecated.
4467 _data: function( elem, name, data ) {
4468 return dataPriv.access( elem, name, data );
4469 },
4470
4471 _removeData: function( elem, name ) {
4472 dataPriv.remove( elem, name );
4473 }
4474 } );
4475
4476 jQuery.fn.extend( {
4477 data: function( key, value ) {
4478 var i, name, data,
4479 elem = this[ 0 ],
4480 attrs = elem && elem.attributes;
4481
4482 // Gets all values
4483 if ( key === undefined ) {
4484 if ( this.length ) {
4485 data = dataUser.get( elem );
4486
4487 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
4488 i = attrs.length;
4489 while ( i-- ) {
4490
4491 // Support: IE 11 only
4492 // The attrs elements can be null (#14894)
4493 if ( attrs[ i ] ) {
4494 name = attrs[ i ].name;
4495 if ( name.indexOf( "data-" ) === 0 ) {
4496 name = camelCase( name.slice( 5 ) );
4497 dataAttr( elem, name, data[ name ] );
4498 }
4499 }
4500 }
4501 dataPriv.set( elem, "hasDataAttrs", true );
4502 }
4503 }
4504
4505 return data;
4506 }
4507
4508 // Sets multiple values
4509 if ( typeof key === "object" ) {
4510 return this.each( function() {
4511 dataUser.set( this, key );
4512 } );
4513 }
4514
4515 return access( this, function( value ) {
4516 var data;
4517
4518 // The calling jQuery object (element matches) is not empty
4519 // (and therefore has an element appears at this[ 0 ]) and the
4520 // `value` parameter was not undefined. An empty jQuery object
4521 // will result in `undefined` for elem = this[ 0 ] which will
4522 // throw an exception if an attempt to read a data cache is made.
4523 if ( elem && value === undefined ) {
4524
4525 // Attempt to get data from the cache
4526 // The key will always be camelCased in Data
4527 data = dataUser.get( elem, key );
4528 if ( data !== undefined ) {
4529 return data;
4530 }
4531
4532 // Attempt to "discover" the data in
4533 // HTML5 custom data-* attrs
4534 data = dataAttr( elem, key );
4535 if ( data !== undefined ) {
4536 return data;
4537 }
4538
4539 // We tried really hard, but the data doesn't exist.
4540 return;
4541 }
4542
4543 // Set the data...
4544 this.each( function() {
4545
4546 // We always store the camelCased key
4547 dataUser.set( this, key, value );
4548 } );
4549 }, null, value, arguments.length > 1, null, true );
4550 },
4551
4552 removeData: function( key ) {
4553 return this.each( function() {
4554 dataUser.remove( this, key );
4555 } );
4556 }
4557 } );
4558
4559
4560 jQuery.extend( {
4561 queue: function( elem, type, data ) {
4562 var queue;
4563
4564 if ( elem ) {
4565 type = ( type || "fx" ) + "queue";
4566 queue = dataPriv.get( elem, type );
4567
4568 // Speed up dequeue by getting out quickly if this is just a lookup
4569 if ( data ) {
4570 if ( !queue || Array.isArray( data ) ) {
4571 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4572 } else {
4573 queue.push( data );
4574 }
4575 }
4576 return queue || [];
4577 }
4578 },
4579
4580 dequeue: function( elem, type ) {
4581 type = type || "fx";
4582
4583 var queue = jQuery.queue( elem, type ),
4584 startLength = queue.length,
4585 fn = queue.shift(),
4586 hooks = jQuery._queueHooks( elem, type ),
4587 next = function() {
4588 jQuery.dequeue( elem, type );
4589 };
4590
4591 // If the fx queue is dequeued, always remove the progress sentinel
4592 if ( fn === "inprogress" ) {
4593 fn = queue.shift();
4594 startLength--;
4595 }
4596
4597 if ( fn ) {
4598
4599 // Add a progress sentinel to prevent the fx queue from being
4600 // automatically dequeued
4601 if ( type === "fx" ) {
4602 queue.unshift( "inprogress" );
4603 }
4604
4605 // Clear up the last queue stop function
4606 delete hooks.stop;
4607 fn.call( elem, next, hooks );
4608 }
4609
4610 if ( !startLength && hooks ) {
4611 hooks.empty.fire();
4612 }
4613 },
4614
4615 // Not public - generate a queueHooks object, or return the current one
4616 _queueHooks: function( elem, type ) {
4617 var key = type + "queueHooks";
4618 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4619 empty: jQuery.Callbacks( "once memory" ).add( function() {
4620 dataPriv.remove( elem, [ type + "queue", key ] );
4621 } )
4622 } );
4623 }
4624 } );
4625
4626 jQuery.fn.extend( {
4627 queue: function( type, data ) {
4628 var setter = 2;
4629
4630 if ( typeof type !== "string" ) {
4631 data = type;
4632 type = "fx";
4633 setter--;
4634 }
4635
4636 if ( arguments.length < setter ) {
4637 return jQuery.queue( this[ 0 ], type );
4638 }
4639
4640 return data === undefined ?
4641 this :
4642 this.each( function() {
4643 var queue = jQuery.queue( this, type, data );
4644
4645 // Ensure a hooks for this queue
4646 jQuery._queueHooks( this, type );
4647
4648 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4649 jQuery.dequeue( this, type );
4650 }
4651 } );
4652 },
4653 dequeue: function( type ) {
4654 return this.each( function() {
4655 jQuery.dequeue( this, type );
4656 } );
4657 },
4658 clearQueue: function( type ) {
4659 return this.queue( type || "fx", [] );
4660 },
4661
4662 // Get a promise resolved when queues of a certain type
4663 // are emptied (fx is the type by default)
4664 promise: function( type, obj ) {
4665 var tmp,
4666 count = 1,
4667 defer = jQuery.Deferred(),
4668 elements = this,
4669 i = this.length,
4670 resolve = function() {
4671 if ( !( --count ) ) {
4672 defer.resolveWith( elements, [ elements ] );
4673 }
4674 };
4675
4676 if ( typeof type !== "string" ) {
4677 obj = type;
4678 type = undefined;
4679 }
4680 type = type || "fx";
4681
4682 while ( i-- ) {
4683 tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4684 if ( tmp && tmp.empty ) {
4685 count++;
4686 tmp.empty.add( resolve );
4687 }
4688 }
4689 resolve();
4690 return defer.promise( obj );
4691 }
4692 } );
4693 var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4694
4695 var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4696
4697
4698 var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4699
4700 var documentElement = document.documentElement;
4701
4702
4703
4704 var isAttached = function( elem ) {
4705 return jQuery.contains( elem.ownerDocument, elem );
4706 },
4707 composed = { composed: true };
4708
4709 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
4710 // Check attachment across shadow DOM boundaries when possible (gh-3504)
4711 // Support: iOS 10.0-10.2 only
4712 // Early iOS 10 versions support `attachShadow` but not `getRootNode`,
4713 // leading to errors. We need to check for `getRootNode`.
4714 if ( documentElement.getRootNode ) {
4715 isAttached = function( elem ) {
4716 return jQuery.contains( elem.ownerDocument, elem ) ||
4717 elem.getRootNode( composed ) === elem.ownerDocument;
4718 };
4719 }
4720 var isHiddenWithinTree = function( elem, el ) {
4721
4722 // isHiddenWithinTree might be called from jQuery#filter function;
4723 // in that case, element will be second argument
4724 elem = el || elem;
4725
4726 // Inline style trumps all
4727 return elem.style.display === "none" ||
4728 elem.style.display === "" &&
4729
4730 // Otherwise, check computed style
4731 // Support: Firefox <=43 - 45
4732 // Disconnected elements can have computed display: none, so first confirm that elem is
4733 // in the document.
4734 isAttached( elem ) &&
4735
4736 jQuery.css( elem, "display" ) === "none";
4737 };
4738
4739
4740
4741 function adjustCSS( elem, prop, valueParts, tween ) {
4742 var adjusted, scale,
4743 maxIterations = 20,
4744 currentValue = tween ?
4745 function() {
4746 return tween.cur();
4747 } :
4748 function() {
4749 return jQuery.css( elem, prop, "" );
4750 },
4751 initial = currentValue(),
4752 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4753
4754 // Starting value computation is required for potential unit mismatches
4755 initialInUnit = elem.nodeType &&
4756 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4757 rcssNum.exec( jQuery.css( elem, prop ) );
4758
4759 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4760
4761 // Support: Firefox <=54
4762 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
4763 initial = initial / 2;
4764
4765 // Trust units reported by jQuery.css
4766 unit = unit || initialInUnit[ 3 ];
4767
4768 // Iteratively approximate from a nonzero starting point
4769 initialInUnit = +initial || 1;
4770
4771 while ( maxIterations-- ) {
4772
4773 // Evaluate and update our best guess (doubling guesses that zero out).
4774 // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
4775 jQuery.style( elem, prop, initialInUnit + unit );
4776 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
4777 maxIterations = 0;
4778 }
4779 initialInUnit = initialInUnit / scale;
4780
4781 }
4782
4783 initialInUnit = initialInUnit * 2;
4784 jQuery.style( elem, prop, initialInUnit + unit );
4785
4786 // Make sure we update the tween properties later on
4787 valueParts = valueParts || [];
4788 }
4789
4790 if ( valueParts ) {
4791 initialInUnit = +initialInUnit || +initial || 0;
4792
4793 // Apply relative offset (+=/-=) if specified
4794 adjusted = valueParts[ 1 ] ?
4795 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4796 +valueParts[ 2 ];
4797 if ( tween ) {
4798 tween.unit = unit;
4799 tween.start = initialInUnit;
4800 tween.end = adjusted;
4801 }
4802 }
4803 return adjusted;
4804 }
4805
4806
4807 var defaultDisplayMap = {};
4808
4809 function getDefaultDisplay( elem ) {
4810 var temp,
4811 doc = elem.ownerDocument,
4812 nodeName = elem.nodeName,
4813 display = defaultDisplayMap[ nodeName ];
4814
4815 if ( display ) {
4816 return display;
4817 }
4818
4819 temp = doc.body.appendChild( doc.createElement( nodeName ) );
4820 display = jQuery.css( temp, "display" );
4821
4822 temp.parentNode.removeChild( temp );
4823
4824 if ( display === "none" ) {
4825 display = "block";
4826 }
4827 defaultDisplayMap[ nodeName ] = display;
4828
4829 return display;
4830 }
4831
4832 function showHide( elements, show ) {
4833 var display, elem,
4834 values = [],
4835 index = 0,
4836 length = elements.length;
4837
4838 // Determine new display value for elements that need to change
4839 for ( ; index < length; index++ ) {
4840 elem = elements[ index ];
4841 if ( !elem.style ) {
4842 continue;
4843 }
4844
4845 display = elem.style.display;
4846 if ( show ) {
4847
4848 // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4849 // check is required in this first loop unless we have a nonempty display value (either
4850 // inline or about-to-be-restored)
4851 if ( display === "none" ) {
4852 values[ index ] = dataPriv.get( elem, "display" ) || null;
4853 if ( !values[ index ] ) {
4854 elem.style.display = "";
4855 }
4856 }
4857 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
4858 values[ index ] = getDefaultDisplay( elem );
4859 }
4860 } else {
4861 if ( display !== "none" ) {
4862 values[ index ] = "none";
4863
4864 // Remember what we're overwriting
4865 dataPriv.set( elem, "display", display );
4866 }
4867 }
4868 }
4869
4870 // Set the display of the elements in a second loop to avoid constant reflow
4871 for ( index = 0; index < length; index++ ) {
4872 if ( values[ index ] != null ) {
4873 elements[ index ].style.display = values[ index ];
4874 }
4875 }
4876
4877 return elements;
4878 }
4879
4880 jQuery.fn.extend( {
4881 show: function() {
4882 return showHide( this, true );
4883 },
4884 hide: function() {
4885 return showHide( this );
4886 },
4887 toggle: function( state ) {
4888 if ( typeof state === "boolean" ) {
4889 return state ? this.show() : this.hide();
4890 }
4891
4892 return this.each( function() {
4893 if ( isHiddenWithinTree( this ) ) {
4894 jQuery( this ).show();
4895 } else {
4896 jQuery( this ).hide();
4897 }
4898 } );
4899 }
4900 } );
4901 var rcheckableType = ( /^(?:checkbox|radio)$/i );
4902
4903 var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
4904
4905 var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
4906
4907
4908
4909 ( function() {
4910 var fragment = document.createDocumentFragment(),
4911 div = fragment.appendChild( document.createElement( "div" ) ),
4912 input = document.createElement( "input" );
4913
4914 // Support: Android 4.0 - 4.3 only
4915 // Check state lost if the name is set (#11217)
4916 // Support: Windows Web Apps (WWA)
4917 // `name` and `type` must use .setAttribute for WWA (#14901)
4918 input.setAttribute( "type", "radio" );
4919 input.setAttribute( "checked", "checked" );
4920 input.setAttribute( "name", "t" );
4921
4922 div.appendChild( input );
4923
4924 // Support: Android <=4.1 only
4925 // Older WebKit doesn't clone checked state correctly in fragments
4926 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4927
4928 // Support: IE <=11 only
4929 // Make sure textarea (and checkbox) defaultValue is properly cloned
4930 div.innerHTML = "<textarea>x</textarea>";
4931 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4932
4933 // Support: IE <=9 only
4934 // IE <=9 replaces <option> tags with their contents when inserted outside of
4935 // the select element.
4936 div.innerHTML = "<option></option>";
4937 support.option = !!div.lastChild;
4938 } )();
4939
4940
4941 // We have to close these tags to support XHTML (#13200)
4942 var wrapMap = {
4943
4944 // XHTML parsers do not magically insert elements in the
4945 // same way that tag soup parsers do. So we cannot shorten
4946 // this by omitting <tbody> or other required elements.
4947 thead: [ 1, "<table>", "</table>" ],
4948 col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4949 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4950 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4951
4952 _default: [ 0, "", "" ]
4953 };
4954
4955 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4956 wrapMap.th = wrapMap.td;
4957
4958 // Support: IE <=9 only
4959 if ( !support.option ) {
4960 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
4961 }
4962
4963
4964 function getAll( context, tag ) {
4965
4966 // Support: IE <=9 - 11 only
4967 // Use typeof to avoid zero-argument method invocation on host objects (#15151)
4968 var ret;
4969
4970 if ( typeof context.getElementsByTagName !== "undefined" ) {
4971 ret = context.getElementsByTagName( tag || "*" );
4972
4973 } else if ( typeof context.querySelectorAll !== "undefined" ) {
4974 ret = context.querySelectorAll( tag || "*" );
4975
4976 } else {
4977 ret = [];
4978 }
4979
4980 if ( tag === undefined || tag && nodeName( context, tag ) ) {
4981 return jQuery.merge( [ context ], ret );
4982 }
4983
4984 return ret;
4985 }
4986
4987
4988 // Mark scripts as having already been evaluated
4989 function setGlobalEval( elems, refElements ) {
4990 var i = 0,
4991 l = elems.length;
4992
4993 for ( ; i < l; i++ ) {
4994 dataPriv.set(
4995 elems[ i ],
4996 "globalEval",
4997 !refElements || dataPriv.get( refElements[ i ], "globalEval" )
4998 );
4999 }
5000 }
5001
5002
5003 var rhtml = /<|&#?\w+;/;
5004
5005 function buildFragment( elems, context, scripts, selection, ignored ) {
5006 var elem, tmp, tag, wrap, attached, j,
5007 fragment = context.createDocumentFragment(),
5008 nodes = [],
5009 i = 0,
5010 l = elems.length;
5011
5012 for ( ; i < l; i++ ) {
5013 elem = elems[ i ];
5014
5015 if ( elem || elem === 0 ) {
5016
5017 // Add nodes directly
5018 if ( toType( elem ) === "object" ) {
5019
5020 // Support: Android <=4.0 only, PhantomJS 1 only
5021 // push.apply(_, arraylike) throws on ancient WebKit
5022 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5023
5024 // Convert non-html into a text node
5025 } else if ( !rhtml.test( elem ) ) {
5026 nodes.push( context.createTextNode( elem ) );
5027
5028 // Convert html into DOM nodes
5029 } else {
5030 tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
5031
5032 // Deserialize a standard representation
5033 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5034 wrap = wrapMap[ tag ] || wrapMap._default;
5035 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
5036
5037 // Descend through wrappers to the right content
5038 j = wrap[ 0 ];
5039 while ( j-- ) {
5040 tmp = tmp.lastChild;
5041 }
5042
5043 // Support: Android <=4.0 only, PhantomJS 1 only
5044 // push.apply(_, arraylike) throws on ancient WebKit
5045 jQuery.merge( nodes, tmp.childNodes );
5046
5047 // Remember the top-level container
5048 tmp = fragment.firstChild;
5049
5050 // Ensure the created nodes are orphaned (#12392)
5051 tmp.textContent = "";
5052 }
5053 }
5054 }
5055
5056 // Remove wrapper from fragment
5057 fragment.textContent = "";
5058
5059 i = 0;
5060 while ( ( elem = nodes[ i++ ] ) ) {
5061
5062 // Skip elements already in the context collection (trac-4087)
5063 if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
5064 if ( ignored ) {
5065 ignored.push( elem );
5066 }
5067 continue;
5068 }
5069
5070 attached = isAttached( elem );
5071
5072 // Append to fragment
5073 tmp = getAll( fragment.appendChild( elem ), "script" );
5074
5075 // Preserve script evaluation history
5076 if ( attached ) {
5077 setGlobalEval( tmp );
5078 }
5079
5080 // Capture executables
5081 if ( scripts ) {
5082 j = 0;
5083 while ( ( elem = tmp[ j++ ] ) ) {
5084 if ( rscriptType.test( elem.type || "" ) ) {
5085 scripts.push( elem );
5086 }
5087 }
5088 }
5089 }
5090
5091 return fragment;
5092 }
5093
5094
5095 var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
5096
5097 function returnTrue() {
5098 return true;
5099 }
5100
5101 function returnFalse() {
5102 return false;
5103 }
5104
5105 // Support: IE <=9 - 11+
5106 // focus() and blur() are asynchronous, except when they are no-op.
5107 // So expect focus to be synchronous when the element is already active,
5108 // and blur to be synchronous when the element is not already active.
5109 // (focus and blur are always synchronous in other supported browsers,
5110 // this just defines when we can count on it).
5111 function expectSync( elem, type ) {
5112 return ( elem === safeActiveElement() ) === ( type === "focus" );
5113 }
5114
5115 // Support: IE <=9 only
5116 // Accessing document.activeElement can throw unexpectedly
5117 // https://bugs.jquery.com/ticket/13393
5118 function safeActiveElement() {
5119 try {
5120 return document.activeElement;
5121 } catch ( err ) { }
5122 }
5123
5124 function on( elem, types, selector, data, fn, one ) {
5125 var origFn, type;
5126
5127 // Types can be a map of types/handlers
5128 if ( typeof types === "object" ) {
5129
5130 // ( types-Object, selector, data )
5131 if ( typeof selector !== "string" ) {
5132
5133 // ( types-Object, data )
5134 data = data || selector;
5135 selector = undefined;
5136 }
5137 for ( type in types ) {
5138 on( elem, type, selector, data, types[ type ], one );
5139 }
5140 return elem;
5141 }
5142
5143 if ( data == null && fn == null ) {
5144
5145 // ( types, fn )
5146 fn = selector;
5147 data = selector = undefined;
5148 } else if ( fn == null ) {
5149 if ( typeof selector === "string" ) {
5150
5151 // ( types, selector, fn )
5152 fn = data;
5153 data = undefined;
5154 } else {
5155
5156 // ( types, data, fn )
5157 fn = data;
5158 data = selector;
5159 selector = undefined;
5160 }
5161 }
5162 if ( fn === false ) {
5163 fn = returnFalse;
5164 } else if ( !fn ) {
5165 return elem;
5166 }
5167
5168 if ( one === 1 ) {
5169 origFn = fn;
5170 fn = function( event ) {
5171
5172 // Can use an empty set, since event contains the info
5173 jQuery().off( event );
5174 return origFn.apply( this, arguments );
5175 };
5176
5177 // Use same guid so caller can remove using origFn
5178 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5179 }
5180 return elem.each( function() {
5181 jQuery.event.add( this, types, fn, data, selector );
5182 } );
5183 }
5184
5185 /*
5186 * Helper functions for managing events -- not part of the public interface.
5187 * Props to Dean Edwards' addEvent library for many of the ideas.
5188 */
5189 jQuery.event = {
5190
5191 global: {},
5192
5193 add: function( elem, types, handler, data, selector ) {
5194
5195 var handleObjIn, eventHandle, tmp,
5196 events, t, handleObj,
5197 special, handlers, type, namespaces, origType,
5198 elemData = dataPriv.get( elem );
5199
5200 // Only attach events to objects that accept data
5201 if ( !acceptData( elem ) ) {
5202 return;
5203 }
5204
5205 // Caller can pass in an object of custom data in lieu of the handler
5206 if ( handler.handler ) {
5207 handleObjIn = handler;
5208 handler = handleObjIn.handler;
5209 selector = handleObjIn.selector;
5210 }
5211
5212 // Ensure that invalid selectors throw exceptions at attach time
5213 // Evaluate against documentElement in case elem is a non-element node (e.g., document)
5214 if ( selector ) {
5215 jQuery.find.matchesSelector( documentElement, selector );
5216 }
5217
5218 // Make sure that the handler has a unique ID, used to find/remove it later
5219 if ( !handler.guid ) {
5220 handler.guid = jQuery.guid++;
5221 }
5222
5223 // Init the element's event structure and main handler, if this is the first
5224 if ( !( events = elemData.events ) ) {
5225 events = elemData.events = Object.create( null );
5226 }
5227 if ( !( eventHandle = elemData.handle ) ) {
5228 eventHandle = elemData.handle = function( e ) {
5229
5230 // Discard the second event of a jQuery.event.trigger() and
5231 // when an event is called after a page has unloaded
5232 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
5233 jQuery.event.dispatch.apply( elem, arguments ) : undefined;
5234 };
5235 }
5236
5237 // Handle multiple events separated by a space
5238 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5239 t = types.length;
5240 while ( t-- ) {
5241 tmp = rtypenamespace.exec( types[ t ] ) || [];
5242 type = origType = tmp[ 1 ];
5243 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5244
5245 // There *must* be a type, no attaching namespace-only handlers
5246 if ( !type ) {
5247 continue;
5248 }
5249
5250 // If event changes its type, use the special event handlers for the changed type
5251 special = jQuery.event.special[ type ] || {};
5252
5253 // If selector defined, determine special event api type, otherwise given type
5254 type = ( selector ? special.delegateType : special.bindType ) || type;
5255
5256 // Update special based on newly reset type
5257 special = jQuery.event.special[ type ] || {};
5258
5259 // handleObj is passed to all event handlers
5260 handleObj = jQuery.extend( {
5261 type: type,
5262 origType: origType,
5263 data: data,
5264 handler: handler,
5265 guid: handler.guid,
5266 selector: selector,
5267 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
5268 namespace: namespaces.join( "." )
5269 }, handleObjIn );
5270
5271 // Init the event handler queue if we're the first
5272 if ( !( handlers = events[ type ] ) ) {
5273 handlers = events[ type ] = [];
5274 handlers.delegateCount = 0;
5275
5276 // Only use addEventListener if the special events handler returns false
5277 if ( !special.setup ||
5278 special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
5279
5280 if ( elem.addEventListener ) {
5281 elem.addEventListener( type, eventHandle );
5282 }
5283 }
5284 }
5285
5286 if ( special.add ) {
5287 special.add.call( elem, handleObj );
5288
5289 if ( !handleObj.handler.guid ) {
5290 handleObj.handler.guid = handler.guid;
5291 }
5292 }
5293
5294 // Add to the element's handler list, delegates in front
5295 if ( selector ) {
5296 handlers.splice( handlers.delegateCount++, 0, handleObj );
5297 } else {
5298 handlers.push( handleObj );
5299 }
5300
5301 // Keep track of which events have ever been used, for event optimization
5302 jQuery.event.global[ type ] = true;
5303 }
5304
5305 },
5306
5307 // Detach an event or set of events from an element
5308 remove: function( elem, types, handler, selector, mappedTypes ) {
5309
5310 var j, origCount, tmp,
5311 events, t, handleObj,
5312 special, handlers, type, namespaces, origType,
5313 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
5314
5315 if ( !elemData || !( events = elemData.events ) ) {
5316 return;
5317 }
5318
5319 // Once for each type.namespace in types; type may be omitted
5320 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5321 t = types.length;
5322 while ( t-- ) {
5323 tmp = rtypenamespace.exec( types[ t ] ) || [];
5324 type = origType = tmp[ 1 ];
5325 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5326
5327 // Unbind all events (on this namespace, if provided) for the element
5328 if ( !type ) {
5329 for ( type in events ) {
5330 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
5331 }
5332 continue;
5333 }
5334
5335 special = jQuery.event.special[ type ] || {};
5336 type = ( selector ? special.delegateType : special.bindType ) || type;
5337 handlers = events[ type ] || [];
5338 tmp = tmp[ 2 ] &&
5339 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
5340
5341 // Remove matching events
5342 origCount = j = handlers.length;
5343 while ( j-- ) {
5344 handleObj = handlers[ j ];
5345
5346 if ( ( mappedTypes || origType === handleObj.origType ) &&
5347 ( !handler || handler.guid === handleObj.guid ) &&
5348 ( !tmp || tmp.test( handleObj.namespace ) ) &&
5349 ( !selector || selector === handleObj.selector ||
5350 selector === "**" && handleObj.selector ) ) {
5351 handlers.splice( j, 1 );
5352
5353 if ( handleObj.selector ) {
5354 handlers.delegateCount--;
5355 }
5356 if ( special.remove ) {
5357 special.remove.call( elem, handleObj );
5358 }
5359 }
5360 }
5361
5362 // Remove generic event handler if we removed something and no more handlers exist
5363 // (avoids potential for endless recursion during removal of special event handlers)
5364 if ( origCount && !handlers.length ) {
5365 if ( !special.teardown ||
5366 special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5367
5368 jQuery.removeEvent( elem, type, elemData.handle );
5369 }
5370
5371 delete events[ type ];
5372 }
5373 }
5374
5375 // Remove data and the expando if it's no longer used
5376 if ( jQuery.isEmptyObject( events ) ) {
5377 dataPriv.remove( elem, "handle events" );
5378 }
5379 },
5380
5381 dispatch: function( nativeEvent ) {
5382
5383 var i, j, ret, matched, handleObj, handlerQueue,
5384 args = new Array( arguments.length ),
5385
5386 // Make a writable jQuery.Event from the native event object
5387 event = jQuery.event.fix( nativeEvent ),
5388
5389 handlers = (
5390 dataPriv.get( this, "events" ) || Object.create( null )
5391 )[ event.type ] || [],
5392 special = jQuery.event.special[ event.type ] || {};
5393
5394 // Use the fix-ed jQuery.Event rather than the (read-only) native event
5395 args[ 0 ] = event;
5396
5397 for ( i = 1; i < arguments.length; i++ ) {
5398 args[ i ] = arguments[ i ];
5399 }
5400
5401 event.delegateTarget = this;
5402
5403 // Call the preDispatch hook for the mapped type, and let it bail if desired
5404 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5405 return;
5406 }
5407
5408 // Determine handlers
5409 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5410
5411 // Run delegates first; they may want to stop propagation beneath us
5412 i = 0;
5413 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5414 event.currentTarget = matched.elem;
5415
5416 j = 0;
5417 while ( ( handleObj = matched.handlers[ j++ ] ) &&
5418 !event.isImmediatePropagationStopped() ) {
5419
5420 // If the event is namespaced, then each handler is only invoked if it is
5421 // specially universal or its namespaces are a superset of the event's.
5422 if ( !event.rnamespace || handleObj.namespace === false ||
5423 event.rnamespace.test( handleObj.namespace ) ) {
5424
5425 event.handleObj = handleObj;
5426 event.data = handleObj.data;
5427
5428 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5429 handleObj.handler ).apply( matched.elem, args );
5430
5431 if ( ret !== undefined ) {
5432 if ( ( event.result = ret ) === false ) {
5433 event.preventDefault();
5434 event.stopPropagation();
5435 }
5436 }
5437 }
5438 }
5439 }
5440
5441 // Call the postDispatch hook for the mapped type
5442 if ( special.postDispatch ) {
5443 special.postDispatch.call( this, event );
5444 }
5445
5446 return event.result;
5447 },
5448
5449 handlers: function( event, handlers ) {
5450 var i, handleObj, sel, matchedHandlers, matchedSelectors,
5451 handlerQueue = [],
5452 delegateCount = handlers.delegateCount,
5453 cur = event.target;
5454
5455 // Find delegate handlers
5456 if ( delegateCount &&
5457
5458 // Support: IE <=9
5459 // Black-hole SVG <use> instance trees (trac-13180)
5460 cur.nodeType &&
5461
5462 // Support: Firefox <=42
5463 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5464 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5465 // Support: IE 11 only
5466 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5467 !( event.type === "click" && event.button >= 1 ) ) {
5468
5469 for ( ; cur !== this; cur = cur.parentNode || this ) {
5470
5471 // Don't check non-elements (#13208)
5472 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5473 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
5474 matchedHandlers = [];
5475 matchedSelectors = {};
5476 for ( i = 0; i < delegateCount; i++ ) {
5477 handleObj = handlers[ i ];
5478
5479 // Don't conflict with Object.prototype properties (#13203)
5480 sel = handleObj.selector + " ";
5481
5482 if ( matchedSelectors[ sel ] === undefined ) {
5483 matchedSelectors[ sel ] = handleObj.needsContext ?
5484 jQuery( sel, this ).index( cur ) > -1 :
5485 jQuery.find( sel, this, null, [ cur ] ).length;
5486 }
5487 if ( matchedSelectors[ sel ] ) {
5488 matchedHandlers.push( handleObj );
5489 }
5490 }
5491 if ( matchedHandlers.length ) {
5492 handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
5493 }
5494 }
5495 }
5496 }
5497
5498 // Add the remaining (directly-bound) handlers
5499 cur = this;
5500 if ( delegateCount < handlers.length ) {
5501 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
5502 }
5503
5504 return handlerQueue;
5505 },
5506
5507 addProp: function( name, hook ) {
5508 Object.defineProperty( jQuery.Event.prototype, name, {
5509 enumerable: true,
5510 configurable: true,
5511
5512 get: isFunction( hook ) ?
5513 function() {
5514 if ( this.originalEvent ) {
5515 return hook( this.originalEvent );
5516 }
5517 } :
5518 function() {
5519 if ( this.originalEvent ) {
5520 return this.originalEvent[ name ];
5521 }
5522 },
5523
5524 set: function( value ) {
5525 Object.defineProperty( this, name, {
5526 enumerable: true,
5527 configurable: true,
5528 writable: true,
5529 value: value
5530 } );
5531 }
5532 } );
5533 },
5534
5535 fix: function( originalEvent ) {
5536 return originalEvent[ jQuery.expando ] ?
5537 originalEvent :
5538 new jQuery.Event( originalEvent );
5539 },
5540
5541 special: {
5542 load: {
5543
5544 // Prevent triggered image.load events from bubbling to window.load
5545 noBubble: true
5546 },
5547 click: {
5548
5549 // Utilize native event to ensure correct state for checkable inputs
5550 setup: function( data ) {
5551
5552 // For mutual compressibility with _default, replace `this` access with a local var.
5553 // `|| data` is dead code meant only to preserve the variable through minification.
5554 var el = this || data;
5555
5556 // Claim the first handler
5557 if ( rcheckableType.test( el.type ) &&
5558 el.click && nodeName( el, "input" ) ) {
5559
5560 // dataPriv.set( el, "click", ... )
5561 leverageNative( el, "click", returnTrue );
5562 }
5563
5564 // Return false to allow normal processing in the caller
5565 return false;
5566 },
5567 trigger: function( data ) {
5568
5569 // For mutual compressibility with _default, replace `this` access with a local var.
5570 // `|| data` is dead code meant only to preserve the variable through minification.
5571 var el = this || data;
5572
5573 // Force setup before triggering a click
5574 if ( rcheckableType.test( el.type ) &&
5575 el.click && nodeName( el, "input" ) ) {
5576
5577 leverageNative( el, "click" );
5578 }
5579
5580 // Return non-false to allow normal event-path propagation
5581 return true;
5582 },
5583
5584 // For cross-browser consistency, suppress native .click() on links
5585 // Also prevent it if we're currently inside a leveraged native-event stack
5586 _default: function( event ) {
5587 var target = event.target;
5588 return rcheckableType.test( target.type ) &&
5589 target.click && nodeName( target, "input" ) &&
5590 dataPriv.get( target, "click" ) ||
5591 nodeName( target, "a" );
5592 }
5593 },
5594
5595 beforeunload: {
5596 postDispatch: function( event ) {
5597
5598 // Support: Firefox 20+
5599 // Firefox doesn't alert if the returnValue field is not set.
5600 if ( event.result !== undefined && event.originalEvent ) {
5601 event.originalEvent.returnValue = event.result;
5602 }
5603 }
5604 }
5605 }
5606 };
5607
5608 // Ensure the presence of an event listener that handles manually-triggered
5609 // synthetic events by interrupting progress until reinvoked in response to
5610 // *native* events that it fires directly, ensuring that state changes have
5611 // already occurred before other listeners are invoked.
5612 function leverageNative( el, type, expectSync ) {
5613
5614 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
5615 if ( !expectSync ) {
5616 if ( dataPriv.get( el, type ) === undefined ) {
5617 jQuery.event.add( el, type, returnTrue );
5618 }
5619 return;
5620 }
5621
5622 // Register the controller as a special universal handler for all event namespaces
5623 dataPriv.set( el, type, false );
5624 jQuery.event.add( el, type, {
5625 namespace: false,
5626 handler: function( event ) {
5627 var notAsync, result,
5628 saved = dataPriv.get( this, type );
5629
5630 if ( ( event.isTrigger & 1 ) && this[ type ] ) {
5631
5632 // Interrupt processing of the outer synthetic .trigger()ed event
5633 // Saved data should be false in such cases, but might be a leftover capture object
5634 // from an async native handler (gh-4350)
5635 if ( !saved.length ) {
5636
5637 // Store arguments for use when handling the inner native event
5638 // There will always be at least one argument (an event object), so this array
5639 // will not be confused with a leftover capture object.
5640 saved = slice.call( arguments );
5641 dataPriv.set( this, type, saved );
5642
5643 // Trigger the native event and capture its result
5644 // Support: IE <=9 - 11+
5645 // focus() and blur() are asynchronous
5646 notAsync = expectSync( this, type );
5647 this[ type ]();
5648 result = dataPriv.get( this, type );
5649 if ( saved !== result || notAsync ) {
5650 dataPriv.set( this, type, false );
5651 } else {
5652 result = {};
5653 }
5654 if ( saved !== result ) {
5655
5656 // Cancel the outer synthetic event
5657 event.stopImmediatePropagation();
5658 event.preventDefault();
5659
5660 // Support: Chrome 86+
5661 // In Chrome, if an element having a focusout handler is blurred by
5662 // clicking outside of it, it invokes the handler synchronously. If
5663 // that handler calls `.remove()` on the element, the data is cleared,
5664 // leaving `result` undefined. We need to guard against this.
5665 return result && result.value;
5666 }
5667
5668 // If this is an inner synthetic event for an event with a bubbling surrogate
5669 // (focus or blur), assume that the surrogate already propagated from triggering the
5670 // native event and prevent that from happening again here.
5671 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
5672 // bubbling surrogate propagates *after* the non-bubbling base), but that seems
5673 // less bad than duplication.
5674 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
5675 event.stopPropagation();
5676 }
5677
5678 // If this is a native event triggered above, everything is now in order
5679 // Fire an inner synthetic event with the original arguments
5680 } else if ( saved.length ) {
5681
5682 // ...and capture the result
5683 dataPriv.set( this, type, {
5684 value: jQuery.event.trigger(
5685
5686 // Support: IE <=9 - 11+
5687 // Extend with the prototype to reset the above stopImmediatePropagation()
5688 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
5689 saved.slice( 1 ),
5690 this
5691 )
5692 } );
5693
5694 // Abort handling of the native event
5695 event.stopImmediatePropagation();
5696 }
5697 }
5698 } );
5699 }
5700
5701 jQuery.removeEvent = function( elem, type, handle ) {
5702
5703 // This "if" is needed for plain objects
5704 if ( elem.removeEventListener ) {
5705 elem.removeEventListener( type, handle );
5706 }
5707 };
5708
5709 jQuery.Event = function( src, props ) {
5710
5711 // Allow instantiation without the 'new' keyword
5712 if ( !( this instanceof jQuery.Event ) ) {
5713 return new jQuery.Event( src, props );
5714 }
5715
5716 // Event object
5717 if ( src && src.type ) {
5718 this.originalEvent = src;
5719 this.type = src.type;
5720
5721 // Events bubbling up the document may have been marked as prevented
5722 // by a handler lower down the tree; reflect the correct value.
5723 this.isDefaultPrevented = src.defaultPrevented ||
5724 src.defaultPrevented === undefined &&
5725
5726 // Support: Android <=2.3 only
5727 src.returnValue === false ?
5728 returnTrue :
5729 returnFalse;
5730
5731 // Create target properties
5732 // Support: Safari <=6 - 7 only
5733 // Target should not be a text node (#504, #13143)
5734 this.target = ( src.target && src.target.nodeType === 3 ) ?
5735 src.target.parentNode :
5736 src.target;
5737
5738 this.currentTarget = src.currentTarget;
5739 this.relatedTarget = src.relatedTarget;
5740
5741 // Event type
5742 } else {
5743 this.type = src;
5744 }
5745
5746 // Put explicitly provided properties onto the event object
5747 if ( props ) {
5748 jQuery.extend( this, props );
5749 }
5750
5751 // Create a timestamp if incoming event doesn't have one
5752 this.timeStamp = src && src.timeStamp || Date.now();
5753
5754 // Mark it as fixed
5755 this[ jQuery.expando ] = true;
5756 };
5757
5758 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5759 // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5760 jQuery.Event.prototype = {
5761 constructor: jQuery.Event,
5762 isDefaultPrevented: returnFalse,
5763 isPropagationStopped: returnFalse,
5764 isImmediatePropagationStopped: returnFalse,
5765 isSimulated: false,
5766
5767 preventDefault: function() {
5768 var e = this.originalEvent;
5769
5770 this.isDefaultPrevented = returnTrue;
5771
5772 if ( e && !this.isSimulated ) {
5773 e.preventDefault();
5774 }
5775 },
5776 stopPropagation: function() {
5777 var e = this.originalEvent;
5778
5779 this.isPropagationStopped = returnTrue;
5780
5781 if ( e && !this.isSimulated ) {
5782 e.stopPropagation();
5783 }
5784 },
5785 stopImmediatePropagation: function() {
5786 var e = this.originalEvent;
5787
5788 this.isImmediatePropagationStopped = returnTrue;
5789
5790 if ( e && !this.isSimulated ) {
5791 e.stopImmediatePropagation();
5792 }
5793
5794 this.stopPropagation();
5795 }
5796 };
5797
5798 // Includes all common event props including KeyEvent and MouseEvent specific props
5799 jQuery.each( {
5800 altKey: true,
5801 bubbles: true,
5802 cancelable: true,
5803 changedTouches: true,
5804 ctrlKey: true,
5805 detail: true,
5806 eventPhase: true,
5807 metaKey: true,
5808 pageX: true,
5809 pageY: true,
5810 shiftKey: true,
5811 view: true,
5812 "char": true,
5813 code: true,
5814 charCode: true,
5815 key: true,
5816 keyCode: true,
5817 button: true,
5818 buttons: true,
5819 clientX: true,
5820 clientY: true,
5821 offsetX: true,
5822 offsetY: true,
5823 pointerId: true,
5824 pointerType: true,
5825 screenX: true,
5826 screenY: true,
5827 targetTouches: true,
5828 toElement: true,
5829 touches: true,
5830 which: true
5831 }, jQuery.event.addProp );
5832
5833 jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
5834 jQuery.event.special[ type ] = {
5835
5836 // Utilize native event if possible so blur/focus sequence is correct
5837 setup: function() {
5838
5839 // Claim the first handler
5840 // dataPriv.set( this, "focus", ... )
5841 // dataPriv.set( this, "blur", ... )
5842 leverageNative( this, type, expectSync );
5843
5844 // Return false to allow normal processing in the caller
5845 return false;
5846 },
5847 trigger: function() {
5848
5849 // Force setup before trigger
5850 leverageNative( this, type );
5851
5852 // Return non-false to allow normal event-path propagation
5853 return true;
5854 },
5855
5856 // Suppress native focus or blur as it's already being fired
5857 // in leverageNative.
5858 _default: function() {
5859 return true;
5860 },
5861
5862 delegateType: delegateType
5863 };
5864 } );
5865
5866 // Create mouseenter/leave events using mouseover/out and event-time checks
5867 // so that event delegation works in jQuery.
5868 // Do the same for pointerenter/pointerleave and pointerover/pointerout
5869 //
5870 // Support: Safari 7 only
5871 // Safari sends mouseenter too often; see:
5872 // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5873 // for the description of the bug (it existed in older Chrome versions as well).
5874 jQuery.each( {
5875 mouseenter: "mouseover",
5876 mouseleave: "mouseout",
5877 pointerenter: "pointerover",
5878 pointerleave: "pointerout"
5879 }, function( orig, fix ) {
5880 jQuery.event.special[ orig ] = {
5881 delegateType: fix,
5882 bindType: fix,
5883
5884 handle: function( event ) {
5885 var ret,
5886 target = this,
5887 related = event.relatedTarget,
5888 handleObj = event.handleObj;
5889
5890 // For mouseenter/leave call the handler if related is outside the target.
5891 // NB: No relatedTarget if the mouse left/entered the browser window
5892 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5893 event.type = handleObj.origType;
5894 ret = handleObj.handler.apply( this, arguments );
5895 event.type = fix;
5896 }
5897 return ret;
5898 }
5899 };
5900 } );
5901
5902 jQuery.fn.extend( {
5903
5904 on: function( types, selector, data, fn ) {
5905 return on( this, types, selector, data, fn );
5906 },
5907 one: function( types, selector, data, fn ) {
5908 return on( this, types, selector, data, fn, 1 );
5909 },
5910 off: function( types, selector, fn ) {
5911 var handleObj, type;
5912 if ( types && types.preventDefault && types.handleObj ) {
5913
5914 // ( event ) dispatched jQuery.Event
5915 handleObj = types.handleObj;
5916 jQuery( types.delegateTarget ).off(
5917 handleObj.namespace ?
5918 handleObj.origType + "." + handleObj.namespace :
5919 handleObj.origType,
5920 handleObj.selector,
5921 handleObj.handler
5922 );
5923 return this;
5924 }
5925 if ( typeof types === "object" ) {
5926
5927 // ( types-object [, selector] )
5928 for ( type in types ) {
5929 this.off( type, selector, types[ type ] );
5930 }
5931 return this;
5932 }
5933 if ( selector === false || typeof selector === "function" ) {
5934
5935 // ( types [, fn] )
5936 fn = selector;
5937 selector = undefined;
5938 }
5939 if ( fn === false ) {
5940 fn = returnFalse;
5941 }
5942 return this.each( function() {
5943 jQuery.event.remove( this, types, fn, selector );
5944 } );
5945 }
5946 } );
5947
5948
5949 var
5950
5951 // Support: IE <=10 - 11, Edge 12 - 13 only
5952 // In IE/Edge using regex groups here causes severe slowdowns.
5953 // See https://connect.microsoft.com/IE/feedback/details/1736512/
5954 rnoInnerhtml = /<script|<style|<link/i,
5955
5956 // checked="checked" or checked
5957 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5958 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5959
5960 // Prefer a tbody over its parent table for containing new rows
5961 function manipulationTarget( elem, content ) {
5962 if ( nodeName( elem, "table" ) &&
5963 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
5964
5965 return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
5966 }
5967
5968 return elem;
5969 }
5970
5971 // Replace/restore the type attribute of script elements for safe DOM manipulation
5972 function disableScript( elem ) {
5973 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5974 return elem;
5975 }
5976 function restoreScript( elem ) {
5977 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
5978 elem.type = elem.type.slice( 5 );
5979 } else {
5980 elem.removeAttribute( "type" );
5981 }
5982
5983 return elem;
5984 }
5985
5986 function cloneCopyEvent( src, dest ) {
5987 var i, l, type, pdataOld, udataOld, udataCur, events;
5988
5989 if ( dest.nodeType !== 1 ) {
5990 return;
5991 }
5992
5993 // 1. Copy private data: events, handlers, etc.
5994 if ( dataPriv.hasData( src ) ) {
5995 pdataOld = dataPriv.get( src );
5996 events = pdataOld.events;
5997
5998 if ( events ) {
5999 dataPriv.remove( dest, "handle events" );
6000
6001 for ( type in events ) {
6002 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6003 jQuery.event.add( dest, type, events[ type ][ i ] );
6004 }
6005 }
6006 }
6007 }
6008
6009 // 2. Copy user data
6010 if ( dataUser.hasData( src ) ) {
6011 udataOld = dataUser.access( src );
6012 udataCur = jQuery.extend( {}, udataOld );
6013
6014 dataUser.set( dest, udataCur );
6015 }
6016 }
6017
6018 // Fix IE bugs, see support tests
6019 function fixInput( src, dest ) {
6020 var nodeName = dest.nodeName.toLowerCase();
6021
6022 // Fails to persist the checked state of a cloned checkbox or radio button.
6023 if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6024 dest.checked = src.checked;
6025
6026 // Fails to return the selected option to the default selected state when cloning options
6027 } else if ( nodeName === "input" || nodeName === "textarea" ) {
6028 dest.defaultValue = src.defaultValue;
6029 }
6030 }
6031
6032 function domManip( collection, args, callback, ignored ) {
6033
6034 // Flatten any nested arrays
6035 args = flat( args );
6036
6037 var fragment, first, scripts, hasScripts, node, doc,
6038 i = 0,
6039 l = collection.length,
6040 iNoClone = l - 1,
6041 value = args[ 0 ],
6042 valueIsFunction = isFunction( value );
6043
6044 // We can't cloneNode fragments that contain checked, in WebKit
6045 if ( valueIsFunction ||
6046 ( l > 1 && typeof value === "string" &&
6047 !support.checkClone && rchecked.test( value ) ) ) {
6048 return collection.each( function( index ) {
6049 var self = collection.eq( index );
6050 if ( valueIsFunction ) {
6051 args[ 0 ] = value.call( this, index, self.html() );
6052 }
6053 domManip( self, args, callback, ignored );
6054 } );
6055 }
6056
6057 if ( l ) {
6058 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6059 first = fragment.firstChild;
6060
6061 if ( fragment.childNodes.length === 1 ) {
6062 fragment = first;
6063 }
6064
6065 // Require either new content or an interest in ignored elements to invoke the callback
6066 if ( first || ignored ) {
6067 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6068 hasScripts = scripts.length;
6069
6070 // Use the original fragment for the last item
6071 // instead of the first because it can end up
6072 // being emptied incorrectly in certain situations (#8070).
6073 for ( ; i < l; i++ ) {
6074 node = fragment;
6075
6076 if ( i !== iNoClone ) {
6077 node = jQuery.clone( node, true, true );
6078
6079 // Keep references to cloned scripts for later restoration
6080 if ( hasScripts ) {
6081
6082 // Support: Android <=4.0 only, PhantomJS 1 only
6083 // push.apply(_, arraylike) throws on ancient WebKit
6084 jQuery.merge( scripts, getAll( node, "script" ) );
6085 }
6086 }
6087
6088 callback.call( collection[ i ], node, i );
6089 }
6090
6091 if ( hasScripts ) {
6092 doc = scripts[ scripts.length - 1 ].ownerDocument;
6093
6094 // Reenable scripts
6095 jQuery.map( scripts, restoreScript );
6096
6097 // Evaluate executable scripts on first document insertion
6098 for ( i = 0; i < hasScripts; i++ ) {
6099 node = scripts[ i ];
6100 if ( rscriptType.test( node.type || "" ) &&
6101 !dataPriv.access( node, "globalEval" ) &&
6102 jQuery.contains( doc, node ) ) {
6103
6104 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) {
6105
6106 // Optional AJAX dependency, but won't run scripts if not present
6107 if ( jQuery._evalUrl && !node.noModule ) {
6108 jQuery._evalUrl( node.src, {
6109 nonce: node.nonce || node.getAttribute( "nonce" )
6110 }, doc );
6111 }
6112 } else {
6113 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
6114 }
6115 }
6116 }
6117 }
6118 }
6119 }
6120
6121 return collection;
6122 }
6123
6124 function remove( elem, selector, keepData ) {
6125 var node,
6126 nodes = selector ? jQuery.filter( selector, elem ) : elem,
6127 i = 0;
6128
6129 for ( ; ( node = nodes[ i ] ) != null; i++ ) {
6130 if ( !keepData && node.nodeType === 1 ) {
6131 jQuery.cleanData( getAll( node ) );
6132 }
6133
6134 if ( node.parentNode ) {
6135 if ( keepData && isAttached( node ) ) {
6136 setGlobalEval( getAll( node, "script" ) );
6137 }
6138 node.parentNode.removeChild( node );
6139 }
6140 }
6141
6142 return elem;
6143 }
6144
6145 jQuery.extend( {
6146 htmlPrefilter: function( html ) {
6147 return html;
6148 },
6149
6150 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6151 var i, l, srcElements, destElements,
6152 clone = elem.cloneNode( true ),
6153 inPage = isAttached( elem );
6154
6155 // Fix IE cloning issues
6156 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
6157 !jQuery.isXMLDoc( elem ) ) {
6158
6159 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
6160 destElements = getAll( clone );
6161 srcElements = getAll( elem );
6162
6163 for ( i = 0, l = srcElements.length; i < l; i++ ) {
6164 fixInput( srcElements[ i ], destElements[ i ] );
6165 }
6166 }
6167
6168 // Copy the events from the original to the clone
6169 if ( dataAndEvents ) {
6170 if ( deepDataAndEvents ) {
6171 srcElements = srcElements || getAll( elem );
6172 destElements = destElements || getAll( clone );
6173
6174 for ( i = 0, l = srcElements.length; i < l; i++ ) {
6175 cloneCopyEvent( srcElements[ i ], destElements[ i ] );
6176 }
6177 } else {
6178 cloneCopyEvent( elem, clone );
6179 }
6180 }
6181
6182 // Preserve script evaluation history
6183 destElements = getAll( clone, "script" );
6184 if ( destElements.length > 0 ) {
6185 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6186 }
6187
6188 // Return the cloned set
6189 return clone;
6190 },
6191
6192 cleanData: function( elems ) {
6193 var data, elem, type,
6194 special = jQuery.event.special,
6195 i = 0;
6196
6197 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
6198 if ( acceptData( elem ) ) {
6199 if ( ( data = elem[ dataPriv.expando ] ) ) {
6200 if ( data.events ) {
6201 for ( type in data.events ) {
6202 if ( special[ type ] ) {
6203 jQuery.event.remove( elem, type );
6204
6205 // This is a shortcut to avoid jQuery.event.remove's overhead
6206 } else {
6207 jQuery.removeEvent( elem, type, data.handle );
6208 }
6209 }
6210 }
6211
6212 // Support: Chrome <=35 - 45+
6213 // Assign undefined instead of using delete, see Data#remove
6214 elem[ dataPriv.expando ] = undefined;
6215 }
6216 if ( elem[ dataUser.expando ] ) {
6217
6218 // Support: Chrome <=35 - 45+
6219 // Assign undefined instead of using delete, see Data#remove
6220 elem[ dataUser.expando ] = undefined;
6221 }
6222 }
6223 }
6224 }
6225 } );
6226
6227 jQuery.fn.extend( {
6228 detach: function( selector ) {
6229 return remove( this, selector, true );
6230 },
6231
6232 remove: function( selector ) {
6233 return remove( this, selector );
6234 },
6235
6236 text: function( value ) {
6237 return access( this, function( value ) {
6238 return value === undefined ?
6239 jQuery.text( this ) :
6240 this.empty().each( function() {
6241 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6242 this.textContent = value;
6243 }
6244 } );
6245 }, null, value, arguments.length );
6246 },
6247
6248 append: function() {
6249 return domManip( this, arguments, function( elem ) {
6250 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6251 var target = manipulationTarget( this, elem );
6252 target.appendChild( elem );
6253 }
6254 } );
6255 },
6256
6257 prepend: function() {
6258 return domManip( this, arguments, function( elem ) {
6259 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6260 var target = manipulationTarget( this, elem );
6261 target.insertBefore( elem, target.firstChild );
6262 }
6263 } );
6264 },
6265
6266 before: function() {
6267 return domManip( this, arguments, function( elem ) {
6268 if ( this.parentNode ) {
6269 this.parentNode.insertBefore( elem, this );
6270 }
6271 } );
6272 },
6273
6274 after: function() {
6275 return domManip( this, arguments, function( elem ) {
6276 if ( this.parentNode ) {
6277 this.parentNode.insertBefore( elem, this.nextSibling );
6278 }
6279 } );
6280 },
6281
6282 empty: function() {
6283 var elem,
6284 i = 0;
6285
6286 for ( ; ( elem = this[ i ] ) != null; i++ ) {
6287 if ( elem.nodeType === 1 ) {
6288
6289 // Prevent memory leaks
6290 jQuery.cleanData( getAll( elem, false ) );
6291
6292 // Remove any remaining nodes
6293 elem.textContent = "";
6294 }
6295 }
6296
6297 return this;
6298 },
6299
6300 clone: function( dataAndEvents, deepDataAndEvents ) {
6301 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6302 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6303
6304 return this.map( function() {
6305 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6306 } );
6307 },
6308
6309 html: function( value ) {
6310 return access( this, function( value ) {
6311 var elem = this[ 0 ] || {},
6312 i = 0,
6313 l = this.length;
6314
6315 if ( value === undefined && elem.nodeType === 1 ) {
6316 return elem.innerHTML;
6317 }
6318
6319 // See if we can take a shortcut and just use innerHTML
6320 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6321 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6322
6323 value = jQuery.htmlPrefilter( value );
6324
6325 try {
6326 for ( ; i < l; i++ ) {
6327 elem = this[ i ] || {};
6328
6329 // Remove element nodes and prevent memory leaks
6330 if ( elem.nodeType === 1 ) {
6331 jQuery.cleanData( getAll( elem, false ) );
6332 elem.innerHTML = value;
6333 }
6334 }
6335
6336 elem = 0;
6337
6338 // If using innerHTML throws an exception, use the fallback method
6339 } catch ( e ) {}
6340 }
6341
6342 if ( elem ) {
6343 this.empty().append( value );
6344 }
6345 }, null, value, arguments.length );
6346 },
6347
6348 replaceWith: function() {
6349 var ignored = [];
6350
6351 // Make the changes, replacing each non-ignored context element with the new content
6352 return domManip( this, arguments, function( elem ) {
6353 var parent = this.parentNode;
6354
6355 if ( jQuery.inArray( this, ignored ) < 0 ) {
6356 jQuery.cleanData( getAll( this ) );
6357 if ( parent ) {
6358 parent.replaceChild( elem, this );
6359 }
6360 }
6361
6362 // Force callback invocation
6363 }, ignored );
6364 }
6365 } );
6366
6367 jQuery.each( {
6368 appendTo: "append",
6369 prependTo: "prepend",
6370 insertBefore: "before",
6371 insertAfter: "after",
6372 replaceAll: "replaceWith"
6373 }, function( name, original ) {
6374 jQuery.fn[ name ] = function( selector ) {
6375 var elems,
6376 ret = [],
6377 insert = jQuery( selector ),
6378 last = insert.length - 1,
6379 i = 0;
6380
6381 for ( ; i <= last; i++ ) {
6382 elems = i === last ? this : this.clone( true );
6383 jQuery( insert[ i ] )[ original ]( elems );
6384
6385 // Support: Android <=4.0 only, PhantomJS 1 only
6386 // .get() because push.apply(_, arraylike) throws on ancient WebKit
6387 push.apply( ret, elems.get() );
6388 }
6389
6390 return this.pushStack( ret );
6391 };
6392 } );
6393 var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6394
6395 var getStyles = function( elem ) {
6396
6397 // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
6398 // IE throws on elements created in popups
6399 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6400 var view = elem.ownerDocument.defaultView;
6401
6402 if ( !view || !view.opener ) {
6403 view = window;
6404 }
6405
6406 return view.getComputedStyle( elem );
6407 };
6408
6409 var swap = function( elem, options, callback ) {
6410 var ret, name,
6411 old = {};
6412
6413 // Remember the old values, and insert the new ones
6414 for ( name in options ) {
6415 old[ name ] = elem.style[ name ];
6416 elem.style[ name ] = options[ name ];
6417 }
6418
6419 ret = callback.call( elem );
6420
6421 // Revert the old values
6422 for ( name in options ) {
6423 elem.style[ name ] = old[ name ];
6424 }
6425
6426 return ret;
6427 };
6428
6429
6430 var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
6431
6432
6433
6434 ( function() {
6435
6436 // Executing both pixelPosition & boxSizingReliable tests require only one layout
6437 // so they're executed at the same time to save the second computation.
6438 function computeStyleTests() {
6439
6440 // This is a singleton, we need to execute it only once
6441 if ( !div ) {
6442 return;
6443 }
6444
6445 container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
6446 "margin-top:1px;padding:0;border:0";
6447 div.style.cssText =
6448 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
6449 "margin:auto;border:1px;padding:1px;" +
6450 "width:60%;top:1%";
6451 documentElement.appendChild( container ).appendChild( div );
6452
6453 var divStyle = window.getComputedStyle( div );
6454 pixelPositionVal = divStyle.top !== "1%";
6455
6456 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6457 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
6458
6459 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
6460 // Some styles come back with percentage values, even though they shouldn't
6461 div.style.right = "60%";
6462 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
6463
6464 // Support: IE 9 - 11 only
6465 // Detect misreporting of content dimensions for box-sizing:border-box elements
6466 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
6467
6468 // Support: IE 9 only
6469 // Detect overflow:scroll screwiness (gh-3699)
6470 // Support: Chrome <=64
6471 // Don't get tricked when zoom affects offsetWidth (gh-4029)
6472 div.style.position = "absolute";
6473 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
6474
6475 documentElement.removeChild( container );
6476
6477 // Nullify the div so it wouldn't be stored in the memory and
6478 // it will also be a sign that checks already performed
6479 div = null;
6480 }
6481
6482 function roundPixelMeasures( measure ) {
6483 return Math.round( parseFloat( measure ) );
6484 }
6485
6486 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
6487 reliableTrDimensionsVal, reliableMarginLeftVal,
6488 container = document.createElement( "div" ),
6489 div = document.createElement( "div" );
6490
6491 // Finish early in limited (non-browser) environments
6492 if ( !div.style ) {
6493 return;
6494 }
6495
6496 // Support: IE <=9 - 11 only
6497 // Style of cloned element affects source element cloned (#8908)
6498 div.style.backgroundClip = "content-box";
6499 div.cloneNode( true ).style.backgroundClip = "";
6500 support.clearCloneStyle = div.style.backgroundClip === "content-box";
6501
6502 jQuery.extend( support, {
6503 boxSizingReliable: function() {
6504 computeStyleTests();
6505 return boxSizingReliableVal;
6506 },
6507 pixelBoxStyles: function() {
6508 computeStyleTests();
6509 return pixelBoxStylesVal;
6510 },
6511 pixelPosition: function() {
6512 computeStyleTests();
6513 return pixelPositionVal;
6514 },
6515 reliableMarginLeft: function() {
6516 computeStyleTests();
6517 return reliableMarginLeftVal;
6518 },
6519 scrollboxSize: function() {
6520 computeStyleTests();
6521 return scrollboxSizeVal;
6522 },
6523
6524 // Support: IE 9 - 11+, Edge 15 - 18+
6525 // IE/Edge misreport `getComputedStyle` of table rows with width/height
6526 // set in CSS while `offset*` properties report correct values.
6527 // Behavior in IE 9 is more subtle than in newer versions & it passes
6528 // some versions of this test; make sure not to make it pass there!
6529 //
6530 // Support: Firefox 70+
6531 // Only Firefox includes border widths
6532 // in computed dimensions. (gh-4529)
6533 reliableTrDimensions: function() {
6534 var table, tr, trChild, trStyle;
6535 if ( reliableTrDimensionsVal == null ) {
6536 table = document.createElement( "table" );
6537 tr = document.createElement( "tr" );
6538 trChild = document.createElement( "div" );
6539
6540 table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
6541 tr.style.cssText = "border:1px solid";
6542
6543 // Support: Chrome 86+
6544 // Height set through cssText does not get applied.
6545 // Computed height then comes back as 0.
6546 tr.style.height = "1px";
6547 trChild.style.height = "9px";
6548
6549 // Support: Android 8 Chrome 86+
6550 // In our bodyBackground.html iframe,
6551 // display for all div elements is set to "inline",
6552 // which causes a problem only in Android 8 Chrome 86.
6553 // Ensuring the div is display: block
6554 // gets around this issue.
6555 trChild.style.display = "block";
6556
6557 documentElement
6558 .appendChild( table )
6559 .appendChild( tr )
6560 .appendChild( trChild );
6561
6562 trStyle = window.getComputedStyle( tr );
6563 reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
6564 parseInt( trStyle.borderTopWidth, 10 ) +
6565 parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
6566
6567 documentElement.removeChild( table );
6568 }
6569 return reliableTrDimensionsVal;
6570 }
6571 } );
6572 } )();
6573
6574
6575 function curCSS( elem, name, computed ) {
6576 var width, minWidth, maxWidth, ret,
6577
6578 // Support: Firefox 51+
6579 // Retrieving style before computed somehow
6580 // fixes an issue with getting wrong values
6581 // on detached elements
6582 style = elem.style;
6583
6584 computed = computed || getStyles( elem );
6585
6586 // getPropertyValue is needed for:
6587 // .css('filter') (IE 9 only, #12537)
6588 // .css('--customProperty) (#3144)
6589 if ( computed ) {
6590 ret = computed.getPropertyValue( name ) || computed[ name ];
6591
6592 if ( ret === "" && !isAttached( elem ) ) {
6593 ret = jQuery.style( elem, name );
6594 }
6595
6596 // A tribute to the "awesome hack by Dean Edwards"
6597 // Android Browser returns percentage for some values,
6598 // but width seems to be reliably pixels.
6599 // This is against the CSSOM draft spec:
6600 // https://drafts.csswg.org/cssom/#resolved-values
6601 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
6602
6603 // Remember the original values
6604 width = style.width;
6605 minWidth = style.minWidth;
6606 maxWidth = style.maxWidth;
6607
6608 // Put in the new values to get a computed value out
6609 style.minWidth = style.maxWidth = style.width = ret;
6610 ret = computed.width;
6611
6612 // Revert the changed values
6613 style.width = width;
6614 style.minWidth = minWidth;
6615 style.maxWidth = maxWidth;
6616 }
6617 }
6618
6619 return ret !== undefined ?
6620
6621 // Support: IE <=9 - 11 only
6622 // IE returns zIndex value as an integer.
6623 ret + "" :
6624 ret;
6625 }
6626
6627
6628 function addGetHookIf( conditionFn, hookFn ) {
6629
6630 // Define the hook, we'll check on the first run if it's really needed.
6631 return {
6632 get: function() {
6633 if ( conditionFn() ) {
6634
6635 // Hook not needed (or it's not possible to use it due
6636 // to missing dependency), remove it.
6637 delete this.get;
6638 return;
6639 }
6640
6641 // Hook needed; redefine it so that the support test is not executed again.
6642 return ( this.get = hookFn ).apply( this, arguments );
6643 }
6644 };
6645 }
6646
6647
6648 var cssPrefixes = [ "Webkit", "Moz", "ms" ],
6649 emptyStyle = document.createElement( "div" ).style,
6650 vendorProps = {};
6651
6652 // Return a vendor-prefixed property or undefined
6653 function vendorPropName( name ) {
6654
6655 // Check for vendor prefixed names
6656 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
6657 i = cssPrefixes.length;
6658
6659 while ( i-- ) {
6660 name = cssPrefixes[ i ] + capName;
6661 if ( name in emptyStyle ) {
6662 return name;
6663 }
6664 }
6665 }
6666
6667 // Return a potentially-mapped jQuery.cssProps or vendor prefixed property
6668 function finalPropName( name ) {
6669 var final = jQuery.cssProps[ name ] || vendorProps[ name ];
6670
6671 if ( final ) {
6672 return final;
6673 }
6674 if ( name in emptyStyle ) {
6675 return name;
6676 }
6677 return vendorProps[ name ] = vendorPropName( name ) || name;
6678 }
6679
6680
6681 var
6682
6683 // Swappable if display is none or starts with table
6684 // except "table", "table-cell", or "table-caption"
6685 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6686 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6687 rcustomProp = /^--/,
6688 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6689 cssNormalTransform = {
6690 letterSpacing: "0",
6691 fontWeight: "400"
6692 };
6693
6694 function setPositiveNumber( _elem, value, subtract ) {
6695
6696 // Any relative (+/-) values have already been
6697 // normalized at this point
6698 var matches = rcssNum.exec( value );
6699 return matches ?
6700
6701 // Guard against undefined "subtract", e.g., when used as in cssHooks
6702 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
6703 value;
6704 }
6705
6706 function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
6707 var i = dimension === "width" ? 1 : 0,
6708 extra = 0,
6709 delta = 0;
6710
6711 // Adjustment may not be necessary
6712 if ( box === ( isBorderBox ? "border" : "content" ) ) {
6713 return 0;
6714 }
6715
6716 for ( ; i < 4; i += 2 ) {
6717
6718 // Both box models exclude margin
6719 if ( box === "margin" ) {
6720 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
6721 }
6722
6723 // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
6724 if ( !isBorderBox ) {
6725
6726 // Add padding
6727 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6728
6729 // For "border" or "margin", add border
6730 if ( box !== "padding" ) {
6731 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6732
6733 // But still keep track of it otherwise
6734 } else {
6735 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6736 }
6737
6738 // If we get here with a border-box (content + padding + border), we're seeking "content" or
6739 // "padding" or "margin"
6740 } else {
6741
6742 // For "content", subtract padding
6743 if ( box === "content" ) {
6744 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6745 }
6746
6747 // For "content" or "padding", subtract border
6748 if ( box !== "margin" ) {
6749 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6750 }
6751 }
6752 }
6753
6754 // Account for positive content-box scroll gutter when requested by providing computedVal
6755 if ( !isBorderBox && computedVal >= 0 ) {
6756
6757 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
6758 // Assuming integer scroll gutter, subtract the rest and round down
6759 delta += Math.max( 0, Math.ceil(
6760 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
6761 computedVal -
6762 delta -
6763 extra -
6764 0.5
6765
6766 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
6767 // Use an explicit zero to avoid NaN (gh-3964)
6768 ) ) || 0;
6769 }
6770
6771 return delta;
6772 }
6773
6774 function getWidthOrHeight( elem, dimension, extra ) {
6775
6776 // Start with computed style
6777 var styles = getStyles( elem ),
6778
6779 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
6780 // Fake content-box until we know it's needed to know the true value.
6781 boxSizingNeeded = !support.boxSizingReliable() || extra,
6782 isBorderBox = boxSizingNeeded &&
6783 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6784 valueIsBorderBox = isBorderBox,
6785
6786 val = curCSS( elem, dimension, styles ),
6787 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
6788
6789 // Support: Firefox <=54
6790 // Return a confounding non-pixel value or feign ignorance, as appropriate.
6791 if ( rnumnonpx.test( val ) ) {
6792 if ( !extra ) {
6793 return val;
6794 }
6795 val = "auto";
6796 }
6797
6798
6799 // Support: IE 9 - 11 only
6800 // Use offsetWidth/offsetHeight for when box sizing is unreliable.
6801 // In those cases, the computed value can be trusted to be border-box.
6802 if ( ( !support.boxSizingReliable() && isBorderBox ||
6803
6804 // Support: IE 10 - 11+, Edge 15 - 18+
6805 // IE/Edge misreport `getComputedStyle` of table rows with width/height
6806 // set in CSS while `offset*` properties report correct values.
6807 // Interestingly, in some cases IE 9 doesn't suffer from this issue.
6808 !support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
6809
6810 // Fall back to offsetWidth/offsetHeight when value is "auto"
6811 // This happens for inline elements with no explicit setting (gh-3571)
6812 val === "auto" ||
6813
6814 // Support: Android <=4.1 - 4.3 only
6815 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
6816 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
6817
6818 // Make sure the element is visible & connected
6819 elem.getClientRects().length ) {
6820
6821 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6822
6823 // Where available, offsetWidth/offsetHeight approximate border box dimensions.
6824 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
6825 // retrieved value as a content box dimension.
6826 valueIsBorderBox = offsetProp in elem;
6827 if ( valueIsBorderBox ) {
6828 val = elem[ offsetProp ];
6829 }
6830 }
6831
6832 // Normalize "" and auto
6833 val = parseFloat( val ) || 0;
6834
6835 // Adjust for the element's box model
6836 return ( val +
6837 boxModelAdjustment(
6838 elem,
6839 dimension,
6840 extra || ( isBorderBox ? "border" : "content" ),
6841 valueIsBorderBox,
6842 styles,
6843
6844 // Provide the current computed size to request scroll gutter calculation (gh-3589)
6845 val
6846 )
6847 ) + "px";
6848 }
6849
6850 jQuery.extend( {
6851
6852 // Add in style property hooks for overriding the default
6853 // behavior of getting and setting a style property
6854 cssHooks: {
6855 opacity: {
6856 get: function( elem, computed ) {
6857 if ( computed ) {
6858
6859 // We should always get a number back from opacity
6860 var ret = curCSS( elem, "opacity" );
6861 return ret === "" ? "1" : ret;
6862 }
6863 }
6864 }
6865 },
6866
6867 // Don't automatically add "px" to these possibly-unitless properties
6868 cssNumber: {
6869 "animationIterationCount": true,
6870 "columnCount": true,
6871 "fillOpacity": true,
6872 "flexGrow": true,
6873 "flexShrink": true,
6874 "fontWeight": true,
6875 "gridArea": true,
6876 "gridColumn": true,
6877 "gridColumnEnd": true,
6878 "gridColumnStart": true,
6879 "gridRow": true,
6880 "gridRowEnd": true,
6881 "gridRowStart": true,
6882 "lineHeight": true,
6883 "opacity": true,
6884 "order": true,
6885 "orphans": true,
6886 "widows": true,
6887 "zIndex": true,
6888 "zoom": true
6889 },
6890
6891 // Add in properties whose names you wish to fix before
6892 // setting or getting the value
6893 cssProps: {},
6894
6895 // Get and set the style property on a DOM Node
6896 style: function( elem, name, value, extra ) {
6897
6898 // Don't set styles on text and comment nodes
6899 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6900 return;
6901 }
6902
6903 // Make sure that we're working with the right name
6904 var ret, type, hooks,
6905 origName = camelCase( name ),
6906 isCustomProp = rcustomProp.test( name ),
6907 style = elem.style;
6908
6909 // Make sure that we're working with the right name. We don't
6910 // want to query the value if it is a CSS custom property
6911 // since they are user-defined.
6912 if ( !isCustomProp ) {
6913 name = finalPropName( origName );
6914 }
6915
6916 // Gets hook for the prefixed version, then unprefixed version
6917 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6918
6919 // Check if we're setting a value
6920 if ( value !== undefined ) {
6921 type = typeof value;
6922
6923 // Convert "+=" or "-=" to relative numbers (#7345)
6924 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6925 value = adjustCSS( elem, name, ret );
6926
6927 // Fixes bug #9237
6928 type = "number";
6929 }
6930
6931 // Make sure that null and NaN values aren't set (#7116)
6932 if ( value == null || value !== value ) {
6933 return;
6934 }
6935
6936 // If a number was passed in, add the unit (except for certain CSS properties)
6937 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
6938 // "px" to a few hardcoded values.
6939 if ( type === "number" && !isCustomProp ) {
6940 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6941 }
6942
6943 // background-* props affect original clone's values
6944 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6945 style[ name ] = "inherit";
6946 }
6947
6948 // If a hook was provided, use that value, otherwise just set the specified value
6949 if ( !hooks || !( "set" in hooks ) ||
6950 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6951
6952 if ( isCustomProp ) {
6953 style.setProperty( name, value );
6954 } else {
6955 style[ name ] = value;
6956 }
6957 }
6958
6959 } else {
6960
6961 // If a hook was provided get the non-computed value from there
6962 if ( hooks && "get" in hooks &&
6963 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6964
6965 return ret;
6966 }
6967
6968 // Otherwise just get the value from the style object
6969 return style[ name ];
6970 }
6971 },
6972
6973 css: function( elem, name, extra, styles ) {
6974 var val, num, hooks,
6975 origName = camelCase( name ),
6976 isCustomProp = rcustomProp.test( name );
6977
6978 // Make sure that we're working with the right name. We don't
6979 // want to modify the value if it is a CSS custom property
6980 // since they are user-defined.
6981 if ( !isCustomProp ) {
6982 name = finalPropName( origName );
6983 }
6984
6985 // Try prefixed name followed by the unprefixed name
6986 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6987
6988 // If a hook was provided get the computed value from there
6989 if ( hooks && "get" in hooks ) {
6990 val = hooks.get( elem, true, extra );
6991 }
6992
6993 // Otherwise, if a way to get the computed value exists, use that
6994 if ( val === undefined ) {
6995 val = curCSS( elem, name, styles );
6996 }
6997
6998 // Convert "normal" to computed value
6999 if ( val === "normal" && name in cssNormalTransform ) {
7000 val = cssNormalTransform[ name ];
7001 }
7002
7003 // Make numeric if forced or a qualifier was provided and val looks numeric
7004 if ( extra === "" || extra ) {
7005 num = parseFloat( val );
7006 return extra === true || isFinite( num ) ? num || 0 : val;
7007 }
7008
7009 return val;
7010 }
7011 } );
7012
7013 jQuery.each( [ "height", "width" ], function( _i, dimension ) {
7014 jQuery.cssHooks[ dimension ] = {
7015 get: function( elem, computed, extra ) {
7016 if ( computed ) {
7017
7018 // Certain elements can have dimension info if we invisibly show them
7019 // but it must have a current display style that would benefit
7020 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7021
7022 // Support: Safari 8+
7023 // Table columns in Safari have non-zero offsetWidth & zero
7024 // getBoundingClientRect().width unless display is changed.
7025 // Support: IE <=11 only
7026 // Running getBoundingClientRect on a disconnected node
7027 // in IE throws an error.
7028 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
7029 swap( elem, cssShow, function() {
7030 return getWidthOrHeight( elem, dimension, extra );
7031 } ) :
7032 getWidthOrHeight( elem, dimension, extra );
7033 }
7034 },
7035
7036 set: function( elem, value, extra ) {
7037 var matches,
7038 styles = getStyles( elem ),
7039
7040 // Only read styles.position if the test has a chance to fail
7041 // to avoid forcing a reflow.
7042 scrollboxSizeBuggy = !support.scrollboxSize() &&
7043 styles.position === "absolute",
7044
7045 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
7046 boxSizingNeeded = scrollboxSizeBuggy || extra,
7047 isBorderBox = boxSizingNeeded &&
7048 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7049 subtract = extra ?
7050 boxModelAdjustment(
7051 elem,
7052 dimension,
7053 extra,
7054 isBorderBox,
7055 styles
7056 ) :
7057 0;
7058
7059 // Account for unreliable border-box dimensions by comparing offset* to computed and
7060 // faking a content-box to get border and padding (gh-3699)
7061 if ( isBorderBox && scrollboxSizeBuggy ) {
7062 subtract -= Math.ceil(
7063 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
7064 parseFloat( styles[ dimension ] ) -
7065 boxModelAdjustment( elem, dimension, "border", false, styles ) -
7066 0.5
7067 );
7068 }
7069
7070 // Convert to pixels if value adjustment is needed
7071 if ( subtract && ( matches = rcssNum.exec( value ) ) &&
7072 ( matches[ 3 ] || "px" ) !== "px" ) {
7073
7074 elem.style[ dimension ] = value;
7075 value = jQuery.css( elem, dimension );
7076 }
7077
7078 return setPositiveNumber( elem, value, subtract );
7079 }
7080 };
7081 } );
7082
7083 jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7084 function( elem, computed ) {
7085 if ( computed ) {
7086 return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
7087 elem.getBoundingClientRect().left -
7088 swap( elem, { marginLeft: 0 }, function() {
7089 return elem.getBoundingClientRect().left;
7090 } )
7091 ) + "px";
7092 }
7093 }
7094 );
7095
7096 // These hooks are used by animate to expand properties
7097 jQuery.each( {
7098 margin: "",
7099 padding: "",
7100 border: "Width"
7101 }, function( prefix, suffix ) {
7102 jQuery.cssHooks[ prefix + suffix ] = {
7103 expand: function( value ) {
7104 var i = 0,
7105 expanded = {},
7106
7107 // Assumes a single number if not a string
7108 parts = typeof value === "string" ? value.split( " " ) : [ value ];
7109
7110 for ( ; i < 4; i++ ) {
7111 expanded[ prefix + cssExpand[ i ] + suffix ] =
7112 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7113 }
7114
7115 return expanded;
7116 }
7117 };
7118
7119 if ( prefix !== "margin" ) {
7120 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7121 }
7122 } );
7123
7124 jQuery.fn.extend( {
7125 css: function( name, value ) {
7126 return access( this, function( elem, name, value ) {
7127 var styles, len,
7128 map = {},
7129 i = 0;
7130
7131 if ( Array.isArray( name ) ) {
7132 styles = getStyles( elem );
7133 len = name.length;
7134
7135 for ( ; i < len; i++ ) {
7136 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7137 }
7138
7139 return map;
7140 }
7141
7142 return value !== undefined ?
7143 jQuery.style( elem, name, value ) :
7144 jQuery.css( elem, name );
7145 }, name, value, arguments.length > 1 );
7146 }
7147 } );
7148
7149
7150 function Tween( elem, options, prop, end, easing ) {
7151 return new Tween.prototype.init( elem, options, prop, end, easing );
7152 }
7153 jQuery.Tween = Tween;
7154
7155 Tween.prototype = {
7156 constructor: Tween,
7157 init: function( elem, options, prop, end, easing, unit ) {
7158 this.elem = elem;
7159 this.prop = prop;
7160 this.easing = easing || jQuery.easing._default;
7161 this.options = options;
7162 this.start = this.now = this.cur();
7163 this.end = end;
7164 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7165 },
7166 cur: function() {
7167 var hooks = Tween.propHooks[ this.prop ];
7168
7169 return hooks && hooks.get ?
7170 hooks.get( this ) :
7171 Tween.propHooks._default.get( this );
7172 },
7173 run: function( percent ) {
7174 var eased,
7175 hooks = Tween.propHooks[ this.prop ];
7176
7177 if ( this.options.duration ) {
7178 this.pos = eased = jQuery.easing[ this.easing ](
7179 percent, this.options.duration * percent, 0, 1, this.options.duration
7180 );
7181 } else {
7182 this.pos = eased = percent;
7183 }
7184 this.now = ( this.end - this.start ) * eased + this.start;
7185
7186 if ( this.options.step ) {
7187 this.options.step.call( this.elem, this.now, this );
7188 }
7189
7190 if ( hooks && hooks.set ) {
7191 hooks.set( this );
7192 } else {
7193 Tween.propHooks._default.set( this );
7194 }
7195 return this;
7196 }
7197 };
7198
7199 Tween.prototype.init.prototype = Tween.prototype;
7200
7201 Tween.propHooks = {
7202 _default: {
7203 get: function( tween ) {
7204 var result;
7205
7206 // Use a property on the element directly when it is not a DOM element,
7207 // or when there is no matching style property that exists.
7208 if ( tween.elem.nodeType !== 1 ||
7209 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7210 return tween.elem[ tween.prop ];
7211 }
7212
7213 // Passing an empty string as a 3rd parameter to .css will automatically
7214 // attempt a parseFloat and fallback to a string if the parse fails.
7215 // Simple values such as "10px" are parsed to Float;
7216 // complex values such as "rotate(1rad)" are returned as-is.
7217 result = jQuery.css( tween.elem, tween.prop, "" );
7218
7219 // Empty strings, null, undefined and "auto" are converted to 0.
7220 return !result || result === "auto" ? 0 : result;
7221 },
7222 set: function( tween ) {
7223
7224 // Use step hook for back compat.
7225 // Use cssHook if its there.
7226 // Use .style if available and use plain properties where available.
7227 if ( jQuery.fx.step[ tween.prop ] ) {
7228 jQuery.fx.step[ tween.prop ]( tween );
7229 } else if ( tween.elem.nodeType === 1 && (
7230 jQuery.cssHooks[ tween.prop ] ||
7231 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
7232 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7233 } else {
7234 tween.elem[ tween.prop ] = tween.now;
7235 }
7236 }
7237 }
7238 };
7239
7240 // Support: IE <=9 only
7241 // Panic based approach to setting things on disconnected nodes
7242 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7243 set: function( tween ) {
7244 if ( tween.elem.nodeType && tween.elem.parentNode ) {
7245 tween.elem[ tween.prop ] = tween.now;
7246 }
7247 }
7248 };
7249
7250 jQuery.easing = {
7251 linear: function( p ) {
7252 return p;
7253 },
7254 swing: function( p ) {
7255 return 0.5 - Math.cos( p * Math.PI ) / 2;
7256 },
7257 _default: "swing"
7258 };
7259
7260 jQuery.fx = Tween.prototype.init;
7261
7262 // Back compat <1.8 extension point
7263 jQuery.fx.step = {};
7264
7265
7266
7267
7268 var
7269 fxNow, inProgress,
7270 rfxtypes = /^(?:toggle|show|hide)$/,
7271 rrun = /queueHooks$/;
7272
7273 function schedule() {
7274 if ( inProgress ) {
7275 if ( document.hidden === false && window.requestAnimationFrame ) {
7276 window.requestAnimationFrame( schedule );
7277 } else {
7278 window.setTimeout( schedule, jQuery.fx.interval );
7279 }
7280
7281 jQuery.fx.tick();
7282 }
7283 }
7284
7285 // Animations created synchronously will run synchronously
7286 function createFxNow() {
7287 window.setTimeout( function() {
7288 fxNow = undefined;
7289 } );
7290 return ( fxNow = Date.now() );
7291 }
7292
7293 // Generate parameters to create a standard animation
7294 function genFx( type, includeWidth ) {
7295 var which,
7296 i = 0,
7297 attrs = { height: type };
7298
7299 // If we include width, step value is 1 to do all cssExpand values,
7300 // otherwise step value is 2 to skip over Left and Right
7301 includeWidth = includeWidth ? 1 : 0;
7302 for ( ; i < 4; i += 2 - includeWidth ) {
7303 which = cssExpand[ i ];
7304 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7305 }
7306
7307 if ( includeWidth ) {
7308 attrs.opacity = attrs.width = type;
7309 }
7310
7311 return attrs;
7312 }
7313
7314 function createTween( value, prop, animation ) {
7315 var tween,
7316 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7317 index = 0,
7318 length = collection.length;
7319 for ( ; index < length; index++ ) {
7320 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7321
7322 // We're done with this property
7323 return tween;
7324 }
7325 }
7326 }
7327
7328 function defaultPrefilter( elem, props, opts ) {
7329 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
7330 isBox = "width" in props || "height" in props,
7331 anim = this,
7332 orig = {},
7333 style = elem.style,
7334 hidden = elem.nodeType && isHiddenWithinTree( elem ),
7335 dataShow = dataPriv.get( elem, "fxshow" );
7336
7337 // Queue-skipping animations hijack the fx hooks
7338 if ( !opts.queue ) {
7339 hooks = jQuery._queueHooks( elem, "fx" );
7340 if ( hooks.unqueued == null ) {
7341 hooks.unqueued = 0;
7342 oldfire = hooks.empty.fire;
7343 hooks.empty.fire = function() {
7344 if ( !hooks.unqueued ) {
7345 oldfire();
7346 }
7347 };
7348 }
7349 hooks.unqueued++;
7350
7351 anim.always( function() {
7352
7353 // Ensure the complete handler is called before this completes
7354 anim.always( function() {
7355 hooks.unqueued--;
7356 if ( !jQuery.queue( elem, "fx" ).length ) {
7357 hooks.empty.fire();
7358 }
7359 } );
7360 } );
7361 }
7362
7363 // Detect show/hide animations
7364 for ( prop in props ) {
7365 value = props[ prop ];
7366 if ( rfxtypes.test( value ) ) {
7367 delete props[ prop ];
7368 toggle = toggle || value === "toggle";
7369 if ( value === ( hidden ? "hide" : "show" ) ) {
7370
7371 // Pretend to be hidden if this is a "show" and
7372 // there is still data from a stopped show/hide
7373 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7374 hidden = true;
7375
7376 // Ignore all other no-op show/hide data
7377 } else {
7378 continue;
7379 }
7380 }
7381 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7382 }
7383 }
7384
7385 // Bail out if this is a no-op like .hide().hide()
7386 propTween = !jQuery.isEmptyObject( props );
7387 if ( !propTween && jQuery.isEmptyObject( orig ) ) {
7388 return;
7389 }
7390
7391 // Restrict "overflow" and "display" styles during box animations
7392 if ( isBox && elem.nodeType === 1 ) {
7393
7394 // Support: IE <=9 - 11, Edge 12 - 15
7395 // Record all 3 overflow attributes because IE does not infer the shorthand
7396 // from identically-valued overflowX and overflowY and Edge just mirrors
7397 // the overflowX value there.
7398 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7399
7400 // Identify a display type, preferring old show/hide data over the CSS cascade
7401 restoreDisplay = dataShow && dataShow.display;
7402 if ( restoreDisplay == null ) {
7403 restoreDisplay = dataPriv.get( elem, "display" );
7404 }
7405 display = jQuery.css( elem, "display" );
7406 if ( display === "none" ) {
7407 if ( restoreDisplay ) {
7408 display = restoreDisplay;
7409 } else {
7410
7411 // Get nonempty value(s) by temporarily forcing visibility
7412 showHide( [ elem ], true );
7413 restoreDisplay = elem.style.display || restoreDisplay;
7414 display = jQuery.css( elem, "display" );
7415 showHide( [ elem ] );
7416 }
7417 }
7418
7419 // Animate inline elements as inline-block
7420 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
7421 if ( jQuery.css( elem, "float" ) === "none" ) {
7422
7423 // Restore the original display value at the end of pure show/hide animations
7424 if ( !propTween ) {
7425 anim.done( function() {
7426 style.display = restoreDisplay;
7427 } );
7428 if ( restoreDisplay == null ) {
7429 display = style.display;
7430 restoreDisplay = display === "none" ? "" : display;
7431 }
7432 }
7433 style.display = "inline-block";
7434 }
7435 }
7436 }
7437
7438 if ( opts.overflow ) {
7439 style.overflow = "hidden";
7440 anim.always( function() {
7441 style.overflow = opts.overflow[ 0 ];
7442 style.overflowX = opts.overflow[ 1 ];
7443 style.overflowY = opts.overflow[ 2 ];
7444 } );
7445 }
7446
7447 // Implement show/hide animations
7448 propTween = false;
7449 for ( prop in orig ) {
7450
7451 // General show/hide setup for this element animation
7452 if ( !propTween ) {
7453 if ( dataShow ) {
7454 if ( "hidden" in dataShow ) {
7455 hidden = dataShow.hidden;
7456 }
7457 } else {
7458 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
7459 }
7460
7461 // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
7462 if ( toggle ) {
7463 dataShow.hidden = !hidden;
7464 }
7465
7466 // Show elements before animating them
7467 if ( hidden ) {
7468 showHide( [ elem ], true );
7469 }
7470
7471 /* eslint-disable no-loop-func */
7472
7473 anim.done( function() {
7474
7475 /* eslint-enable no-loop-func */
7476
7477 // The final step of a "hide" animation is actually hiding the element
7478 if ( !hidden ) {
7479 showHide( [ elem ] );
7480 }
7481 dataPriv.remove( elem, "fxshow" );
7482 for ( prop in orig ) {
7483 jQuery.style( elem, prop, orig[ prop ] );
7484 }
7485 } );
7486 }
7487
7488 // Per-property setup
7489 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7490 if ( !( prop in dataShow ) ) {
7491 dataShow[ prop ] = propTween.start;
7492 if ( hidden ) {
7493 propTween.end = propTween.start;
7494 propTween.start = 0;
7495 }
7496 }
7497 }
7498 }
7499
7500 function propFilter( props, specialEasing ) {
7501 var index, name, easing, value, hooks;
7502
7503 // camelCase, specialEasing and expand cssHook pass
7504 for ( index in props ) {
7505 name = camelCase( index );
7506 easing = specialEasing[ name ];
7507 value = props[ index ];
7508 if ( Array.isArray( value ) ) {
7509 easing = value[ 1 ];
7510 value = props[ index ] = value[ 0 ];
7511 }
7512
7513 if ( index !== name ) {
7514 props[ name ] = value;
7515 delete props[ index ];
7516 }
7517
7518 hooks = jQuery.cssHooks[ name ];
7519 if ( hooks && "expand" in hooks ) {
7520 value = hooks.expand( value );
7521 delete props[ name ];
7522
7523 // Not quite $.extend, this won't overwrite existing keys.
7524 // Reusing 'index' because we have the correct "name"
7525 for ( index in value ) {
7526 if ( !( index in props ) ) {
7527 props[ index ] = value[ index ];
7528 specialEasing[ index ] = easing;
7529 }
7530 }
7531 } else {
7532 specialEasing[ name ] = easing;
7533 }
7534 }
7535 }
7536
7537 function Animation( elem, properties, options ) {
7538 var result,
7539 stopped,
7540 index = 0,
7541 length = Animation.prefilters.length,
7542 deferred = jQuery.Deferred().always( function() {
7543
7544 // Don't match elem in the :animated selector
7545 delete tick.elem;
7546 } ),
7547 tick = function() {
7548 if ( stopped ) {
7549 return false;
7550 }
7551 var currentTime = fxNow || createFxNow(),
7552 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7553
7554 // Support: Android 2.3 only
7555 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7556 temp = remaining / animation.duration || 0,
7557 percent = 1 - temp,
7558 index = 0,
7559 length = animation.tweens.length;
7560
7561 for ( ; index < length; index++ ) {
7562 animation.tweens[ index ].run( percent );
7563 }
7564
7565 deferred.notifyWith( elem, [ animation, percent, remaining ] );
7566
7567 // If there's more to do, yield
7568 if ( percent < 1 && length ) {
7569 return remaining;
7570 }
7571
7572 // If this was an empty animation, synthesize a final progress notification
7573 if ( !length ) {
7574 deferred.notifyWith( elem, [ animation, 1, 0 ] );
7575 }
7576
7577 // Resolve the animation and report its conclusion
7578 deferred.resolveWith( elem, [ animation ] );
7579 return false;
7580 },
7581 animation = deferred.promise( {
7582 elem: elem,
7583 props: jQuery.extend( {}, properties ),
7584 opts: jQuery.extend( true, {
7585 specialEasing: {},
7586 easing: jQuery.easing._default
7587 }, options ),
7588 originalProperties: properties,
7589 originalOptions: options,
7590 startTime: fxNow || createFxNow(),
7591 duration: options.duration,
7592 tweens: [],
7593 createTween: function( prop, end ) {
7594 var tween = jQuery.Tween( elem, animation.opts, prop, end,
7595 animation.opts.specialEasing[ prop ] || animation.opts.easing );
7596 animation.tweens.push( tween );
7597 return tween;
7598 },
7599 stop: function( gotoEnd ) {
7600 var index = 0,
7601
7602 // If we are going to the end, we want to run all the tweens
7603 // otherwise we skip this part
7604 length = gotoEnd ? animation.tweens.length : 0;
7605 if ( stopped ) {
7606 return this;
7607 }
7608 stopped = true;
7609 for ( ; index < length; index++ ) {
7610 animation.tweens[ index ].run( 1 );
7611 }
7612
7613 // Resolve when we played the last frame; otherwise, reject
7614 if ( gotoEnd ) {
7615 deferred.notifyWith( elem, [ animation, 1, 0 ] );
7616 deferred.resolveWith( elem, [ animation, gotoEnd ] );
7617 } else {
7618 deferred.rejectWith( elem, [ animation, gotoEnd ] );
7619 }
7620 return this;
7621 }
7622 } ),
7623 props = animation.props;
7624
7625 propFilter( props, animation.opts.specialEasing );
7626
7627 for ( ; index < length; index++ ) {
7628 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7629 if ( result ) {
7630 if ( isFunction( result.stop ) ) {
7631 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7632 result.stop.bind( result );
7633 }
7634 return result;
7635 }
7636 }
7637
7638 jQuery.map( props, createTween, animation );
7639
7640 if ( isFunction( animation.opts.start ) ) {
7641 animation.opts.start.call( elem, animation );
7642 }
7643
7644 // Attach callbacks from options
7645 animation
7646 .progress( animation.opts.progress )
7647 .done( animation.opts.done, animation.opts.complete )
7648 .fail( animation.opts.fail )
7649 .always( animation.opts.always );
7650
7651 jQuery.fx.timer(
7652 jQuery.extend( tick, {
7653 elem: elem,
7654 anim: animation,
7655 queue: animation.opts.queue
7656 } )
7657 );
7658
7659 return animation;
7660 }
7661
7662 jQuery.Animation = jQuery.extend( Animation, {
7663
7664 tweeners: {
7665 "*": [ function( prop, value ) {
7666 var tween = this.createTween( prop, value );
7667 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7668 return tween;
7669 } ]
7670 },
7671
7672 tweener: function( props, callback ) {
7673 if ( isFunction( props ) ) {
7674 callback = props;
7675 props = [ "*" ];
7676 } else {
7677 props = props.match( rnothtmlwhite );
7678 }
7679
7680 var prop,
7681 index = 0,
7682 length = props.length;
7683
7684 for ( ; index < length; index++ ) {
7685 prop = props[ index ];
7686 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7687 Animation.tweeners[ prop ].unshift( callback );
7688 }
7689 },
7690
7691 prefilters: [ defaultPrefilter ],
7692
7693 prefilter: function( callback, prepend ) {
7694 if ( prepend ) {
7695 Animation.prefilters.unshift( callback );
7696 } else {
7697 Animation.prefilters.push( callback );
7698 }
7699 }
7700 } );
7701
7702 jQuery.speed = function( speed, easing, fn ) {
7703 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7704 complete: fn || !fn && easing ||
7705 isFunction( speed ) && speed,
7706 duration: speed,
7707 easing: fn && easing || easing && !isFunction( easing ) && easing
7708 };
7709
7710 // Go to the end state if fx are off
7711 if ( jQuery.fx.off ) {
7712 opt.duration = 0;
7713
7714 } else {
7715 if ( typeof opt.duration !== "number" ) {
7716 if ( opt.duration in jQuery.fx.speeds ) {
7717 opt.duration = jQuery.fx.speeds[ opt.duration ];
7718
7719 } else {
7720 opt.duration = jQuery.fx.speeds._default;
7721 }
7722 }
7723 }
7724
7725 // Normalize opt.queue - true/undefined/null -> "fx"
7726 if ( opt.queue == null || opt.queue === true ) {
7727 opt.queue = "fx";
7728 }
7729
7730 // Queueing
7731 opt.old = opt.complete;
7732
7733 opt.complete = function() {
7734 if ( isFunction( opt.old ) ) {
7735 opt.old.call( this );
7736 }
7737
7738 if ( opt.queue ) {
7739 jQuery.dequeue( this, opt.queue );
7740 }
7741 };
7742
7743 return opt;
7744 };
7745
7746 jQuery.fn.extend( {
7747 fadeTo: function( speed, to, easing, callback ) {
7748
7749 // Show any hidden elements after setting opacity to 0
7750 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
7751
7752 // Animate to the value specified
7753 .end().animate( { opacity: to }, speed, easing, callback );
7754 },
7755 animate: function( prop, speed, easing, callback ) {
7756 var empty = jQuery.isEmptyObject( prop ),
7757 optall = jQuery.speed( speed, easing, callback ),
7758 doAnimation = function() {
7759
7760 // Operate on a copy of prop so per-property easing won't be lost
7761 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7762
7763 // Empty animations, or finishing resolves immediately
7764 if ( empty || dataPriv.get( this, "finish" ) ) {
7765 anim.stop( true );
7766 }
7767 };
7768
7769 doAnimation.finish = doAnimation;
7770
7771 return empty || optall.queue === false ?
7772 this.each( doAnimation ) :
7773 this.queue( optall.queue, doAnimation );
7774 },
7775 stop: function( type, clearQueue, gotoEnd ) {
7776 var stopQueue = function( hooks ) {
7777 var stop = hooks.stop;
7778 delete hooks.stop;
7779 stop( gotoEnd );
7780 };
7781
7782 if ( typeof type !== "string" ) {
7783 gotoEnd = clearQueue;
7784 clearQueue = type;
7785 type = undefined;
7786 }
7787 if ( clearQueue ) {
7788 this.queue( type || "fx", [] );
7789 }
7790
7791 return this.each( function() {
7792 var dequeue = true,
7793 index = type != null && type + "queueHooks",
7794 timers = jQuery.timers,
7795 data = dataPriv.get( this );
7796
7797 if ( index ) {
7798 if ( data[ index ] && data[ index ].stop ) {
7799 stopQueue( data[ index ] );
7800 }
7801 } else {
7802 for ( index in data ) {
7803 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7804 stopQueue( data[ index ] );
7805 }
7806 }
7807 }
7808
7809 for ( index = timers.length; index--; ) {
7810 if ( timers[ index ].elem === this &&
7811 ( type == null || timers[ index ].queue === type ) ) {
7812
7813 timers[ index ].anim.stop( gotoEnd );
7814 dequeue = false;
7815 timers.splice( index, 1 );
7816 }
7817 }
7818
7819 // Start the next in the queue if the last step wasn't forced.
7820 // Timers currently will call their complete callbacks, which
7821 // will dequeue but only if they were gotoEnd.
7822 if ( dequeue || !gotoEnd ) {
7823 jQuery.dequeue( this, type );
7824 }
7825 } );
7826 },
7827 finish: function( type ) {
7828 if ( type !== false ) {
7829 type = type || "fx";
7830 }
7831 return this.each( function() {
7832 var index,
7833 data = dataPriv.get( this ),
7834 queue = data[ type + "queue" ],
7835 hooks = data[ type + "queueHooks" ],
7836 timers = jQuery.timers,
7837 length = queue ? queue.length : 0;
7838
7839 // Enable finishing flag on private data
7840 data.finish = true;
7841
7842 // Empty the queue first
7843 jQuery.queue( this, type, [] );
7844
7845 if ( hooks && hooks.stop ) {
7846 hooks.stop.call( this, true );
7847 }
7848
7849 // Look for any active animations, and finish them
7850 for ( index = timers.length; index--; ) {
7851 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7852 timers[ index ].anim.stop( true );
7853 timers.splice( index, 1 );
7854 }
7855 }
7856
7857 // Look for any animations in the old queue and finish them
7858 for ( index = 0; index < length; index++ ) {
7859 if ( queue[ index ] && queue[ index ].finish ) {
7860 queue[ index ].finish.call( this );
7861 }
7862 }
7863
7864 // Turn off finishing flag
7865 delete data.finish;
7866 } );
7867 }
7868 } );
7869
7870 jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
7871 var cssFn = jQuery.fn[ name ];
7872 jQuery.fn[ name ] = function( speed, easing, callback ) {
7873 return speed == null || typeof speed === "boolean" ?
7874 cssFn.apply( this, arguments ) :
7875 this.animate( genFx( name, true ), speed, easing, callback );
7876 };
7877 } );
7878
7879 // Generate shortcuts for custom animations
7880 jQuery.each( {
7881 slideDown: genFx( "show" ),
7882 slideUp: genFx( "hide" ),
7883 slideToggle: genFx( "toggle" ),
7884 fadeIn: { opacity: "show" },
7885 fadeOut: { opacity: "hide" },
7886 fadeToggle: { opacity: "toggle" }
7887 }, function( name, props ) {
7888 jQuery.fn[ name ] = function( speed, easing, callback ) {
7889 return this.animate( props, speed, easing, callback );
7890 };
7891 } );
7892
7893 jQuery.timers = [];
7894 jQuery.fx.tick = function() {
7895 var timer,
7896 i = 0,
7897 timers = jQuery.timers;
7898
7899 fxNow = Date.now();
7900
7901 for ( ; i < timers.length; i++ ) {
7902 timer = timers[ i ];
7903
7904 // Run the timer and safely remove it when done (allowing for external removal)
7905 if ( !timer() && timers[ i ] === timer ) {
7906 timers.splice( i--, 1 );
7907 }
7908 }
7909
7910 if ( !timers.length ) {
7911 jQuery.fx.stop();
7912 }
7913 fxNow = undefined;
7914 };
7915
7916 jQuery.fx.timer = function( timer ) {
7917 jQuery.timers.push( timer );
7918 jQuery.fx.start();
7919 };
7920
7921 jQuery.fx.interval = 13;
7922 jQuery.fx.start = function() {
7923 if ( inProgress ) {
7924 return;
7925 }
7926
7927 inProgress = true;
7928 schedule();
7929 };
7930
7931 jQuery.fx.stop = function() {
7932 inProgress = null;
7933 };
7934
7935 jQuery.fx.speeds = {
7936 slow: 600,
7937 fast: 200,
7938
7939 // Default speed
7940 _default: 400
7941 };
7942
7943
7944 // Based off of the plugin by Clint Helfers, with permission.
7945 // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7946 jQuery.fn.delay = function( time, type ) {
7947 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7948 type = type || "fx";
7949
7950 return this.queue( type, function( next, hooks ) {
7951 var timeout = window.setTimeout( next, time );
7952 hooks.stop = function() {
7953 window.clearTimeout( timeout );
7954 };
7955 } );
7956 };
7957
7958
7959 ( function() {
7960 var input = document.createElement( "input" ),
7961 select = document.createElement( "select" ),
7962 opt = select.appendChild( document.createElement( "option" ) );
7963
7964 input.type = "checkbox";
7965
7966 // Support: Android <=4.3 only
7967 // Default value for a checkbox should be "on"
7968 support.checkOn = input.value !== "";
7969
7970 // Support: IE <=11 only
7971 // Must access selectedIndex to make default options select
7972 support.optSelected = opt.selected;
7973
7974 // Support: IE <=11 only
7975 // An input loses its value after becoming a radio
7976 input = document.createElement( "input" );
7977 input.value = "t";
7978 input.type = "radio";
7979 support.radioValue = input.value === "t";
7980 } )();
7981
7982
7983 var boolHook,
7984 attrHandle = jQuery.expr.attrHandle;
7985
7986 jQuery.fn.extend( {
7987 attr: function( name, value ) {
7988 return access( this, jQuery.attr, name, value, arguments.length > 1 );
7989 },
7990
7991 removeAttr: function( name ) {
7992 return this.each( function() {
7993 jQuery.removeAttr( this, name );
7994 } );
7995 }
7996 } );
7997
7998 jQuery.extend( {
7999 attr: function( elem, name, value ) {
8000 var ret, hooks,
8001 nType = elem.nodeType;
8002
8003 // Don't get/set attributes on text, comment and attribute nodes
8004 if ( nType === 3 || nType === 8 || nType === 2 ) {
8005 return;
8006 }
8007
8008 // Fallback to prop when attributes are not supported
8009 if ( typeof elem.getAttribute === "undefined" ) {
8010 return jQuery.prop( elem, name, value );
8011 }
8012
8013 // Attribute hooks are determined by the lowercase version
8014 // Grab necessary hook if one is defined
8015 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8016 hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
8017 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
8018 }
8019
8020 if ( value !== undefined ) {
8021 if ( value === null ) {
8022 jQuery.removeAttr( elem, name );
8023 return;
8024 }
8025
8026 if ( hooks && "set" in hooks &&
8027 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8028 return ret;
8029 }
8030
8031 elem.setAttribute( name, value + "" );
8032 return value;
8033 }
8034
8035 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8036 return ret;
8037 }
8038
8039 ret = jQuery.find.attr( elem, name );
8040
8041 // Non-existent attributes return null, we normalize to undefined
8042 return ret == null ? undefined : ret;
8043 },
8044
8045 attrHooks: {
8046 type: {
8047 set: function( elem, value ) {
8048 if ( !support.radioValue && value === "radio" &&
8049 nodeName( elem, "input" ) ) {
8050 var val = elem.value;
8051 elem.setAttribute( "type", value );
8052 if ( val ) {
8053 elem.value = val;
8054 }
8055 return value;
8056 }
8057 }
8058 }
8059 },
8060
8061 removeAttr: function( elem, value ) {
8062 var name,
8063 i = 0,
8064
8065 // Attribute names can contain non-HTML whitespace characters
8066 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
8067 attrNames = value && value.match( rnothtmlwhite );
8068
8069 if ( attrNames && elem.nodeType === 1 ) {
8070 while ( ( name = attrNames[ i++ ] ) ) {
8071 elem.removeAttribute( name );
8072 }
8073 }
8074 }
8075 } );
8076
8077 // Hooks for boolean attributes
8078 boolHook = {
8079 set: function( elem, value, name ) {
8080 if ( value === false ) {
8081
8082 // Remove boolean attributes when set to false
8083 jQuery.removeAttr( elem, name );
8084 } else {
8085 elem.setAttribute( name, name );
8086 }
8087 return name;
8088 }
8089 };
8090
8091 jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
8092 var getter = attrHandle[ name ] || jQuery.find.attr;
8093
8094 attrHandle[ name ] = function( elem, name, isXML ) {
8095 var ret, handle,
8096 lowercaseName = name.toLowerCase();
8097
8098 if ( !isXML ) {
8099
8100 // Avoid an infinite loop by temporarily removing this function from the getter
8101 handle = attrHandle[ lowercaseName ];
8102 attrHandle[ lowercaseName ] = ret;
8103 ret = getter( elem, name, isXML ) != null ?
8104 lowercaseName :
8105 null;
8106 attrHandle[ lowercaseName ] = handle;
8107 }
8108 return ret;
8109 };
8110 } );
8111
8112
8113
8114
8115 var rfocusable = /^(?:input|select|textarea|button)$/i,
8116 rclickable = /^(?:a|area)$/i;
8117
8118 jQuery.fn.extend( {
8119 prop: function( name, value ) {
8120 return access( this, jQuery.prop, name, value, arguments.length > 1 );
8121 },
8122
8123 removeProp: function( name ) {
8124 return this.each( function() {
8125 delete this[ jQuery.propFix[ name ] || name ];
8126 } );
8127 }
8128 } );
8129
8130 jQuery.extend( {
8131 prop: function( elem, name, value ) {
8132 var ret, hooks,
8133 nType = elem.nodeType;
8134
8135 // Don't get/set properties on text, comment and attribute nodes
8136 if ( nType === 3 || nType === 8 || nType === 2 ) {
8137 return;
8138 }
8139
8140 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8141
8142 // Fix name and attach hooks
8143 name = jQuery.propFix[ name ] || name;
8144 hooks = jQuery.propHooks[ name ];
8145 }
8146
8147 if ( value !== undefined ) {
8148 if ( hooks && "set" in hooks &&
8149 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8150 return ret;
8151 }
8152
8153 return ( elem[ name ] = value );
8154 }
8155
8156 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8157 return ret;
8158 }
8159
8160 return elem[ name ];
8161 },
8162
8163 propHooks: {
8164 tabIndex: {
8165 get: function( elem ) {
8166
8167 // Support: IE <=9 - 11 only
8168 // elem.tabIndex doesn't always return the
8169 // correct value when it hasn't been explicitly set
8170 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8171 // Use proper attribute retrieval(#12072)
8172 var tabindex = jQuery.find.attr( elem, "tabindex" );
8173
8174 if ( tabindex ) {
8175 return parseInt( tabindex, 10 );
8176 }
8177
8178 if (
8179 rfocusable.test( elem.nodeName ) ||
8180 rclickable.test( elem.nodeName ) &&
8181 elem.href
8182 ) {
8183 return 0;
8184 }
8185
8186 return -1;
8187 }
8188 }
8189 },
8190
8191 propFix: {
8192 "for": "htmlFor",
8193 "class": "className"
8194 }
8195 } );
8196
8197 // Support: IE <=11 only
8198 // Accessing the selectedIndex property
8199 // forces the browser to respect setting selected
8200 // on the option
8201 // The getter ensures a default option is selected
8202 // when in an optgroup
8203 // eslint rule "no-unused-expressions" is disabled for this code
8204 // since it considers such accessions noop
8205 if ( !support.optSelected ) {
8206 jQuery.propHooks.selected = {
8207 get: function( elem ) {
8208
8209 /* eslint no-unused-expressions: "off" */
8210
8211 var parent = elem.parentNode;
8212 if ( parent && parent.parentNode ) {
8213 parent.parentNode.selectedIndex;
8214 }
8215 return null;
8216 },
8217 set: function( elem ) {
8218
8219 /* eslint no-unused-expressions: "off" */
8220
8221 var parent = elem.parentNode;
8222 if ( parent ) {
8223 parent.selectedIndex;
8224
8225 if ( parent.parentNode ) {
8226 parent.parentNode.selectedIndex;
8227 }
8228 }
8229 }
8230 };
8231 }
8232
8233 jQuery.each( [
8234 "tabIndex",
8235 "readOnly",
8236 "maxLength",
8237 "cellSpacing",
8238 "cellPadding",
8239 "rowSpan",
8240 "colSpan",
8241 "useMap",
8242 "frameBorder",
8243 "contentEditable"
8244 ], function() {
8245 jQuery.propFix[ this.toLowerCase() ] = this;
8246 } );
8247
8248
8249
8250
8251 // Strip and collapse whitespace according to HTML spec
8252 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
8253 function stripAndCollapse( value ) {
8254 var tokens = value.match( rnothtmlwhite ) || [];
8255 return tokens.join( " " );
8256 }
8257
8258
8259 function getClass( elem ) {
8260 return elem.getAttribute && elem.getAttribute( "class" ) || "";
8261 }
8262
8263 function classesToArray( value ) {
8264 if ( Array.isArray( value ) ) {
8265 return value;
8266 }
8267 if ( typeof value === "string" ) {
8268 return value.match( rnothtmlwhite ) || [];
8269 }
8270 return [];
8271 }
8272
8273 jQuery.fn.extend( {
8274 addClass: function( value ) {
8275 var classes, elem, cur, curValue, clazz, j, finalValue,
8276 i = 0;
8277
8278 if ( isFunction( value ) ) {
8279 return this.each( function( j ) {
8280 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8281 } );
8282 }
8283
8284 classes = classesToArray( value );
8285
8286 if ( classes.length ) {
8287 while ( ( elem = this[ i++ ] ) ) {
8288 curValue = getClass( elem );
8289 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8290
8291 if ( cur ) {
8292 j = 0;
8293 while ( ( clazz = classes[ j++ ] ) ) {
8294 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8295 cur += clazz + " ";
8296 }
8297 }
8298
8299 // Only assign if different to avoid unneeded rendering.
8300 finalValue = stripAndCollapse( cur );
8301 if ( curValue !== finalValue ) {
8302 elem.setAttribute( "class", finalValue );
8303 }
8304 }
8305 }
8306 }
8307
8308 return this;
8309 },
8310
8311 removeClass: function( value ) {
8312 var classes, elem, cur, curValue, clazz, j, finalValue,
8313 i = 0;
8314
8315 if ( isFunction( value ) ) {
8316 return this.each( function( j ) {
8317 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8318 } );
8319 }
8320
8321 if ( !arguments.length ) {
8322 return this.attr( "class", "" );
8323 }
8324
8325 classes = classesToArray( value );
8326
8327 if ( classes.length ) {
8328 while ( ( elem = this[ i++ ] ) ) {
8329 curValue = getClass( elem );
8330
8331 // This expression is here for better compressibility (see addClass)
8332 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8333
8334 if ( cur ) {
8335 j = 0;
8336 while ( ( clazz = classes[ j++ ] ) ) {
8337
8338 // Remove *all* instances
8339 while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
8340 cur = cur.replace( " " + clazz + " ", " " );
8341 }
8342 }
8343
8344 // Only assign if different to avoid unneeded rendering.
8345 finalValue = stripAndCollapse( cur );
8346 if ( curValue !== finalValue ) {
8347 elem.setAttribute( "class", finalValue );
8348 }
8349 }
8350 }
8351 }
8352
8353 return this;
8354 },
8355
8356 toggleClass: function( value, stateVal ) {
8357 var type = typeof value,
8358 isValidValue = type === "string" || Array.isArray( value );
8359
8360 if ( typeof stateVal === "boolean" && isValidValue ) {
8361 return stateVal ? this.addClass( value ) : this.removeClass( value );
8362 }
8363
8364 if ( isFunction( value ) ) {
8365 return this.each( function( i ) {
8366 jQuery( this ).toggleClass(
8367 value.call( this, i, getClass( this ), stateVal ),
8368 stateVal
8369 );
8370 } );
8371 }
8372
8373 return this.each( function() {
8374 var className, i, self, classNames;
8375
8376 if ( isValidValue ) {
8377
8378 // Toggle individual class names
8379 i = 0;
8380 self = jQuery( this );
8381 classNames = classesToArray( value );
8382
8383 while ( ( className = classNames[ i++ ] ) ) {
8384
8385 // Check each className given, space separated list
8386 if ( self.hasClass( className ) ) {
8387 self.removeClass( className );
8388 } else {
8389 self.addClass( className );
8390 }
8391 }
8392
8393 // Toggle whole class name
8394 } else if ( value === undefined || type === "boolean" ) {
8395 className = getClass( this );
8396 if ( className ) {
8397
8398 // Store className if set
8399 dataPriv.set( this, "__className__", className );
8400 }
8401
8402 // If the element has a class name or if we're passed `false`,
8403 // then remove the whole classname (if there was one, the above saved it).
8404 // Otherwise bring back whatever was previously saved (if anything),
8405 // falling back to the empty string if nothing was stored.
8406 if ( this.setAttribute ) {
8407 this.setAttribute( "class",
8408 className || value === false ?
8409 "" :
8410 dataPriv.get( this, "__className__" ) || ""
8411 );
8412 }
8413 }
8414 } );
8415 },
8416
8417 hasClass: function( selector ) {
8418 var className, elem,
8419 i = 0;
8420
8421 className = " " + selector + " ";
8422 while ( ( elem = this[ i++ ] ) ) {
8423 if ( elem.nodeType === 1 &&
8424 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
8425 return true;
8426 }
8427 }
8428
8429 return false;
8430 }
8431 } );
8432
8433
8434
8435
8436 var rreturn = /\r/g;
8437
8438 jQuery.fn.extend( {
8439 val: function( value ) {
8440 var hooks, ret, valueIsFunction,
8441 elem = this[ 0 ];
8442
8443 if ( !arguments.length ) {
8444 if ( elem ) {
8445 hooks = jQuery.valHooks[ elem.type ] ||
8446 jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8447
8448 if ( hooks &&
8449 "get" in hooks &&
8450 ( ret = hooks.get( elem, "value" ) ) !== undefined
8451 ) {
8452 return ret;
8453 }
8454
8455 ret = elem.value;
8456
8457 // Handle most common string cases
8458 if ( typeof ret === "string" ) {
8459 return ret.replace( rreturn, "" );
8460 }
8461
8462 // Handle cases where value is null/undef or number
8463 return ret == null ? "" : ret;
8464 }
8465
8466 return;
8467 }
8468
8469 valueIsFunction = isFunction( value );
8470
8471 return this.each( function( i ) {
8472 var val;
8473
8474 if ( this.nodeType !== 1 ) {
8475 return;
8476 }
8477
8478 if ( valueIsFunction ) {
8479 val = value.call( this, i, jQuery( this ).val() );
8480 } else {
8481 val = value;
8482 }
8483
8484 // Treat null/undefined as ""; convert numbers to string
8485 if ( val == null ) {
8486 val = "";
8487
8488 } else if ( typeof val === "number" ) {
8489 val += "";
8490
8491 } else if ( Array.isArray( val ) ) {
8492 val = jQuery.map( val, function( value ) {
8493 return value == null ? "" : value + "";
8494 } );
8495 }
8496
8497 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8498
8499 // If set returns undefined, fall back to normal setting
8500 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8501 this.value = val;
8502 }
8503 } );
8504 }
8505 } );
8506
8507 jQuery.extend( {
8508 valHooks: {
8509 option: {
8510 get: function( elem ) {
8511
8512 var val = jQuery.find.attr( elem, "value" );
8513 return val != null ?
8514 val :
8515
8516 // Support: IE <=10 - 11 only
8517 // option.text throws exceptions (#14686, #14858)
8518 // Strip and collapse whitespace
8519 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8520 stripAndCollapse( jQuery.text( elem ) );
8521 }
8522 },
8523 select: {
8524 get: function( elem ) {
8525 var value, option, i,
8526 options = elem.options,
8527 index = elem.selectedIndex,
8528 one = elem.type === "select-one",
8529 values = one ? null : [],
8530 max = one ? index + 1 : options.length;
8531
8532 if ( index < 0 ) {
8533 i = max;
8534
8535 } else {
8536 i = one ? index : 0;
8537 }
8538
8539 // Loop through all the selected options
8540 for ( ; i < max; i++ ) {
8541 option = options[ i ];
8542
8543 // Support: IE <=9 only
8544 // IE8-9 doesn't update selected after form reset (#2551)
8545 if ( ( option.selected || i === index ) &&
8546
8547 // Don't return options that are disabled or in a disabled optgroup
8548 !option.disabled &&
8549 ( !option.parentNode.disabled ||
8550 !nodeName( option.parentNode, "optgroup" ) ) ) {
8551
8552 // Get the specific value for the option
8553 value = jQuery( option ).val();
8554
8555 // We don't need an array for one selects
8556 if ( one ) {
8557 return value;
8558 }
8559
8560 // Multi-Selects return an array
8561 values.push( value );
8562 }
8563 }
8564
8565 return values;
8566 },
8567
8568 set: function( elem, value ) {
8569 var optionSet, option,
8570 options = elem.options,
8571 values = jQuery.makeArray( value ),
8572 i = options.length;
8573
8574 while ( i-- ) {
8575 option = options[ i ];
8576
8577 /* eslint-disable no-cond-assign */
8578
8579 if ( option.selected =
8580 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
8581 ) {
8582 optionSet = true;
8583 }
8584
8585 /* eslint-enable no-cond-assign */
8586 }
8587
8588 // Force browsers to behave consistently when non-matching value is set
8589 if ( !optionSet ) {
8590 elem.selectedIndex = -1;
8591 }
8592 return values;
8593 }
8594 }
8595 }
8596 } );
8597
8598 // Radios and checkboxes getter/setter
8599 jQuery.each( [ "radio", "checkbox" ], function() {
8600 jQuery.valHooks[ this ] = {
8601 set: function( elem, value ) {
8602 if ( Array.isArray( value ) ) {
8603 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8604 }
8605 }
8606 };
8607 if ( !support.checkOn ) {
8608 jQuery.valHooks[ this ].get = function( elem ) {
8609 return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8610 };
8611 }
8612 } );
8613
8614
8615
8616
8617 // Return jQuery for attributes-only inclusion
8618
8619
8620 support.focusin = "onfocusin" in window;
8621
8622
8623 var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
8624 stopPropagationCallback = function( e ) {
8625 e.stopPropagation();
8626 };
8627
8628 jQuery.extend( jQuery.event, {
8629
8630 trigger: function( event, data, elem, onlyHandlers ) {
8631
8632 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
8633 eventPath = [ elem || document ],
8634 type = hasOwn.call( event, "type" ) ? event.type : event,
8635 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
8636
8637 cur = lastElement = tmp = elem = elem || document;
8638
8639 // Don't do events on text and comment nodes
8640 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
8641 return;
8642 }
8643
8644 // focus/blur morphs to focusin/out; ensure we're not firing them right now
8645 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
8646 return;
8647 }
8648
8649 if ( type.indexOf( "." ) > -1 ) {
8650
8651 // Namespaced trigger; create a regexp to match event type in handle()
8652 namespaces = type.split( "." );
8653 type = namespaces.shift();
8654 namespaces.sort();
8655 }
8656 ontype = type.indexOf( ":" ) < 0 && "on" + type;
8657
8658 // Caller can pass in a jQuery.Event object, Object, or just an event type string
8659 event = event[ jQuery.expando ] ?
8660 event :
8661 new jQuery.Event( type, typeof event === "object" && event );
8662
8663 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8664 event.isTrigger = onlyHandlers ? 2 : 3;
8665 event.namespace = namespaces.join( "." );
8666 event.rnamespace = event.namespace ?
8667 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
8668 null;
8669
8670 // Clean up the event in case it is being reused
8671 event.result = undefined;
8672 if ( !event.target ) {
8673 event.target = elem;
8674 }
8675
8676 // Clone any incoming data and prepend the event, creating the handler arg list
8677 data = data == null ?
8678 [ event ] :
8679 jQuery.makeArray( data, [ event ] );
8680
8681 // Allow special events to draw outside the lines
8682 special = jQuery.event.special[ type ] || {};
8683 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
8684 return;
8685 }
8686
8687 // Determine event propagation path in advance, per W3C events spec (#9951)
8688 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
8689 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
8690
8691 bubbleType = special.delegateType || type;
8692 if ( !rfocusMorph.test( bubbleType + type ) ) {
8693 cur = cur.parentNode;
8694 }
8695 for ( ; cur; cur = cur.parentNode ) {
8696 eventPath.push( cur );
8697 tmp = cur;
8698 }
8699
8700 // Only add window if we got to document (e.g., not plain obj or detached DOM)
8701 if ( tmp === ( elem.ownerDocument || document ) ) {
8702 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
8703 }
8704 }
8705
8706 // Fire handlers on the event path
8707 i = 0;
8708 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
8709 lastElement = cur;
8710 event.type = i > 1 ?
8711 bubbleType :
8712 special.bindType || type;
8713
8714 // jQuery handler
8715 handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&
8716 dataPriv.get( cur, "handle" );
8717 if ( handle ) {
8718 handle.apply( cur, data );
8719 }
8720
8721 // Native handler
8722 handle = ontype && cur[ ontype ];
8723 if ( handle && handle.apply && acceptData( cur ) ) {
8724 event.result = handle.apply( cur, data );
8725 if ( event.result === false ) {
8726 event.preventDefault();
8727 }
8728 }
8729 }
8730 event.type = type;
8731
8732 // If nobody prevented the default action, do it now
8733 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
8734
8735 if ( ( !special._default ||
8736 special._default.apply( eventPath.pop(), data ) === false ) &&
8737 acceptData( elem ) ) {
8738
8739 // Call a native DOM method on the target with the same name as the event.
8740 // Don't do default actions on window, that's where global variables be (#6170)
8741 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
8742
8743 // Don't re-trigger an onFOO event when we call its FOO() method
8744 tmp = elem[ ontype ];
8745
8746 if ( tmp ) {
8747 elem[ ontype ] = null;
8748 }
8749
8750 // Prevent re-triggering of the same event, since we already bubbled it above
8751 jQuery.event.triggered = type;
8752
8753 if ( event.isPropagationStopped() ) {
8754 lastElement.addEventListener( type, stopPropagationCallback );
8755 }
8756
8757 elem[ type ]();
8758
8759 if ( event.isPropagationStopped() ) {
8760 lastElement.removeEventListener( type, stopPropagationCallback );
8761 }
8762
8763 jQuery.event.triggered = undefined;
8764
8765 if ( tmp ) {
8766 elem[ ontype ] = tmp;
8767 }
8768 }
8769 }
8770 }
8771
8772 return event.result;
8773 },
8774
8775 // Piggyback on a donor event to simulate a different one
8776 // Used only for `focus(in | out)` events
8777 simulate: function( type, elem, event ) {
8778 var e = jQuery.extend(
8779 new jQuery.Event(),
8780 event,
8781 {
8782 type: type,
8783 isSimulated: true
8784 }
8785 );
8786
8787 jQuery.event.trigger( e, null, elem );
8788 }
8789
8790 } );
8791
8792 jQuery.fn.extend( {
8793
8794 trigger: function( type, data ) {
8795 return this.each( function() {
8796 jQuery.event.trigger( type, data, this );
8797 } );
8798 },
8799 triggerHandler: function( type, data ) {
8800 var elem = this[ 0 ];
8801 if ( elem ) {
8802 return jQuery.event.trigger( type, data, elem, true );
8803 }
8804 }
8805 } );
8806
8807
8808 // Support: Firefox <=44
8809 // Firefox doesn't have focus(in | out) events
8810 // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
8811 //
8812 // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
8813 // focus(in | out) events fire after focus & blur events,
8814 // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
8815 // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
8816 if ( !support.focusin ) {
8817 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
8818
8819 // Attach a single capturing handler on the document while someone wants focusin/focusout
8820 var handler = function( event ) {
8821 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
8822 };
8823
8824 jQuery.event.special[ fix ] = {
8825 setup: function() {
8826
8827 // Handle: regular nodes (via `this.ownerDocument`), window
8828 // (via `this.document`) & document (via `this`).
8829 var doc = this.ownerDocument || this.document || this,
8830 attaches = dataPriv.access( doc, fix );
8831
8832 if ( !attaches ) {
8833 doc.addEventListener( orig, handler, true );
8834 }
8835 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
8836 },
8837 teardown: function() {
8838 var doc = this.ownerDocument || this.document || this,
8839 attaches = dataPriv.access( doc, fix ) - 1;
8840
8841 if ( !attaches ) {
8842 doc.removeEventListener( orig, handler, true );
8843 dataPriv.remove( doc, fix );
8844
8845 } else {
8846 dataPriv.access( doc, fix, attaches );
8847 }
8848 }
8849 };
8850 } );
8851 }
8852 var location = window.location;
8853
8854 var nonce = { guid: Date.now() };
8855
8856 var rquery = ( /\?/ );
8857
8858
8859
8860 // Cross-browser xml parsing
8861 jQuery.parseXML = function( data ) {
8862 var xml, parserErrorElem;
8863 if ( !data || typeof data !== "string" ) {
8864 return null;
8865 }
8866
8867 // Support: IE 9 - 11 only
8868 // IE throws on parseFromString with invalid input.
8869 try {
8870 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
8871 } catch ( e ) {}
8872
8873 parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
8874 if ( !xml || parserErrorElem ) {
8875 jQuery.error( "Invalid XML: " + (
8876 parserErrorElem ?
8877 jQuery.map( parserErrorElem.childNodes, function( el ) {
8878 return el.textContent;
8879 } ).join( "\n" ) :
8880 data
8881 ) );
8882 }
8883 return xml;
8884 };
8885
8886
8887 var
8888 rbracket = /\[\]$/,
8889 rCRLF = /\r?\n/g,
8890 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8891 rsubmittable = /^(?:input|select|textarea|keygen)/i;
8892
8893 function buildParams( prefix, obj, traditional, add ) {
8894 var name;
8895
8896 if ( Array.isArray( obj ) ) {
8897
8898 // Serialize array item.
8899 jQuery.each( obj, function( i, v ) {
8900 if ( traditional || rbracket.test( prefix ) ) {
8901
8902 // Treat each array item as a scalar.
8903 add( prefix, v );
8904
8905 } else {
8906
8907 // Item is non-scalar (array or object), encode its numeric index.
8908 buildParams(
8909 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8910 v,
8911 traditional,
8912 add
8913 );
8914 }
8915 } );
8916
8917 } else if ( !traditional && toType( obj ) === "object" ) {
8918
8919 // Serialize object item.
8920 for ( name in obj ) {
8921 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8922 }
8923
8924 } else {
8925
8926 // Serialize scalar item.
8927 add( prefix, obj );
8928 }
8929 }
8930
8931 // Serialize an array of form elements or a set of
8932 // key/values into a query string
8933 jQuery.param = function( a, traditional ) {
8934 var prefix,
8935 s = [],
8936 add = function( key, valueOrFunction ) {
8937
8938 // If value is a function, invoke it and use its return value
8939 var value = isFunction( valueOrFunction ) ?
8940 valueOrFunction() :
8941 valueOrFunction;
8942
8943 s[ s.length ] = encodeURIComponent( key ) + "=" +
8944 encodeURIComponent( value == null ? "" : value );
8945 };
8946
8947 if ( a == null ) {
8948 return "";
8949 }
8950
8951 // If an array was passed in, assume that it is an array of form elements.
8952 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8953
8954 // Serialize the form elements
8955 jQuery.each( a, function() {
8956 add( this.name, this.value );
8957 } );
8958
8959 } else {
8960
8961 // If traditional, encode the "old" way (the way 1.3.2 or older
8962 // did it), otherwise encode params recursively.
8963 for ( prefix in a ) {
8964 buildParams( prefix, a[ prefix ], traditional, add );
8965 }
8966 }
8967
8968 // Return the resulting serialization
8969 return s.join( "&" );
8970 };
8971
8972 jQuery.fn.extend( {
8973 serialize: function() {
8974 return jQuery.param( this.serializeArray() );
8975 },
8976 serializeArray: function() {
8977 return this.map( function() {
8978
8979 // Can add propHook for "elements" to filter or add form elements
8980 var elements = jQuery.prop( this, "elements" );
8981 return elements ? jQuery.makeArray( elements ) : this;
8982 } ).filter( function() {
8983 var type = this.type;
8984
8985 // Use .is( ":disabled" ) so that fieldset[disabled] works
8986 return this.name && !jQuery( this ).is( ":disabled" ) &&
8987 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
8988 ( this.checked || !rcheckableType.test( type ) );
8989 } ).map( function( _i, elem ) {
8990 var val = jQuery( this ).val();
8991
8992 if ( val == null ) {
8993 return null;
8994 }
8995
8996 if ( Array.isArray( val ) ) {
8997 return jQuery.map( val, function( val ) {
8998 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8999 } );
9000 }
9001
9002 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9003 } ).get();
9004 }
9005 } );
9006
9007
9008 var
9009 r20 = /%20/g,
9010 rhash = /#.*$/,
9011 rantiCache = /([?&])_=[^&]*/,
9012 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
9013
9014 // #7653, #8125, #8152: local protocol detection
9015 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9016 rnoContent = /^(?:GET|HEAD)$/,
9017 rprotocol = /^\/\//,
9018
9019 /* Prefilters
9020 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9021 * 2) These are called:
9022 * - BEFORE asking for a transport
9023 * - AFTER param serialization (s.data is a string if s.processData is true)
9024 * 3) key is the dataType
9025 * 4) the catchall symbol "*" can be used
9026 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9027 */
9028 prefilters = {},
9029
9030 /* Transports bindings
9031 * 1) key is the dataType
9032 * 2) the catchall symbol "*" can be used
9033 * 3) selection will start with transport dataType and THEN go to "*" if needed
9034 */
9035 transports = {},
9036
9037 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
9038 allTypes = "*/".concat( "*" ),
9039
9040 // Anchor tag for parsing the document origin
9041 originAnchor = document.createElement( "a" );
9042
9043 originAnchor.href = location.href;
9044
9045 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9046 function addToPrefiltersOrTransports( structure ) {
9047
9048 // dataTypeExpression is optional and defaults to "*"
9049 return function( dataTypeExpression, func ) {
9050
9051 if ( typeof dataTypeExpression !== "string" ) {
9052 func = dataTypeExpression;
9053 dataTypeExpression = "*";
9054 }
9055
9056 var dataType,
9057 i = 0,
9058 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
9059
9060 if ( isFunction( func ) ) {
9061
9062 // For each dataType in the dataTypeExpression
9063 while ( ( dataType = dataTypes[ i++ ] ) ) {
9064
9065 // Prepend if requested
9066 if ( dataType[ 0 ] === "+" ) {
9067 dataType = dataType.slice( 1 ) || "*";
9068 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9069
9070 // Otherwise append
9071 } else {
9072 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9073 }
9074 }
9075 }
9076 };
9077 }
9078
9079 // Base inspection function for prefilters and transports
9080 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9081
9082 var inspected = {},
9083 seekingTransport = ( structure === transports );
9084
9085 function inspect( dataType ) {
9086 var selected;
9087 inspected[ dataType ] = true;
9088 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9089 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9090 if ( typeof dataTypeOrTransport === "string" &&
9091 !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9092
9093 options.dataTypes.unshift( dataTypeOrTransport );
9094 inspect( dataTypeOrTransport );
9095 return false;
9096 } else if ( seekingTransport ) {
9097 return !( selected = dataTypeOrTransport );
9098 }
9099 } );
9100 return selected;
9101 }
9102
9103 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9104 }
9105
9106 // A special extend for ajax options
9107 // that takes "flat" options (not to be deep extended)
9108 // Fixes #9887
9109 function ajaxExtend( target, src ) {
9110 var key, deep,
9111 flatOptions = jQuery.ajaxSettings.flatOptions || {};
9112
9113 for ( key in src ) {
9114 if ( src[ key ] !== undefined ) {
9115 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9116 }
9117 }
9118 if ( deep ) {
9119 jQuery.extend( true, target, deep );
9120 }
9121
9122 return target;
9123 }
9124
9125 /* Handles responses to an ajax request:
9126 * - finds the right dataType (mediates between content-type and expected dataType)
9127 * - returns the corresponding response
9128 */
9129 function ajaxHandleResponses( s, jqXHR, responses ) {
9130
9131 var ct, type, finalDataType, firstDataType,
9132 contents = s.contents,
9133 dataTypes = s.dataTypes;
9134
9135 // Remove auto dataType and get content-type in the process
9136 while ( dataTypes[ 0 ] === "*" ) {
9137 dataTypes.shift();
9138 if ( ct === undefined ) {
9139 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9140 }
9141 }
9142
9143 // Check if we're dealing with a known content-type
9144 if ( ct ) {
9145 for ( type in contents ) {
9146 if ( contents[ type ] && contents[ type ].test( ct ) ) {
9147 dataTypes.unshift( type );
9148 break;
9149 }
9150 }
9151 }
9152
9153 // Check to see if we have a response for the expected dataType
9154 if ( dataTypes[ 0 ] in responses ) {
9155 finalDataType = dataTypes[ 0 ];
9156 } else {
9157
9158 // Try convertible dataTypes
9159 for ( type in responses ) {
9160 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9161 finalDataType = type;
9162 break;
9163 }
9164 if ( !firstDataType ) {
9165 firstDataType = type;
9166 }
9167 }
9168
9169 // Or just use first one
9170 finalDataType = finalDataType || firstDataType;
9171 }
9172
9173 // If we found a dataType
9174 // We add the dataType to the list if needed
9175 // and return the corresponding response
9176 if ( finalDataType ) {
9177 if ( finalDataType !== dataTypes[ 0 ] ) {
9178 dataTypes.unshift( finalDataType );
9179 }
9180 return responses[ finalDataType ];
9181 }
9182 }
9183
9184 /* Chain conversions given the request and the original response
9185 * Also sets the responseXXX fields on the jqXHR instance
9186 */
9187 function ajaxConvert( s, response, jqXHR, isSuccess ) {
9188 var conv2, current, conv, tmp, prev,
9189 converters = {},
9190
9191 // Work with a copy of dataTypes in case we need to modify it for conversion
9192 dataTypes = s.dataTypes.slice();
9193
9194 // Create converters map with lowercased keys
9195 if ( dataTypes[ 1 ] ) {
9196 for ( conv in s.converters ) {
9197 converters[ conv.toLowerCase() ] = s.converters[ conv ];
9198 }
9199 }
9200
9201 current = dataTypes.shift();
9202
9203 // Convert to each sequential dataType
9204 while ( current ) {
9205
9206 if ( s.responseFields[ current ] ) {
9207 jqXHR[ s.responseFields[ current ] ] = response;
9208 }
9209
9210 // Apply the dataFilter if provided
9211 if ( !prev && isSuccess && s.dataFilter ) {
9212 response = s.dataFilter( response, s.dataType );
9213 }
9214
9215 prev = current;
9216 current = dataTypes.shift();
9217
9218 if ( current ) {
9219
9220 // There's only work to do if current dataType is non-auto
9221 if ( current === "*" ) {
9222
9223 current = prev;
9224
9225 // Convert response if prev dataType is non-auto and differs from current
9226 } else if ( prev !== "*" && prev !== current ) {
9227
9228 // Seek a direct converter
9229 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9230
9231 // If none found, seek a pair
9232 if ( !conv ) {
9233 for ( conv2 in converters ) {
9234
9235 // If conv2 outputs current
9236 tmp = conv2.split( " " );
9237 if ( tmp[ 1 ] === current ) {
9238
9239 // If prev can be converted to accepted input
9240 conv = converters[ prev + " " + tmp[ 0 ] ] ||
9241 converters[ "* " + tmp[ 0 ] ];
9242 if ( conv ) {
9243
9244 // Condense equivalence converters
9245 if ( conv === true ) {
9246 conv = converters[ conv2 ];
9247
9248 // Otherwise, insert the intermediate dataType
9249 } else if ( converters[ conv2 ] !== true ) {
9250 current = tmp[ 0 ];
9251 dataTypes.unshift( tmp[ 1 ] );
9252 }
9253 break;
9254 }
9255 }
9256 }
9257 }
9258
9259 // Apply converter (if not an equivalence)
9260 if ( conv !== true ) {
9261
9262 // Unless errors are allowed to bubble, catch and return them
9263 if ( conv && s.throws ) {
9264 response = conv( response );
9265 } else {
9266 try {
9267 response = conv( response );
9268 } catch ( e ) {
9269 return {
9270 state: "parsererror",
9271 error: conv ? e : "No conversion from " + prev + " to " + current
9272 };
9273 }
9274 }
9275 }
9276 }
9277 }
9278 }
9279
9280 return { state: "success", data: response };
9281 }
9282
9283 jQuery.extend( {
9284
9285 // Counter for holding the number of active queries
9286 active: 0,
9287
9288 // Last-Modified header cache for next request
9289 lastModified: {},
9290 etag: {},
9291
9292 ajaxSettings: {
9293 url: location.href,
9294 type: "GET",
9295 isLocal: rlocalProtocol.test( location.protocol ),
9296 global: true,
9297 processData: true,
9298 async: true,
9299 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9300
9301 /*
9302 timeout: 0,
9303 data: null,
9304 dataType: null,
9305 username: null,
9306 password: null,
9307 cache: null,
9308 throws: false,
9309 traditional: false,
9310 headers: {},
9311 */
9312
9313 accepts: {
9314 "*": allTypes,
9315 text: "text/plain",
9316 html: "text/html",
9317 xml: "application/xml, text/xml",
9318 json: "application/json, text/javascript"
9319 },
9320
9321 contents: {
9322 xml: /\bxml\b/,
9323 html: /\bhtml/,
9324 json: /\bjson\b/
9325 },
9326
9327 responseFields: {
9328 xml: "responseXML",
9329 text: "responseText",
9330 json: "responseJSON"
9331 },
9332
9333 // Data converters
9334 // Keys separate source (or catchall "*") and destination types with a single space
9335 converters: {
9336
9337 // Convert anything to text
9338 "* text": String,
9339
9340 // Text to html (true = no transformation)
9341 "text html": true,
9342
9343 // Evaluate text as a json expression
9344 "text json": JSON.parse,
9345
9346 // Parse text as xml
9347 "text xml": jQuery.parseXML
9348 },
9349
9350 // For options that shouldn't be deep extended:
9351 // you can add your own custom options here if
9352 // and when you create one that shouldn't be
9353 // deep extended (see ajaxExtend)
9354 flatOptions: {
9355 url: true,
9356 context: true
9357 }
9358 },
9359
9360 // Creates a full fledged settings object into target
9361 // with both ajaxSettings and settings fields.
9362 // If target is omitted, writes into ajaxSettings.
9363 ajaxSetup: function( target, settings ) {
9364 return settings ?
9365
9366 // Building a settings object
9367 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9368
9369 // Extending ajaxSettings
9370 ajaxExtend( jQuery.ajaxSettings, target );
9371 },
9372
9373 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9374 ajaxTransport: addToPrefiltersOrTransports( transports ),
9375
9376 // Main method
9377 ajax: function( url, options ) {
9378
9379 // If url is an object, simulate pre-1.5 signature
9380 if ( typeof url === "object" ) {
9381 options = url;
9382 url = undefined;
9383 }
9384
9385 // Force options to be an object
9386 options = options || {};
9387
9388 var transport,
9389
9390 // URL without anti-cache param
9391 cacheURL,
9392
9393 // Response headers
9394 responseHeadersString,
9395 responseHeaders,
9396
9397 // timeout handle
9398 timeoutTimer,
9399
9400 // Url cleanup var
9401 urlAnchor,
9402
9403 // Request state (becomes false upon send and true upon completion)
9404 completed,
9405
9406 // To know if global events are to be dispatched
9407 fireGlobals,
9408
9409 // Loop variable
9410 i,
9411
9412 // uncached part of the url
9413 uncached,
9414
9415 // Create the final options object
9416 s = jQuery.ajaxSetup( {}, options ),
9417
9418 // Callbacks context
9419 callbackContext = s.context || s,
9420
9421 // Context for global events is callbackContext if it is a DOM node or jQuery collection
9422 globalEventContext = s.context &&
9423 ( callbackContext.nodeType || callbackContext.jquery ) ?
9424 jQuery( callbackContext ) :
9425 jQuery.event,
9426
9427 // Deferreds
9428 deferred = jQuery.Deferred(),
9429 completeDeferred = jQuery.Callbacks( "once memory" ),
9430
9431 // Status-dependent callbacks
9432 statusCode = s.statusCode || {},
9433
9434 // Headers (they are sent all at once)
9435 requestHeaders = {},
9436 requestHeadersNames = {},
9437
9438 // Default abort message
9439 strAbort = "canceled",
9440
9441 // Fake xhr
9442 jqXHR = {
9443 readyState: 0,
9444
9445 // Builds headers hashtable if needed
9446 getResponseHeader: function( key ) {
9447 var match;
9448 if ( completed ) {
9449 if ( !responseHeaders ) {
9450 responseHeaders = {};
9451 while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9452 responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
9453 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
9454 .concat( match[ 2 ] );
9455 }
9456 }
9457 match = responseHeaders[ key.toLowerCase() + " " ];
9458 }
9459 return match == null ? null : match.join( ", " );
9460 },
9461
9462 // Raw string
9463 getAllResponseHeaders: function() {
9464 return completed ? responseHeadersString : null;
9465 },
9466
9467 // Caches the header
9468 setRequestHeader: function( name, value ) {
9469 if ( completed == null ) {
9470 name = requestHeadersNames[ name.toLowerCase() ] =
9471 requestHeadersNames[ name.toLowerCase() ] || name;
9472 requestHeaders[ name ] = value;
9473 }
9474 return this;
9475 },
9476
9477 // Overrides response content-type header
9478 overrideMimeType: function( type ) {
9479 if ( completed == null ) {
9480 s.mimeType = type;
9481 }
9482 return this;
9483 },
9484
9485 // Status-dependent callbacks
9486 statusCode: function( map ) {
9487 var code;
9488 if ( map ) {
9489 if ( completed ) {
9490
9491 // Execute the appropriate callbacks
9492 jqXHR.always( map[ jqXHR.status ] );
9493 } else {
9494
9495 // Lazy-add the new callbacks in a way that preserves old ones
9496 for ( code in map ) {
9497 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9498 }
9499 }
9500 }
9501 return this;
9502 },
9503
9504 // Cancel the request
9505 abort: function( statusText ) {
9506 var finalText = statusText || strAbort;
9507 if ( transport ) {
9508 transport.abort( finalText );
9509 }
9510 done( 0, finalText );
9511 return this;
9512 }
9513 };
9514
9515 // Attach deferreds
9516 deferred.promise( jqXHR );
9517
9518 // Add protocol if not provided (prefilters might expect it)
9519 // Handle falsy url in the settings object (#10093: consistency with old signature)
9520 // We also use the url parameter if available
9521 s.url = ( ( url || s.url || location.href ) + "" )
9522 .replace( rprotocol, location.protocol + "//" );
9523
9524 // Alias method option to type as per ticket #12004
9525 s.type = options.method || options.type || s.method || s.type;
9526
9527 // Extract dataTypes list
9528 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
9529
9530 // A cross-domain request is in order when the origin doesn't match the current origin.
9531 if ( s.crossDomain == null ) {
9532 urlAnchor = document.createElement( "a" );
9533
9534 // Support: IE <=8 - 11, Edge 12 - 15
9535 // IE throws exception on accessing the href property if url is malformed,
9536 // e.g. http://example.com:80x/
9537 try {
9538 urlAnchor.href = s.url;
9539
9540 // Support: IE <=8 - 11 only
9541 // Anchor's host property isn't correctly set when s.url is relative
9542 urlAnchor.href = urlAnchor.href;
9543 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9544 urlAnchor.protocol + "//" + urlAnchor.host;
9545 } catch ( e ) {
9546
9547 // If there is an error parsing the URL, assume it is crossDomain,
9548 // it can be rejected by the transport if it is invalid
9549 s.crossDomain = true;
9550 }
9551 }
9552
9553 // Convert data if not already a string
9554 if ( s.data && s.processData && typeof s.data !== "string" ) {
9555 s.data = jQuery.param( s.data, s.traditional );
9556 }
9557
9558 // Apply prefilters
9559 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9560
9561 // If request was aborted inside a prefilter, stop there
9562 if ( completed ) {
9563 return jqXHR;
9564 }
9565
9566 // We can fire global events as of now if asked to
9567 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9568 fireGlobals = jQuery.event && s.global;
9569
9570 // Watch for a new set of requests
9571 if ( fireGlobals && jQuery.active++ === 0 ) {
9572 jQuery.event.trigger( "ajaxStart" );
9573 }
9574
9575 // Uppercase the type
9576 s.type = s.type.toUpperCase();
9577
9578 // Determine if request has content
9579 s.hasContent = !rnoContent.test( s.type );
9580
9581 // Save the URL in case we're toying with the If-Modified-Since
9582 // and/or If-None-Match header later on
9583 // Remove hash to simplify url manipulation
9584 cacheURL = s.url.replace( rhash, "" );
9585
9586 // More options handling for requests with no content
9587 if ( !s.hasContent ) {
9588
9589 // Remember the hash so we can put it back
9590 uncached = s.url.slice( cacheURL.length );
9591
9592 // If data is available and should be processed, append data to url
9593 if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
9594 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
9595
9596 // #9682: remove data so that it's not used in an eventual retry
9597 delete s.data;
9598 }
9599
9600 // Add or update anti-cache param if needed
9601 if ( s.cache === false ) {
9602 cacheURL = cacheURL.replace( rantiCache, "$1" );
9603 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
9604 uncached;
9605 }
9606
9607 // Put hash and anti-cache on the URL that will be requested (gh-1732)
9608 s.url = cacheURL + uncached;
9609
9610 // Change '%20' to '+' if this is encoded form body content (gh-2658)
9611 } else if ( s.data && s.processData &&
9612 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
9613 s.data = s.data.replace( r20, "+" );
9614 }
9615
9616 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9617 if ( s.ifModified ) {
9618 if ( jQuery.lastModified[ cacheURL ] ) {
9619 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9620 }
9621 if ( jQuery.etag[ cacheURL ] ) {
9622 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9623 }
9624 }
9625
9626 // Set the correct header, if data is being sent
9627 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9628 jqXHR.setRequestHeader( "Content-Type", s.contentType );
9629 }
9630
9631 // Set the Accepts header for the server, depending on the dataType
9632 jqXHR.setRequestHeader(
9633 "Accept",
9634 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9635 s.accepts[ s.dataTypes[ 0 ] ] +
9636 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9637 s.accepts[ "*" ]
9638 );
9639
9640 // Check for headers option
9641 for ( i in s.headers ) {
9642 jqXHR.setRequestHeader( i, s.headers[ i ] );
9643 }
9644
9645 // Allow custom headers/mimetypes and early abort
9646 if ( s.beforeSend &&
9647 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
9648
9649 // Abort if not done already and return
9650 return jqXHR.abort();
9651 }
9652
9653 // Aborting is no longer a cancellation
9654 strAbort = "abort";
9655
9656 // Install callbacks on deferreds
9657 completeDeferred.add( s.complete );
9658 jqXHR.done( s.success );
9659 jqXHR.fail( s.error );
9660
9661 // Get transport
9662 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9663
9664 // If no transport, we auto-abort
9665 if ( !transport ) {
9666 done( -1, "No Transport" );
9667 } else {
9668 jqXHR.readyState = 1;
9669
9670 // Send global event
9671 if ( fireGlobals ) {
9672 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9673 }
9674
9675 // If request was aborted inside ajaxSend, stop there
9676 if ( completed ) {
9677 return jqXHR;
9678 }
9679
9680 // Timeout
9681 if ( s.async && s.timeout > 0 ) {
9682 timeoutTimer = window.setTimeout( function() {
9683 jqXHR.abort( "timeout" );
9684 }, s.timeout );
9685 }
9686
9687 try {
9688 completed = false;
9689 transport.send( requestHeaders, done );
9690 } catch ( e ) {
9691
9692 // Rethrow post-completion exceptions
9693 if ( completed ) {
9694 throw e;
9695 }
9696
9697 // Propagate others as results
9698 done( -1, e );
9699 }
9700 }
9701
9702 // Callback for when everything is done
9703 function done( status, nativeStatusText, responses, headers ) {
9704 var isSuccess, success, error, response, modified,
9705 statusText = nativeStatusText;
9706
9707 // Ignore repeat invocations
9708 if ( completed ) {
9709 return;
9710 }
9711
9712 completed = true;
9713
9714 // Clear timeout if it exists
9715 if ( timeoutTimer ) {
9716 window.clearTimeout( timeoutTimer );
9717 }
9718
9719 // Dereference transport for early garbage collection
9720 // (no matter how long the jqXHR object will be used)
9721 transport = undefined;
9722
9723 // Cache response headers
9724 responseHeadersString = headers || "";
9725
9726 // Set readyState
9727 jqXHR.readyState = status > 0 ? 4 : 0;
9728
9729 // Determine if successful
9730 isSuccess = status >= 200 && status < 300 || status === 304;
9731
9732 // Get response data
9733 if ( responses ) {
9734 response = ajaxHandleResponses( s, jqXHR, responses );
9735 }
9736
9737 // Use a noop converter for missing script but not if jsonp
9738 if ( !isSuccess &&
9739 jQuery.inArray( "script", s.dataTypes ) > -1 &&
9740 jQuery.inArray( "json", s.dataTypes ) < 0 ) {
9741 s.converters[ "text script" ] = function() {};
9742 }
9743
9744 // Convert no matter what (that way responseXXX fields are always set)
9745 response = ajaxConvert( s, response, jqXHR, isSuccess );
9746
9747 // If successful, handle type chaining
9748 if ( isSuccess ) {
9749
9750 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9751 if ( s.ifModified ) {
9752 modified = jqXHR.getResponseHeader( "Last-Modified" );
9753 if ( modified ) {
9754 jQuery.lastModified[ cacheURL ] = modified;
9755 }
9756 modified = jqXHR.getResponseHeader( "etag" );
9757 if ( modified ) {
9758 jQuery.etag[ cacheURL ] = modified;
9759 }
9760 }
9761
9762 // if no content
9763 if ( status === 204 || s.type === "HEAD" ) {
9764 statusText = "nocontent";
9765
9766 // if not modified
9767 } else if ( status === 304 ) {
9768 statusText = "notmodified";
9769
9770 // If we have data, let's convert it
9771 } else {
9772 statusText = response.state;
9773 success = response.data;
9774 error = response.error;
9775 isSuccess = !error;
9776 }
9777 } else {
9778
9779 // Extract error from statusText and normalize for non-aborts
9780 error = statusText;
9781 if ( status || !statusText ) {
9782 statusText = "error";
9783 if ( status < 0 ) {
9784 status = 0;
9785 }
9786 }
9787 }
9788
9789 // Set data for the fake xhr object
9790 jqXHR.status = status;
9791 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9792
9793 // Success/Error
9794 if ( isSuccess ) {
9795 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9796 } else {
9797 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9798 }
9799
9800 // Status-dependent callbacks
9801 jqXHR.statusCode( statusCode );
9802 statusCode = undefined;
9803
9804 if ( fireGlobals ) {
9805 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9806 [ jqXHR, s, isSuccess ? success : error ] );
9807 }
9808
9809 // Complete
9810 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9811
9812 if ( fireGlobals ) {
9813 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9814
9815 // Handle the global AJAX counter
9816 if ( !( --jQuery.active ) ) {
9817 jQuery.event.trigger( "ajaxStop" );
9818 }
9819 }
9820 }
9821
9822 return jqXHR;
9823 },
9824
9825 getJSON: function( url, data, callback ) {
9826 return jQuery.get( url, data, callback, "json" );
9827 },
9828
9829 getScript: function( url, callback ) {
9830 return jQuery.get( url, undefined, callback, "script" );
9831 }
9832 } );
9833
9834 jQuery.each( [ "get", "post" ], function( _i, method ) {
9835 jQuery[ method ] = function( url, data, callback, type ) {
9836
9837 // Shift arguments if data argument was omitted
9838 if ( isFunction( data ) ) {
9839 type = type || callback;
9840 callback = data;
9841 data = undefined;
9842 }
9843
9844 // The url can be an options object (which then must have .url)
9845 return jQuery.ajax( jQuery.extend( {
9846 url: url,
9847 type: method,
9848 dataType: type,
9849 data: data,
9850 success: callback
9851 }, jQuery.isPlainObject( url ) && url ) );
9852 };
9853 } );
9854
9855 jQuery.ajaxPrefilter( function( s ) {
9856 var i;
9857 for ( i in s.headers ) {
9858 if ( i.toLowerCase() === "content-type" ) {
9859 s.contentType = s.headers[ i ] || "";
9860 }
9861 }
9862 } );
9863
9864
9865 jQuery._evalUrl = function( url, options, doc ) {
9866 return jQuery.ajax( {
9867 url: url,
9868
9869 // Make this explicit, since user can override this through ajaxSetup (#11264)
9870 type: "GET",
9871 dataType: "script",
9872 cache: true,
9873 async: false,
9874 global: false,
9875
9876 // Only evaluate the response if it is successful (gh-4126)
9877 // dataFilter is not invoked for failure responses, so using it instead
9878 // of the default converter is kludgy but it works.
9879 converters: {
9880 "text script": function() {}
9881 },
9882 dataFilter: function( response ) {
9883 jQuery.globalEval( response, options, doc );
9884 }
9885 } );
9886 };
9887
9888
9889 jQuery.fn.extend( {
9890 wrapAll: function( html ) {
9891 var wrap;
9892
9893 if ( this[ 0 ] ) {
9894 if ( isFunction( html ) ) {
9895 html = html.call( this[ 0 ] );
9896 }
9897
9898 // The elements to wrap the target around
9899 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9900
9901 if ( this[ 0 ].parentNode ) {
9902 wrap.insertBefore( this[ 0 ] );
9903 }
9904
9905 wrap.map( function() {
9906 var elem = this;
9907
9908 while ( elem.firstElementChild ) {
9909 elem = elem.firstElementChild;
9910 }
9911
9912 return elem;
9913 } ).append( this );
9914 }
9915
9916 return this;
9917 },
9918
9919 wrapInner: function( html ) {
9920 if ( isFunction( html ) ) {
9921 return this.each( function( i ) {
9922 jQuery( this ).wrapInner( html.call( this, i ) );
9923 } );
9924 }
9925
9926 return this.each( function() {
9927 var self = jQuery( this ),
9928 contents = self.contents();
9929
9930 if ( contents.length ) {
9931 contents.wrapAll( html );
9932
9933 } else {
9934 self.append( html );
9935 }
9936 } );
9937 },
9938
9939 wrap: function( html ) {
9940 var htmlIsFunction = isFunction( html );
9941
9942 return this.each( function( i ) {
9943 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
9944 } );
9945 },
9946
9947 unwrap: function( selector ) {
9948 this.parent( selector ).not( "body" ).each( function() {
9949 jQuery( this ).replaceWith( this.childNodes );
9950 } );
9951 return this;
9952 }
9953 } );
9954
9955
9956 jQuery.expr.pseudos.hidden = function( elem ) {
9957 return !jQuery.expr.pseudos.visible( elem );
9958 };
9959 jQuery.expr.pseudos.visible = function( elem ) {
9960 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
9961 };
9962
9963
9964
9965
9966 jQuery.ajaxSettings.xhr = function() {
9967 try {
9968 return new window.XMLHttpRequest();
9969 } catch ( e ) {}
9970 };
9971
9972 var xhrSuccessStatus = {
9973
9974 // File protocol always yields status code 0, assume 200
9975 0: 200,
9976
9977 // Support: IE <=9 only
9978 // #1450: sometimes IE returns 1223 when it should be 204
9979 1223: 204
9980 },
9981 xhrSupported = jQuery.ajaxSettings.xhr();
9982
9983 support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9984 support.ajax = xhrSupported = !!xhrSupported;
9985
9986 jQuery.ajaxTransport( function( options ) {
9987 var callback, errorCallback;
9988
9989 // Cross domain only allowed if supported through XMLHttpRequest
9990 if ( support.cors || xhrSupported && !options.crossDomain ) {
9991 return {
9992 send: function( headers, complete ) {
9993 var i,
9994 xhr = options.xhr();
9995
9996 xhr.open(
9997 options.type,
9998 options.url,
9999 options.async,
10000 options.username,
10001 options.password
10002 );
10003
10004 // Apply custom fields if provided
10005 if ( options.xhrFields ) {
10006 for ( i in options.xhrFields ) {
10007 xhr[ i ] = options.xhrFields[ i ];
10008 }
10009 }
10010
10011 // Override mime type if needed
10012 if ( options.mimeType && xhr.overrideMimeType ) {
10013 xhr.overrideMimeType( options.mimeType );
10014 }
10015
10016 // X-Requested-With header
10017 // For cross-domain requests, seeing as conditions for a preflight are
10018 // akin to a jigsaw puzzle, we simply never set it to be sure.
10019 // (it can always be set on a per-request basis or even using ajaxSetup)
10020 // For same-domain requests, won't change header if already provided.
10021 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10022 headers[ "X-Requested-With" ] = "XMLHttpRequest";
10023 }
10024
10025 // Set headers
10026 for ( i in headers ) {
10027 xhr.setRequestHeader( i, headers[ i ] );
10028 }
10029
10030 // Callback
10031 callback = function( type ) {
10032 return function() {
10033 if ( callback ) {
10034 callback = errorCallback = xhr.onload =
10035 xhr.onerror = xhr.onabort = xhr.ontimeout =
10036 xhr.onreadystatechange = null;
10037
10038 if ( type === "abort" ) {
10039 xhr.abort();
10040 } else if ( type === "error" ) {
10041
10042 // Support: IE <=9 only
10043 // On a manual native abort, IE9 throws
10044 // errors on any property access that is not readyState
10045 if ( typeof xhr.status !== "number" ) {
10046 complete( 0, "error" );
10047 } else {
10048 complete(
10049
10050 // File: protocol always yields status 0; see #8605, #14207
10051 xhr.status,
10052 xhr.statusText
10053 );
10054 }
10055 } else {
10056 complete(
10057 xhrSuccessStatus[ xhr.status ] || xhr.status,
10058 xhr.statusText,
10059
10060 // Support: IE <=9 only
10061 // IE9 has no XHR2 but throws on binary (trac-11426)
10062 // For XHR2 non-text, let the caller handle it (gh-2498)
10063 ( xhr.responseType || "text" ) !== "text" ||
10064 typeof xhr.responseText !== "string" ?
10065 { binary: xhr.response } :
10066 { text: xhr.responseText },
10067 xhr.getAllResponseHeaders()
10068 );
10069 }
10070 }
10071 };
10072 };
10073
10074 // Listen to events
10075 xhr.onload = callback();
10076 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
10077
10078 // Support: IE 9 only
10079 // Use onreadystatechange to replace onabort
10080 // to handle uncaught aborts
10081 if ( xhr.onabort !== undefined ) {
10082 xhr.onabort = errorCallback;
10083 } else {
10084 xhr.onreadystatechange = function() {
10085
10086 // Check readyState before timeout as it changes
10087 if ( xhr.readyState === 4 ) {
10088
10089 // Allow onerror to be called first,
10090 // but that will not handle a native abort
10091 // Also, save errorCallback to a variable
10092 // as xhr.onerror cannot be accessed
10093 window.setTimeout( function() {
10094 if ( callback ) {
10095 errorCallback();
10096 }
10097 } );
10098 }
10099 };
10100 }
10101
10102 // Create the abort callback
10103 callback = callback( "abort" );
10104
10105 try {
10106
10107 // Do send the request (this may raise an exception)
10108 xhr.send( options.hasContent && options.data || null );
10109 } catch ( e ) {
10110
10111 // #14683: Only rethrow if this hasn't been notified as an error yet
10112 if ( callback ) {
10113 throw e;
10114 }
10115 }
10116 },
10117
10118 abort: function() {
10119 if ( callback ) {
10120 callback();
10121 }
10122 }
10123 };
10124 }
10125 } );
10126
10127
10128
10129
10130 // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
10131 jQuery.ajaxPrefilter( function( s ) {
10132 if ( s.crossDomain ) {
10133 s.contents.script = false;
10134 }
10135 } );
10136
10137 // Install script dataType
10138 jQuery.ajaxSetup( {
10139 accepts: {
10140 script: "text/javascript, application/javascript, " +
10141 "application/ecmascript, application/x-ecmascript"
10142 },
10143 contents: {
10144 script: /\b(?:java|ecma)script\b/
10145 },
10146 converters: {
10147 "text script": function( text ) {
10148 jQuery.globalEval( text );
10149 return text;
10150 }
10151 }
10152 } );
10153
10154 // Handle cache's special case and crossDomain
10155 jQuery.ajaxPrefilter( "script", function( s ) {
10156 if ( s.cache === undefined ) {
10157 s.cache = false;
10158 }
10159 if ( s.crossDomain ) {
10160 s.type = "GET";
10161 }
10162 } );
10163
10164 // Bind script tag hack transport
10165 jQuery.ajaxTransport( "script", function( s ) {
10166
10167 // This transport only deals with cross domain or forced-by-attrs requests
10168 if ( s.crossDomain || s.scriptAttrs ) {
10169 var script, callback;
10170 return {
10171 send: function( _, complete ) {
10172 script = jQuery( "<script>" )
10173 .attr( s.scriptAttrs || {} )
10174 .prop( { charset: s.scriptCharset, src: s.url } )
10175 .on( "load error", callback = function( evt ) {
10176 script.remove();
10177 callback = null;
10178 if ( evt ) {
10179 complete( evt.type === "error" ? 404 : 200, evt.type );
10180 }
10181 } );
10182
10183 // Use native DOM manipulation to avoid our domManip AJAX trickery
10184 document.head.appendChild( script[ 0 ] );
10185 },
10186 abort: function() {
10187 if ( callback ) {
10188 callback();
10189 }
10190 }
10191 };
10192 }
10193 } );
10194
10195
10196
10197
10198 var oldCallbacks = [],
10199 rjsonp = /(=)\?(?=&|$)|\?\?/;
10200
10201 // Default jsonp settings
10202 jQuery.ajaxSetup( {
10203 jsonp: "callback",
10204 jsonpCallback: function() {
10205 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
10206 this[ callback ] = true;
10207 return callback;
10208 }
10209 } );
10210
10211 // Detect, normalize options and install callbacks for jsonp requests
10212 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10213
10214 var callbackName, overwritten, responseContainer,
10215 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10216 "url" :
10217 typeof s.data === "string" &&
10218 ( s.contentType || "" )
10219 .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10220 rjsonp.test( s.data ) && "data"
10221 );
10222
10223 // Handle iff the expected data type is "jsonp" or we have a parameter to set
10224 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10225
10226 // Get callback name, remembering preexisting value associated with it
10227 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
10228 s.jsonpCallback() :
10229 s.jsonpCallback;
10230
10231 // Insert callback into url or form data
10232 if ( jsonProp ) {
10233 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10234 } else if ( s.jsonp !== false ) {
10235 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10236 }
10237
10238 // Use data converter to retrieve json after script execution
10239 s.converters[ "script json" ] = function() {
10240 if ( !responseContainer ) {
10241 jQuery.error( callbackName + " was not called" );
10242 }
10243 return responseContainer[ 0 ];
10244 };
10245
10246 // Force json dataType
10247 s.dataTypes[ 0 ] = "json";
10248
10249 // Install callback
10250 overwritten = window[ callbackName ];
10251 window[ callbackName ] = function() {
10252 responseContainer = arguments;
10253 };
10254
10255 // Clean-up function (fires after converters)
10256 jqXHR.always( function() {
10257
10258 // If previous value didn't exist - remove it
10259 if ( overwritten === undefined ) {
10260 jQuery( window ).removeProp( callbackName );
10261
10262 // Otherwise restore preexisting value
10263 } else {
10264 window[ callbackName ] = overwritten;
10265 }
10266
10267 // Save back as free
10268 if ( s[ callbackName ] ) {
10269
10270 // Make sure that re-using the options doesn't screw things around
10271 s.jsonpCallback = originalSettings.jsonpCallback;
10272
10273 // Save the callback name for future use
10274 oldCallbacks.push( callbackName );
10275 }
10276
10277 // Call if it was a function and we have a response
10278 if ( responseContainer && isFunction( overwritten ) ) {
10279 overwritten( responseContainer[ 0 ] );
10280 }
10281
10282 responseContainer = overwritten = undefined;
10283 } );
10284
10285 // Delegate to script
10286 return "script";
10287 }
10288 } );
10289
10290
10291
10292
10293 // Support: Safari 8 only
10294 // In Safari 8 documents created via document.implementation.createHTMLDocument
10295 // collapse sibling forms: the second one becomes a child of the first one.
10296 // Because of that, this security measure has to be disabled in Safari 8.
10297 // https://bugs.webkit.org/show_bug.cgi?id=137337
10298 support.createHTMLDocument = ( function() {
10299 var body = document.implementation.createHTMLDocument( "" ).body;
10300 body.innerHTML = "<form></form><form></form>";
10301 return body.childNodes.length === 2;
10302 } )();
10303
10304
10305 // Argument "data" should be string of html
10306 // context (optional): If specified, the fragment will be created in this context,
10307 // defaults to document
10308 // keepScripts (optional): If true, will include scripts passed in the html string
10309 jQuery.parseHTML = function( data, context, keepScripts ) {
10310 if ( typeof data !== "string" ) {
10311 return [];
10312 }
10313 if ( typeof context === "boolean" ) {
10314 keepScripts = context;
10315 context = false;
10316 }
10317
10318 var base, parsed, scripts;
10319
10320 if ( !context ) {
10321
10322 // Stop scripts or inline event handlers from being executed immediately
10323 // by using document.implementation
10324 if ( support.createHTMLDocument ) {
10325 context = document.implementation.createHTMLDocument( "" );
10326
10327 // Set the base href for the created document
10328 // so any parsed elements with URLs
10329 // are based on the document's URL (gh-2965)
10330 base = context.createElement( "base" );
10331 base.href = document.location.href;
10332 context.head.appendChild( base );
10333 } else {
10334 context = document;
10335 }
10336 }
10337
10338 parsed = rsingleTag.exec( data );
10339 scripts = !keepScripts && [];
10340
10341 // Single tag
10342 if ( parsed ) {
10343 return [ context.createElement( parsed[ 1 ] ) ];
10344 }
10345
10346 parsed = buildFragment( [ data ], context, scripts );
10347
10348 if ( scripts && scripts.length ) {
10349 jQuery( scripts ).remove();
10350 }
10351
10352 return jQuery.merge( [], parsed.childNodes );
10353 };
10354
10355
10356 /**
10357 * Load a url into a page
10358 */
10359 jQuery.fn.load = function( url, params, callback ) {
10360 var selector, type, response,
10361 self = this,
10362 off = url.indexOf( " " );
10363
10364 if ( off > -1 ) {
10365 selector = stripAndCollapse( url.slice( off ) );
10366 url = url.slice( 0, off );
10367 }
10368
10369 // If it's a function
10370 if ( isFunction( params ) ) {
10371
10372 // We assume that it's the callback
10373 callback = params;
10374 params = undefined;
10375
10376 // Otherwise, build a param string
10377 } else if ( params && typeof params === "object" ) {
10378 type = "POST";
10379 }
10380
10381 // If we have elements to modify, make the request
10382 if ( self.length > 0 ) {
10383 jQuery.ajax( {
10384 url: url,
10385
10386 // If "type" variable is undefined, then "GET" method will be used.
10387 // Make value of this field explicit since
10388 // user can override it through ajaxSetup method
10389 type: type || "GET",
10390 dataType: "html",
10391 data: params
10392 } ).done( function( responseText ) {
10393
10394 // Save response for use in complete callback
10395 response = arguments;
10396
10397 self.html( selector ?
10398
10399 // If a selector was specified, locate the right elements in a dummy div
10400 // Exclude scripts to avoid IE 'Permission Denied' errors
10401 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10402
10403 // Otherwise use the full result
10404 responseText );
10405
10406 // If the request succeeds, this function gets "data", "status", "jqXHR"
10407 // but they are ignored because response was set above.
10408 // If it fails, this function gets "jqXHR", "status", "error"
10409 } ).always( callback && function( jqXHR, status ) {
10410 self.each( function() {
10411 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10412 } );
10413 } );
10414 }
10415
10416 return this;
10417 };
10418
10419
10420
10421
10422 jQuery.expr.pseudos.animated = function( elem ) {
10423 return jQuery.grep( jQuery.timers, function( fn ) {
10424 return elem === fn.elem;
10425 } ).length;
10426 };
10427
10428
10429
10430
10431 jQuery.offset = {
10432 setOffset: function( elem, options, i ) {
10433 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10434 position = jQuery.css( elem, "position" ),
10435 curElem = jQuery( elem ),
10436 props = {};
10437
10438 // Set position first, in-case top/left are set even on static elem
10439 if ( position === "static" ) {
10440 elem.style.position = "relative";
10441 }
10442
10443 curOffset = curElem.offset();
10444 curCSSTop = jQuery.css( elem, "top" );
10445 curCSSLeft = jQuery.css( elem, "left" );
10446 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10447 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
10448
10449 // Need to be able to calculate position if either
10450 // top or left is auto and position is either absolute or fixed
10451 if ( calculatePosition ) {
10452 curPosition = curElem.position();
10453 curTop = curPosition.top;
10454 curLeft = curPosition.left;
10455
10456 } else {
10457 curTop = parseFloat( curCSSTop ) || 0;
10458 curLeft = parseFloat( curCSSLeft ) || 0;
10459 }
10460
10461 if ( isFunction( options ) ) {
10462
10463 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10464 options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10465 }
10466
10467 if ( options.top != null ) {
10468 props.top = ( options.top - curOffset.top ) + curTop;
10469 }
10470 if ( options.left != null ) {
10471 props.left = ( options.left - curOffset.left ) + curLeft;
10472 }
10473
10474 if ( "using" in options ) {
10475 options.using.call( elem, props );
10476
10477 } else {
10478 curElem.css( props );
10479 }
10480 }
10481 };
10482
10483 jQuery.fn.extend( {
10484
10485 // offset() relates an element's border box to the document origin
10486 offset: function( options ) {
10487
10488 // Preserve chaining for setter
10489 if ( arguments.length ) {
10490 return options === undefined ?
10491 this :
10492 this.each( function( i ) {
10493 jQuery.offset.setOffset( this, options, i );
10494 } );
10495 }
10496
10497 var rect, win,
10498 elem = this[ 0 ];
10499
10500 if ( !elem ) {
10501 return;
10502 }
10503
10504 // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
10505 // Support: IE <=11 only
10506 // Running getBoundingClientRect on a
10507 // disconnected node in IE throws an error
10508 if ( !elem.getClientRects().length ) {
10509 return { top: 0, left: 0 };
10510 }
10511
10512 // Get document-relative position by adding viewport scroll to viewport-relative gBCR
10513 rect = elem.getBoundingClientRect();
10514 win = elem.ownerDocument.defaultView;
10515 return {
10516 top: rect.top + win.pageYOffset,
10517 left: rect.left + win.pageXOffset
10518 };
10519 },
10520
10521 // position() relates an element's margin box to its offset parent's padding box
10522 // This corresponds to the behavior of CSS absolute positioning
10523 position: function() {
10524 if ( !this[ 0 ] ) {
10525 return;
10526 }
10527
10528 var offsetParent, offset, doc,
10529 elem = this[ 0 ],
10530 parentOffset = { top: 0, left: 0 };
10531
10532 // position:fixed elements are offset from the viewport, which itself always has zero offset
10533 if ( jQuery.css( elem, "position" ) === "fixed" ) {
10534
10535 // Assume position:fixed implies availability of getBoundingClientRect
10536 offset = elem.getBoundingClientRect();
10537
10538 } else {
10539 offset = this.offset();
10540
10541 // Account for the *real* offset parent, which can be the document or its root element
10542 // when a statically positioned element is identified
10543 doc = elem.ownerDocument;
10544 offsetParent = elem.offsetParent || doc.documentElement;
10545 while ( offsetParent &&
10546 ( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
10547 jQuery.css( offsetParent, "position" ) === "static" ) {
10548
10549 offsetParent = offsetParent.parentNode;
10550 }
10551 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
10552
10553 // Incorporate borders into its offset, since they are outside its content origin
10554 parentOffset = jQuery( offsetParent ).offset();
10555 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
10556 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
10557 }
10558 }
10559
10560 // Subtract parent offsets and element margins
10561 return {
10562 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10563 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10564 };
10565 },
10566
10567 // This method will return documentElement in the following cases:
10568 // 1) For the element inside the iframe without offsetParent, this method will return
10569 // documentElement of the parent window
10570 // 2) For the hidden or detached element
10571 // 3) For body or html element, i.e. in case of the html node - it will return itself
10572 //
10573 // but those exceptions were never presented as a real life use-cases
10574 // and might be considered as more preferable results.
10575 //
10576 // This logic, however, is not guaranteed and can change at any point in the future
10577 offsetParent: function() {
10578 return this.map( function() {
10579 var offsetParent = this.offsetParent;
10580
10581 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
10582 offsetParent = offsetParent.offsetParent;
10583 }
10584
10585 return offsetParent || documentElement;
10586 } );
10587 }
10588 } );
10589
10590 // Create scrollLeft and scrollTop methods
10591 jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10592 var top = "pageYOffset" === prop;
10593
10594 jQuery.fn[ method ] = function( val ) {
10595 return access( this, function( elem, method, val ) {
10596
10597 // Coalesce documents and windows
10598 var win;
10599 if ( isWindow( elem ) ) {
10600 win = elem;
10601 } else if ( elem.nodeType === 9 ) {
10602 win = elem.defaultView;
10603 }
10604
10605 if ( val === undefined ) {
10606 return win ? win[ prop ] : elem[ method ];
10607 }
10608
10609 if ( win ) {
10610 win.scrollTo(
10611 !top ? val : win.pageXOffset,
10612 top ? val : win.pageYOffset
10613 );
10614
10615 } else {
10616 elem[ method ] = val;
10617 }
10618 }, method, val, arguments.length );
10619 };
10620 } );
10621
10622 // Support: Safari <=7 - 9.1, Chrome <=37 - 49
10623 // Add the top/left cssHooks using jQuery.fn.position
10624 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10625 // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10626 // getComputedStyle returns percent when specified for top/left/bottom/right;
10627 // rather than make the css module depend on the offset module, just check for it here
10628 jQuery.each( [ "top", "left" ], function( _i, prop ) {
10629 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10630 function( elem, computed ) {
10631 if ( computed ) {
10632 computed = curCSS( elem, prop );
10633
10634 // If curCSS returns percentage, fallback to offset
10635 return rnumnonpx.test( computed ) ?
10636 jQuery( elem ).position()[ prop ] + "px" :
10637 computed;
10638 }
10639 }
10640 );
10641 } );
10642
10643
10644 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10645 jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10646 jQuery.each( {
10647 padding: "inner" + name,
10648 content: type,
10649 "": "outer" + name
10650 }, function( defaultExtra, funcName ) {
10651
10652 // Margin is only for outerHeight, outerWidth
10653 jQuery.fn[ funcName ] = function( margin, value ) {
10654 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10655 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10656
10657 return access( this, function( elem, type, value ) {
10658 var doc;
10659
10660 if ( isWindow( elem ) ) {
10661
10662 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10663 return funcName.indexOf( "outer" ) === 0 ?
10664 elem[ "inner" + name ] :
10665 elem.document.documentElement[ "client" + name ];
10666 }
10667
10668 // Get document width or height
10669 if ( elem.nodeType === 9 ) {
10670 doc = elem.documentElement;
10671
10672 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10673 // whichever is greatest
10674 return Math.max(
10675 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10676 elem.body[ "offset" + name ], doc[ "offset" + name ],
10677 doc[ "client" + name ]
10678 );
10679 }
10680
10681 return value === undefined ?
10682
10683 // Get width or height on the element, requesting but not forcing parseFloat
10684 jQuery.css( elem, type, extra ) :
10685
10686 // Set width or height on the element
10687 jQuery.style( elem, type, value, extra );
10688 }, type, chainable ? margin : undefined, chainable );
10689 };
10690 } );
10691 } );
10692
10693
10694 jQuery.each( [
10695 "ajaxStart",
10696 "ajaxStop",
10697 "ajaxComplete",
10698 "ajaxError",
10699 "ajaxSuccess",
10700 "ajaxSend"
10701 ], function( _i, type ) {
10702 jQuery.fn[ type ] = function( fn ) {
10703 return this.on( type, fn );
10704 };
10705 } );
10706
10707
10708
10709
10710 jQuery.fn.extend( {
10711
10712 bind: function( types, data, fn ) {
10713 return this.on( types, null, data, fn );
10714 },
10715 unbind: function( types, fn ) {
10716 return this.off( types, null, fn );
10717 },
10718
10719 delegate: function( selector, types, data, fn ) {
10720 return this.on( types, selector, data, fn );
10721 },
10722 undelegate: function( selector, types, fn ) {
10723
10724 // ( namespace ) or ( selector, types [, fn] )
10725 return arguments.length === 1 ?
10726 this.off( selector, "**" ) :
10727 this.off( types, selector || "**", fn );
10728 },
10729
10730 hover: function( fnOver, fnOut ) {
10731 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
10732 }
10733 } );
10734
10735 jQuery.each(
10736 ( "blur focus focusin focusout resize scroll click dblclick " +
10737 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
10738 "change select submit keydown keypress keyup contextmenu" ).split( " " ),
10739 function( _i, name ) {
10740
10741 // Handle event binding
10742 jQuery.fn[ name ] = function( data, fn ) {
10743 return arguments.length > 0 ?
10744 this.on( name, null, data, fn ) :
10745 this.trigger( name );
10746 };
10747 }
10748 );
10749
10750
10751
10752
10753 // Support: Android <=4.0 only
10754 // Make sure we trim BOM and NBSP
10755 var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
10756
10757 // Bind a function to a context, optionally partially applying any
10758 // arguments.
10759 // jQuery.proxy is deprecated to promote standards (specifically Function#bind)
10760 // However, it is not slated for removal any time soon
10761 jQuery.proxy = function( fn, context ) {
10762 var tmp, args, proxy;
10763
10764 if ( typeof context === "string" ) {
10765 tmp = fn[ context ];
10766 context = fn;
10767 fn = tmp;
10768 }
10769
10770 // Quick check to determine if target is callable, in the spec
10771 // this throws a TypeError, but we will just return undefined.
10772 if ( !isFunction( fn ) ) {
10773 return undefined;
10774 }
10775
10776 // Simulated bind
10777 args = slice.call( arguments, 2 );
10778 proxy = function() {
10779 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
10780 };
10781
10782 // Set the guid of unique handler to the same of original handler, so it can be removed
10783 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
10784
10785 return proxy;
10786 };
10787
10788 jQuery.holdReady = function( hold ) {
10789 if ( hold ) {
10790 jQuery.readyWait++;
10791 } else {
10792 jQuery.ready( true );
10793 }
10794 };
10795 jQuery.isArray = Array.isArray;
10796 jQuery.parseJSON = JSON.parse;
10797 jQuery.nodeName = nodeName;
10798 jQuery.isFunction = isFunction;
10799 jQuery.isWindow = isWindow;
10800 jQuery.camelCase = camelCase;
10801 jQuery.type = toType;
10802
10803 jQuery.now = Date.now;
10804
10805 jQuery.isNumeric = function( obj ) {
10806
10807 // As of jQuery 3.0, isNumeric is limited to
10808 // strings and numbers (primitives or objects)
10809 // that can be coerced to finite numbers (gh-2662)
10810 var type = jQuery.type( obj );
10811 return ( type === "number" || type === "string" ) &&
10812
10813 // parseFloat NaNs numeric-cast false positives ("")
10814 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
10815 // subtraction forces infinities to NaN
10816 !isNaN( obj - parseFloat( obj ) );
10817 };
10818
10819 jQuery.trim = function( text ) {
10820 return text == null ?
10821 "" :
10822 ( text + "" ).replace( rtrim, "" );
10823 };
10824
10825
10826
10827 // Register as a named AMD module, since jQuery can be concatenated with other
10828 // files that may use define, but not via a proper concatenation script that
10829 // understands anonymous AMD modules. A named AMD is safest and most robust
10830 // way to register. Lowercase jquery is used because AMD module names are
10831 // derived from file names, and jQuery is normally delivered in a lowercase
10832 // file name. Do this after creating the global so that if an AMD module wants
10833 // to call noConflict to hide this version of jQuery, it will work.
10834
10835 // Note that for maximum portability, libraries that are not jQuery should
10836 // declare themselves as anonymous modules, and avoid setting a global if an
10837 // AMD loader is present. jQuery is a special case. For more information, see
10838 // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10839
10840 if ( typeof define === "function" && define.amd ) {
10841 define( "jquery", [], function() {
10842 return jQuery;
10843 } );
10844 }
10845
10846
10847
10848
10849 var
10850
10851 // Map over jQuery in case of overwrite
10852 _jQuery = window.jQuery,
10853
10854 // Map over the $ in case of overwrite
10855 _$ = window.$;
10856
10857 jQuery.noConflict = function( deep ) {
10858 if ( window.$ === jQuery ) {
10859 window.$ = _$;
10860 }
10861
10862 if ( deep && window.jQuery === jQuery ) {
10863 window.jQuery = _jQuery;
10864 }
10865
10866 return jQuery;
10867 };
10868
10869 // Expose jQuery and $ identifiers, even in AMD
10870 // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10871 // and CommonJS for browser emulators (#13566)
10872 if ( typeof noGlobal === "undefined" ) {
10873 window.jQuery = window.$ = jQuery;
10874 }
10875
10876
10877
10878
10879 return jQuery;
10880 } );
0 /*!
1 * jQuery JavaScript Library v1.11.3
2 * http://jquery.com/
3 *
4 * Includes Sizzle.js
5 * http://sizzlejs.com/
6 *
7 * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
8 * Released under the MIT license
9 * http://jquery.org/license
10 *
11 * Date: 2015-09-23T12:31Z
12 */
13
14 (function( global, factory ) {
15
16 if ( typeof module === "object" && typeof module.exports === "object" ) {
17 // For CommonJS and CommonJS-like environments where a proper window is present,
18 // execute the factory and get jQuery
19 // For environments that do not inherently posses a window with a document
20 // (such as Node.js), expose a jQuery-making factory as module.exports
21 // This accentuates the need for the creation of a real window
22 // e.g. var jQuery = require("jquery")(window);
23 // See ticket #14549 for more info
24 module.exports = global.document ?
25 factory( global, true ) :
26 function( w ) {
27 if ( !w.document ) {
28 throw new Error( "jQuery requires a window with a document" );
29 }
30 return factory( w );
31 };
32 } else {
33 factory( global );
34 }
35
36 // Pass this if window is not defined yet
37 }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
38
39 // Can't do this because several apps including ASP.NET trace
40 // the stack via arguments.caller.callee and Firefox dies if
41 // you try to trace through "use strict" call chains. (#13335)
42 // Support: Firefox 18+
43 //
44 var deletedIds = [];
45
46 var slice = deletedIds.slice;
47
48 var concat = deletedIds.concat;
49
50 var push = deletedIds.push;
51
52 var indexOf = deletedIds.indexOf;
53
54 var class2type = {};
55
56 var toString = class2type.toString;
57
58 var hasOwn = class2type.hasOwnProperty;
59
60 var support = {};
61
62
63
64 var
65 version = "1.11.3",
66
67 // Define a local copy of jQuery
68 jQuery = function( selector, context ) {
69 // The jQuery object is actually just the init constructor 'enhanced'
70 // Need init if jQuery is called (just allow error to be thrown if not included)
71 return new jQuery.fn.init( selector, context );
72 },
73
74 // Support: Android<4.1, IE<9
75 // Make sure we trim BOM and NBSP
76 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
77
78 // Matches dashed string for camelizing
79 rmsPrefix = /^-ms-/,
80 rdashAlpha = /-([\da-z])/gi,
81
82 // Used by jQuery.camelCase as callback to replace()
83 fcamelCase = function( all, letter ) {
84 return letter.toUpperCase();
85 };
86
87 jQuery.fn = jQuery.prototype = {
88 // The current version of jQuery being used
89 jquery: version,
90
91 constructor: jQuery,
92
93 // Start with an empty selector
94 selector: "",
95
96 // The default length of a jQuery object is 0
97 length: 0,
98
99 toArray: function() {
100 return slice.call( this );
101 },
102
103 // Get the Nth element in the matched element set OR
104 // Get the whole matched element set as a clean array
105 get: function( num ) {
106 return num != null ?
107
108 // Return just the one element from the set
109 ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
110
111 // Return all the elements in a clean array
112 slice.call( this );
113 },
114
115 // Take an array of elements and push it onto the stack
116 // (returning the new matched element set)
117 pushStack: function( elems ) {
118
119 // Build a new jQuery matched element set
120 var ret = jQuery.merge( this.constructor(), elems );
121
122 // Add the old object onto the stack (as a reference)
123 ret.prevObject = this;
124 ret.context = this.context;
125
126 // Return the newly-formed element set
127 return ret;
128 },
129
130 // Execute a callback for every element in the matched set.
131 // (You can seed the arguments with an array of args, but this is
132 // only used internally.)
133 each: function( callback, args ) {
134 return jQuery.each( this, callback, args );
135 },
136
137 map: function( callback ) {
138 return this.pushStack( jQuery.map(this, function( elem, i ) {
139 return callback.call( elem, i, elem );
140 }));
141 },
142
143 slice: function() {
144 return this.pushStack( slice.apply( this, arguments ) );
145 },
146
147 first: function() {
148 return this.eq( 0 );
149 },
150
151 last: function() {
152 return this.eq( -1 );
153 },
154
155 eq: function( i ) {
156 var len = this.length,
157 j = +i + ( i < 0 ? len : 0 );
158 return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
159 },
160
161 end: function() {
162 return this.prevObject || this.constructor(null);
163 },
164
165 // For internal use only.
166 // Behaves like an Array's method, not like a jQuery method.
167 push: push,
168 sort: deletedIds.sort,
169 splice: deletedIds.splice
170 };
171
172 jQuery.extend = jQuery.fn.extend = function() {
173 var src, copyIsArray, copy, name, options, clone,
174 target = arguments[0] || {},
175 i = 1,
176 length = arguments.length,
177 deep = false;
178
179 // Handle a deep copy situation
180 if ( typeof target === "boolean" ) {
181 deep = target;
182
183 // skip the boolean and the target
184 target = arguments[ i ] || {};
185 i++;
186 }
187
188 // Handle case when target is a string or something (possible in deep copy)
189 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
190 target = {};
191 }
192
193 // extend jQuery itself if only one argument is passed
194 if ( i === length ) {
195 target = this;
196 i--;
197 }
198
199 for ( ; i < length; i++ ) {
200 // Only deal with non-null/undefined values
201 if ( (options = arguments[ i ]) != null ) {
202 // Extend the base object
203 for ( name in options ) {
204 src = target[ name ];
205 copy = options[ name ];
206
207 // Prevent never-ending loop
208 if ( target === copy ) {
209 continue;
210 }
211
212 // Recurse if we're merging plain objects or arrays
213 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
214 if ( copyIsArray ) {
215 copyIsArray = false;
216 clone = src && jQuery.isArray(src) ? src : [];
217
218 } else {
219 clone = src && jQuery.isPlainObject(src) ? src : {};
220 }
221
222 // Never move original objects, clone them
223 target[ name ] = jQuery.extend( deep, clone, copy );
224
225 // Don't bring in undefined values
226 } else if ( copy !== undefined ) {
227 target[ name ] = copy;
228 }
229 }
230 }
231 }
232
233 // Return the modified object
234 return target;
235 };
236
237 jQuery.extend({
238 // Unique for each copy of jQuery on the page
239 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
240
241 // Assume jQuery is ready without the ready module
242 isReady: true,
243
244 error: function( msg ) {
245 throw new Error( msg );
246 },
247
248 noop: function() {},
249
250 // See test/unit/core.js for details concerning isFunction.
251 // Since version 1.3, DOM methods and functions like alert
252 // aren't supported. They return false on IE (#2968).
253 isFunction: function( obj ) {
254 return jQuery.type(obj) === "function";
255 },
256
257 isArray: Array.isArray || function( obj ) {
258 return jQuery.type(obj) === "array";
259 },
260
261 isWindow: function( obj ) {
262 /* jshint eqeqeq: false */
263 return obj != null && obj == obj.window;
264 },
265
266 isNumeric: function( obj ) {
267 // parseFloat NaNs numeric-cast false positives (null|true|false|"")
268 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
269 // subtraction forces infinities to NaN
270 // adding 1 corrects loss of precision from parseFloat (#15100)
271 return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
272 },
273
274 isEmptyObject: function( obj ) {
275 var name;
276 for ( name in obj ) {
277 return false;
278 }
279 return true;
280 },
281
282 isPlainObject: function( obj ) {
283 var key;
284
285 // Must be an Object.
286 // Because of IE, we also have to check the presence of the constructor property.
287 // Make sure that DOM nodes and window objects don't pass through, as well
288 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
289 return false;
290 }
291
292 try {
293 // Not own constructor property must be Object
294 if ( obj.constructor &&
295 !hasOwn.call(obj, "constructor") &&
296 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
297 return false;
298 }
299 } catch ( e ) {
300 // IE8,9 Will throw exceptions on certain host objects #9897
301 return false;
302 }
303
304 // Support: IE<9
305 // Handle iteration over inherited properties before own properties.
306 if ( support.ownLast ) {
307 for ( key in obj ) {
308 return hasOwn.call( obj, key );
309 }
310 }
311
312 // Own properties are enumerated firstly, so to speed up,
313 // if last one is own, then all properties are own.
314 for ( key in obj ) {}
315
316 return key === undefined || hasOwn.call( obj, key );
317 },
318
319 type: function( obj ) {
320 if ( obj == null ) {
321 return obj + "";
322 }
323 return typeof obj === "object" || typeof obj === "function" ?
324 class2type[ toString.call(obj) ] || "object" :
325 typeof obj;
326 },
327
328 // Evaluates a script in a global context
329 // Workarounds based on findings by Jim Driscoll
330 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
331 globalEval: function( data ) {
332 if ( data && jQuery.trim( data ) ) {
333 // We use execScript on Internet Explorer
334 // We use an anonymous function so that context is window
335 // rather than jQuery in Firefox
336 ( window.execScript || function( data ) {
337 window[ "eval" ].call( window, data );
338 } )( data );
339 }
340 },
341
342 // Convert dashed to camelCase; used by the css and data modules
343 // Microsoft forgot to hump their vendor prefix (#9572)
344 camelCase: function( string ) {
345 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
346 },
347
348 nodeName: function( elem, name ) {
349 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
350 },
351
352 // args is for internal usage only
353 each: function( obj, callback, args ) {
354 var value,
355 i = 0,
356 length = obj.length,
357 isArray = isArraylike( obj );
358
359 if ( args ) {
360 if ( isArray ) {
361 for ( ; i < length; i++ ) {
362 value = callback.apply( obj[ i ], args );
363
364 if ( value === false ) {
365 break;
366 }
367 }
368 } else {
369 for ( i in obj ) {
370 value = callback.apply( obj[ i ], args );
371
372 if ( value === false ) {
373 break;
374 }
375 }
376 }
377
378 // A special, fast, case for the most common use of each
379 } else {
380 if ( isArray ) {
381 for ( ; i < length; i++ ) {
382 value = callback.call( obj[ i ], i, obj[ i ] );
383
384 if ( value === false ) {
385 break;
386 }
387 }
388 } else {
389 for ( i in obj ) {
390 value = callback.call( obj[ i ], i, obj[ i ] );
391
392 if ( value === false ) {
393 break;
394 }
395 }
396 }
397 }
398
399 return obj;
400 },
401
402 // Support: Android<4.1, IE<9
403 trim: function( text ) {
404 return text == null ?
405 "" :
406 ( text + "" ).replace( rtrim, "" );
407 },
408
409 // results is for internal usage only
410 makeArray: function( arr, results ) {
411 var ret = results || [];
412
413 if ( arr != null ) {
414 if ( isArraylike( Object(arr) ) ) {
415 jQuery.merge( ret,
416 typeof arr === "string" ?
417 [ arr ] : arr
418 );
419 } else {
420 push.call( ret, arr );
421 }
422 }
423
424 return ret;
425 },
426
427 inArray: function( elem, arr, i ) {
428 var len;
429
430 if ( arr ) {
431 if ( indexOf ) {
432 return indexOf.call( arr, elem, i );
433 }
434
435 len = arr.length;
436 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
437
438 for ( ; i < len; i++ ) {
439 // Skip accessing in sparse arrays
440 if ( i in arr && arr[ i ] === elem ) {
441 return i;
442 }
443 }
444 }
445
446 return -1;
447 },
448
449 merge: function( first, second ) {
450 var len = +second.length,
451 j = 0,
452 i = first.length;
453
454 while ( j < len ) {
455 first[ i++ ] = second[ j++ ];
456 }
457
458 // Support: IE<9
459 // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
460 if ( len !== len ) {
461 while ( second[j] !== undefined ) {
462 first[ i++ ] = second[ j++ ];
463 }
464 }
465
466 first.length = i;
467
468 return first;
469 },
470
471 grep: function( elems, callback, invert ) {
472 var callbackInverse,
473 matches = [],
474 i = 0,
475 length = elems.length,
476 callbackExpect = !invert;
477
478 // Go through the array, only saving the items
479 // that pass the validator function
480 for ( ; i < length; i++ ) {
481 callbackInverse = !callback( elems[ i ], i );
482 if ( callbackInverse !== callbackExpect ) {
483 matches.push( elems[ i ] );
484 }
485 }
486
487 return matches;
488 },
489
490 // arg is for internal usage only
491 map: function( elems, callback, arg ) {
492 var value,
493 i = 0,
494 length = elems.length,
495 isArray = isArraylike( elems ),
496 ret = [];
497
498 // Go through the array, translating each of the items to their new values
499 if ( isArray ) {
500 for ( ; i < length; i++ ) {
501 value = callback( elems[ i ], i, arg );
502
503 if ( value != null ) {
504 ret.push( value );
505 }
506 }
507
508 // Go through every key on the object,
509 } else {
510 for ( i in elems ) {
511 value = callback( elems[ i ], i, arg );
512
513 if ( value != null ) {
514 ret.push( value );
515 }
516 }
517 }
518
519 // Flatten any nested arrays
520 return concat.apply( [], ret );
521 },
522
523 // A global GUID counter for objects
524 guid: 1,
525
526 // Bind a function to a context, optionally partially applying any
527 // arguments.
528 proxy: function( fn, context ) {
529 var args, proxy, tmp;
530
531 if ( typeof context === "string" ) {
532 tmp = fn[ context ];
533 context = fn;
534 fn = tmp;
535 }
536
537 // Quick check to determine if target is callable, in the spec
538 // this throws a TypeError, but we will just return undefined.
539 if ( !jQuery.isFunction( fn ) ) {
540 return undefined;
541 }
542
543 // Simulated bind
544 args = slice.call( arguments, 2 );
545 proxy = function() {
546 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
547 };
548
549 // Set the guid of unique handler to the same of original handler, so it can be removed
550 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
551
552 return proxy;
553 },
554
555 now: function() {
556 return +( new Date() );
557 },
558
559 // jQuery.support is not used in Core but other projects attach their
560 // properties to it so it needs to exist.
561 support: support
562 });
563
564 // Populate the class2type map
565 jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
566 class2type[ "[object " + name + "]" ] = name.toLowerCase();
567 });
568
569 function isArraylike( obj ) {
570
571 // Support: iOS 8.2 (not reproducible in simulator)
572 // `in` check used to prevent JIT error (gh-2145)
573 // hasOwn isn't used here due to false negatives
574 // regarding Nodelist length in IE
575 var length = "length" in obj && obj.length,
576 type = jQuery.type( obj );
577
578 if ( type === "function" || jQuery.isWindow( obj ) ) {
579 return false;
580 }
581
582 if ( obj.nodeType === 1 && length ) {
583 return true;
584 }
585
586 return type === "array" || length === 0 ||
587 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
588 }
589 var Sizzle =
590 /*!
591 * Sizzle CSS Selector Engine v2.2.0-pre
592 * http://sizzlejs.com/
593 *
594 * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
595 * Released under the MIT license
596 * http://jquery.org/license
597 *
598 * Date: 2014-12-16
599 */
600 (function( window ) {
601
602 var i,
603 support,
604 Expr,
605 getText,
606 isXML,
607 tokenize,
608 compile,
609 select,
610 outermostContext,
611 sortInput,
612 hasDuplicate,
613
614 // Local document vars
615 setDocument,
616 document,
617 docElem,
618 documentIsHTML,
619 rbuggyQSA,
620 rbuggyMatches,
621 matches,
622 contains,
623
624 // Instance-specific data
625 expando = "sizzle" + 1 * new Date(),
626 preferredDoc = window.document,
627 dirruns = 0,
628 done = 0,
629 classCache = createCache(),
630 tokenCache = createCache(),
631 compilerCache = createCache(),
632 sortOrder = function( a, b ) {
633 if ( a === b ) {
634 hasDuplicate = true;
635 }
636 return 0;
637 },
638
639 // General-purpose constants
640 MAX_NEGATIVE = 1 << 31,
641
642 // Instance methods
643 hasOwn = ({}).hasOwnProperty,
644 arr = [],
645 pop = arr.pop,
646 push_native = arr.push,
647 push = arr.push,
648 slice = arr.slice,
649 // Use a stripped-down indexOf as it's faster than native
650 // http://jsperf.com/thor-indexof-vs-for/5
651 indexOf = function( list, elem ) {
652 var i = 0,
653 len = list.length;
654 for ( ; i < len; i++ ) {
655 if ( list[i] === elem ) {
656 return i;
657 }
658 }
659 return -1;
660 },
661
662 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
663
664 // Regular expressions
665
666 // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
667 whitespace = "[\\x20\\t\\r\\n\\f]",
668 // http://www.w3.org/TR/css3-syntax/#characters
669 characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
670
671 // Loosely modeled on CSS identifier characters
672 // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
673 // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
674 identifier = characterEncoding.replace( "w", "w#" ),
675
676 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
677 attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
678 // Operator (capture 2)
679 "*([*^$|!~]?=)" + whitespace +
680 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
681 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
682 "*\\]",
683
684 pseudos = ":(" + characterEncoding + ")(?:\\((" +
685 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
686 // 1. quoted (capture 3; capture 4 or capture 5)
687 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
688 // 2. simple (capture 6)
689 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
690 // 3. anything else (capture 2)
691 ".*" +
692 ")\\)|)",
693
694 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
695 rwhitespace = new RegExp( whitespace + "+", "g" ),
696 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
697
698 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
699 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
700
701 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
702
703 rpseudo = new RegExp( pseudos ),
704 ridentifier = new RegExp( "^" + identifier + "$" ),
705
706 matchExpr = {
707 "ID": new RegExp( "^#(" + characterEncoding + ")" ),
708 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
709 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
710 "ATTR": new RegExp( "^" + attributes ),
711 "PSEUDO": new RegExp( "^" + pseudos ),
712 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
713 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
714 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
715 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
716 // For use in libraries implementing .is()
717 // We use this for POS matching in `select`
718 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
719 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
720 },
721
722 rinputs = /^(?:input|select|textarea|button)$/i,
723 rheader = /^h\d$/i,
724
725 rnative = /^[^{]+\{\s*\[native \w/,
726
727 // Easily-parseable/retrievable ID or TAG or CLASS selectors
728 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
729
730 rsibling = /[+~]/,
731 rescape = /'|\\/g,
732
733 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
734 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
735 funescape = function( _, escaped, escapedWhitespace ) {
736 var high = "0x" + escaped - 0x10000;
737 // NaN means non-codepoint
738 // Support: Firefox<24
739 // Workaround erroneous numeric interpretation of +"0x"
740 return high !== high || escapedWhitespace ?
741 escaped :
742 high < 0 ?
743 // BMP codepoint
744 String.fromCharCode( high + 0x10000 ) :
745 // Supplemental Plane codepoint (surrogate pair)
746 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
747 },
748
749 // Used for iframes
750 // See setDocument()
751 // Removing the function wrapper causes a "Permission Denied"
752 // error in IE
753 unloadHandler = function() {
754 setDocument();
755 };
756
757 // Optimize for push.apply( _, NodeList )
758 try {
759 push.apply(
760 (arr = slice.call( preferredDoc.childNodes )),
761 preferredDoc.childNodes
762 );
763 // Support: Android<4.0
764 // Detect silently failing push.apply
765 arr[ preferredDoc.childNodes.length ].nodeType;
766 } catch ( e ) {
767 push = { apply: arr.length ?
768
769 // Leverage slice if possible
770 function( target, els ) {
771 push_native.apply( target, slice.call(els) );
772 } :
773
774 // Support: IE<9
775 // Otherwise append directly
776 function( target, els ) {
777 var j = target.length,
778 i = 0;
779 // Can't trust NodeList.length
780 while ( (target[j++] = els[i++]) ) {}
781 target.length = j - 1;
782 }
783 };
784 }
785
786 function Sizzle( selector, context, results, seed ) {
787 var match, elem, m, nodeType,
788 // QSA vars
789 i, groups, old, nid, newContext, newSelector;
790
791 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
792 setDocument( context );
793 }
794
795 context = context || document;
796 results = results || [];
797 nodeType = context.nodeType;
798
799 if ( typeof selector !== "string" || !selector ||
800 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
801
802 return results;
803 }
804
805 if ( !seed && documentIsHTML ) {
806
807 // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
808 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
809 // Speed-up: Sizzle("#ID")
810 if ( (m = match[1]) ) {
811 if ( nodeType === 9 ) {
812 elem = context.getElementById( m );
813 // Check parentNode to catch when Blackberry 4.6 returns
814 // nodes that are no longer in the document (jQuery #6963)
815 if ( elem && elem.parentNode ) {
816 // Handle the case where IE, Opera, and Webkit return items
817 // by name instead of ID
818 if ( elem.id === m ) {
819 results.push( elem );
820 return results;
821 }
822 } else {
823 return results;
824 }
825 } else {
826 // Context is not a document
827 if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
828 contains( context, elem ) && elem.id === m ) {
829 results.push( elem );
830 return results;
831 }
832 }
833
834 // Speed-up: Sizzle("TAG")
835 } else if ( match[2] ) {
836 push.apply( results, context.getElementsByTagName( selector ) );
837 return results;
838
839 // Speed-up: Sizzle(".CLASS")
840 } else if ( (m = match[3]) && support.getElementsByClassName ) {
841 push.apply( results, context.getElementsByClassName( m ) );
842 return results;
843 }
844 }
845
846 // QSA path
847 if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
848 nid = old = expando;
849 newContext = context;
850 newSelector = nodeType !== 1 && selector;
851
852 // qSA works strangely on Element-rooted queries
853 // We can work around this by specifying an extra ID on the root
854 // and working up from there (Thanks to Andrew Dupont for the technique)
855 // IE 8 doesn't work on object elements
856 if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
857 groups = tokenize( selector );
858
859 if ( (old = context.getAttribute("id")) ) {
860 nid = old.replace( rescape, "\\$&" );
861 } else {
862 context.setAttribute( "id", nid );
863 }
864 nid = "[id='" + nid + "'] ";
865
866 i = groups.length;
867 while ( i-- ) {
868 groups[i] = nid + toSelector( groups[i] );
869 }
870 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
871 newSelector = groups.join(",");
872 }
873
874 if ( newSelector ) {
875 try {
876 push.apply( results,
877 newContext.querySelectorAll( newSelector )
878 );
879 return results;
880 } catch(qsaError) {
881 } finally {
882 if ( !old ) {
883 context.removeAttribute("id");
884 }
885 }
886 }
887 }
888 }
889
890 // All others
891 return select( selector.replace( rtrim, "$1" ), context, results, seed );
892 }
893
894 /**
895 * Create key-value caches of limited size
896 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
897 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
898 * deleting the oldest entry
899 */
900 function createCache() {
901 var keys = [];
902
903 function cache( key, value ) {
904 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
905 if ( keys.push( key + " " ) > Expr.cacheLength ) {
906 // Only keep the most recent entries
907 delete cache[ keys.shift() ];
908 }
909 return (cache[ key + " " ] = value);
910 }
911 return cache;
912 }
913
914 /**
915 * Mark a function for special use by Sizzle
916 * @param {Function} fn The function to mark
917 */
918 function markFunction( fn ) {
919 fn[ expando ] = true;
920 return fn;
921 }
922
923 /**
924 * Support testing using an element
925 * @param {Function} fn Passed the created div and expects a boolean result
926 */
927 function assert( fn ) {
928 var div = document.createElement("div");
929
930 try {
931 return !!fn( div );
932 } catch (e) {
933 return false;
934 } finally {
935 // Remove from its parent by default
936 if ( div.parentNode ) {
937 div.parentNode.removeChild( div );
938 }
939 // release memory in IE
940 div = null;
941 }
942 }
943
944 /**
945 * Adds the same handler for all of the specified attrs
946 * @param {String} attrs Pipe-separated list of attributes
947 * @param {Function} handler The method that will be applied
948 */
949 function addHandle( attrs, handler ) {
950 var arr = attrs.split("|"),
951 i = attrs.length;
952
953 while ( i-- ) {
954 Expr.attrHandle[ arr[i] ] = handler;
955 }
956 }
957
958 /**
959 * Checks document order of two siblings
960 * @param {Element} a
961 * @param {Element} b
962 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
963 */
964 function siblingCheck( a, b ) {
965 var cur = b && a,
966 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
967 ( ~b.sourceIndex || MAX_NEGATIVE ) -
968 ( ~a.sourceIndex || MAX_NEGATIVE );
969
970 // Use IE sourceIndex if available on both nodes
971 if ( diff ) {
972 return diff;
973 }
974
975 // Check if b follows a
976 if ( cur ) {
977 while ( (cur = cur.nextSibling) ) {
978 if ( cur === b ) {
979 return -1;
980 }
981 }
982 }
983
984 return a ? 1 : -1;
985 }
986
987 /**
988 * Returns a function to use in pseudos for input types
989 * @param {String} type
990 */
991 function createInputPseudo( type ) {
992 return function( elem ) {
993 var name = elem.nodeName.toLowerCase();
994 return name === "input" && elem.type === type;
995 };
996 }
997
998 /**
999 * Returns a function to use in pseudos for buttons
1000 * @param {String} type
1001 */
1002 function createButtonPseudo( type ) {
1003 return function( elem ) {
1004 var name = elem.nodeName.toLowerCase();
1005 return (name === "input" || name === "button") && elem.type === type;
1006 };
1007 }
1008
1009 /**
1010 * Returns a function to use in pseudos for positionals
1011 * @param {Function} fn
1012 */
1013 function createPositionalPseudo( fn ) {
1014 return markFunction(function( argument ) {
1015 argument = +argument;
1016 return markFunction(function( seed, matches ) {
1017 var j,
1018 matchIndexes = fn( [], seed.length, argument ),
1019 i = matchIndexes.length;
1020
1021 // Match elements found at the specified indexes
1022 while ( i-- ) {
1023 if ( seed[ (j = matchIndexes[i]) ] ) {
1024 seed[j] = !(matches[j] = seed[j]);
1025 }
1026 }
1027 });
1028 });
1029 }
1030
1031 /**
1032 * Checks a node for validity as a Sizzle context
1033 * @param {Element|Object=} context
1034 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1035 */
1036 function testContext( context ) {
1037 return context && typeof context.getElementsByTagName !== "undefined" && context;
1038 }
1039
1040 // Expose support vars for convenience
1041 support = Sizzle.support = {};
1042
1043 /**
1044 * Detects XML nodes
1045 * @param {Element|Object} elem An element or a document
1046 * @returns {Boolean} True iff elem is a non-HTML XML node
1047 */
1048 isXML = Sizzle.isXML = function( elem ) {
1049 // documentElement is verified for cases where it doesn't yet exist
1050 // (such as loading iframes in IE - #4833)
1051 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1052 return documentElement ? documentElement.nodeName !== "HTML" : false;
1053 };
1054
1055 /**
1056 * Sets document-related variables once based on the current document
1057 * @param {Element|Object} [doc] An element or document object to use to set the document
1058 * @returns {Object} Returns the current document
1059 */
1060 setDocument = Sizzle.setDocument = function( node ) {
1061 var hasCompare, parent,
1062 doc = node ? node.ownerDocument || node : preferredDoc;
1063
1064 // If no document and documentElement is available, return
1065 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1066 return document;
1067 }
1068
1069 // Set our document
1070 document = doc;
1071 docElem = doc.documentElement;
1072 parent = doc.defaultView;
1073
1074 // Support: IE>8
1075 // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1076 // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1077 // IE6-8 do not support the defaultView property so parent will be undefined
1078 if ( parent && parent !== parent.top ) {
1079 // IE11 does not have attachEvent, so all must suffer
1080 if ( parent.addEventListener ) {
1081 parent.addEventListener( "unload", unloadHandler, false );
1082 } else if ( parent.attachEvent ) {
1083 parent.attachEvent( "onunload", unloadHandler );
1084 }
1085 }
1086
1087 /* Support tests
1088 ---------------------------------------------------------------------- */
1089 documentIsHTML = !isXML( doc );
1090
1091 /* Attributes
1092 ---------------------------------------------------------------------- */
1093
1094 // Support: IE<8
1095 // Verify that getAttribute really returns attributes and not properties
1096 // (excepting IE8 booleans)
1097 support.attributes = assert(function( div ) {
1098 div.className = "i";
1099 return !div.getAttribute("className");
1100 });
1101
1102 /* getElement(s)By*
1103 ---------------------------------------------------------------------- */
1104
1105 // Check if getElementsByTagName("*") returns only elements
1106 support.getElementsByTagName = assert(function( div ) {
1107 div.appendChild( doc.createComment("") );
1108 return !div.getElementsByTagName("*").length;
1109 });
1110
1111 // Support: IE<9
1112 support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
1113
1114 // Support: IE<10
1115 // Check if getElementById returns elements by name
1116 // The broken getElementById methods don't pick up programatically-set names,
1117 // so use a roundabout getElementsByName test
1118 support.getById = assert(function( div ) {
1119 docElem.appendChild( div ).id = expando;
1120 return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1121 });
1122
1123 // ID find and filter
1124 if ( support.getById ) {
1125 Expr.find["ID"] = function( id, context ) {
1126 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1127 var m = context.getElementById( id );
1128 // Check parentNode to catch when Blackberry 4.6 returns
1129 // nodes that are no longer in the document #6963
1130 return m && m.parentNode ? [ m ] : [];
1131 }
1132 };
1133 Expr.filter["ID"] = function( id ) {
1134 var attrId = id.replace( runescape, funescape );
1135 return function( elem ) {
1136 return elem.getAttribute("id") === attrId;
1137 };
1138 };
1139 } else {
1140 // Support: IE6/7
1141 // getElementById is not reliable as a find shortcut
1142 delete Expr.find["ID"];
1143
1144 Expr.filter["ID"] = function( id ) {
1145 var attrId = id.replace( runescape, funescape );
1146 return function( elem ) {
1147 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
1148 return node && node.value === attrId;
1149 };
1150 };
1151 }
1152
1153 // Tag
1154 Expr.find["TAG"] = support.getElementsByTagName ?
1155 function( tag, context ) {
1156 if ( typeof context.getElementsByTagName !== "undefined" ) {
1157 return context.getElementsByTagName( tag );
1158
1159 // DocumentFragment nodes don't have gEBTN
1160 } else if ( support.qsa ) {
1161 return context.querySelectorAll( tag );
1162 }
1163 } :
1164
1165 function( tag, context ) {
1166 var elem,
1167 tmp = [],
1168 i = 0,
1169 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1170 results = context.getElementsByTagName( tag );
1171
1172 // Filter out possible comments
1173 if ( tag === "*" ) {
1174 while ( (elem = results[i++]) ) {
1175 if ( elem.nodeType === 1 ) {
1176 tmp.push( elem );
1177 }
1178 }
1179
1180 return tmp;
1181 }
1182 return results;
1183 };
1184
1185 // Class
1186 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1187 if ( documentIsHTML ) {
1188 return context.getElementsByClassName( className );
1189 }
1190 };
1191
1192 /* QSA/matchesSelector
1193 ---------------------------------------------------------------------- */
1194
1195 // QSA and matchesSelector support
1196
1197 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1198 rbuggyMatches = [];
1199
1200 // qSa(:focus) reports false when true (Chrome 21)
1201 // We allow this because of a bug in IE8/9 that throws an error
1202 // whenever `document.activeElement` is accessed on an iframe
1203 // So, we allow :focus to pass through QSA all the time to avoid the IE error
1204 // See http://bugs.jquery.com/ticket/13378
1205 rbuggyQSA = [];
1206
1207 if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1208 // Build QSA regex
1209 // Regex strategy adopted from Diego Perini
1210 assert(function( div ) {
1211 // Select is set to empty string on purpose
1212 // This is to test IE's treatment of not explicitly
1213 // setting a boolean content attribute,
1214 // since its presence should be enough
1215 // http://bugs.jquery.com/ticket/12359
1216 docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1217 "<select id='" + expando + "-\f]' msallowcapture=''>" +
1218 "<option selected=''></option></select>";
1219
1220 // Support: IE8, Opera 11-12.16
1221 // Nothing should be selected when empty strings follow ^= or $= or *=
1222 // The test attribute must be unknown in Opera but "safe" for WinRT
1223 // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1224 if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1225 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1226 }
1227
1228 // Support: IE8
1229 // Boolean attributes and "value" are not treated correctly
1230 if ( !div.querySelectorAll("[selected]").length ) {
1231 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1232 }
1233
1234 // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
1235 if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1236 rbuggyQSA.push("~=");
1237 }
1238
1239 // Webkit/Opera - :checked should return selected option elements
1240 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1241 // IE8 throws error here and will not see later tests
1242 if ( !div.querySelectorAll(":checked").length ) {
1243 rbuggyQSA.push(":checked");
1244 }
1245
1246 // Support: Safari 8+, iOS 8+
1247 // https://bugs.webkit.org/show_bug.cgi?id=136851
1248 // In-page `selector#id sibing-combinator selector` fails
1249 if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1250 rbuggyQSA.push(".#.+[+~]");
1251 }
1252 });
1253
1254 assert(function( div ) {
1255 // Support: Windows 8 Native Apps
1256 // The type and name attributes are restricted during .innerHTML assignment
1257 var input = doc.createElement("input");
1258 input.setAttribute( "type", "hidden" );
1259 div.appendChild( input ).setAttribute( "name", "D" );
1260
1261 // Support: IE8
1262 // Enforce case-sensitivity of name attribute
1263 if ( div.querySelectorAll("[name=d]").length ) {
1264 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1265 }
1266
1267 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1268 // IE8 throws error here and will not see later tests
1269 if ( !div.querySelectorAll(":enabled").length ) {
1270 rbuggyQSA.push( ":enabled", ":disabled" );
1271 }
1272
1273 // Opera 10-11 does not throw on post-comma invalid pseudos
1274 div.querySelectorAll("*,:x");
1275 rbuggyQSA.push(",.*:");
1276 });
1277 }
1278
1279 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1280 docElem.webkitMatchesSelector ||
1281 docElem.mozMatchesSelector ||
1282 docElem.oMatchesSelector ||
1283 docElem.msMatchesSelector) )) ) {
1284
1285 assert(function( div ) {
1286 // Check to see if it's possible to do matchesSelector
1287 // on a disconnected node (IE 9)
1288 support.disconnectedMatch = matches.call( div, "div" );
1289
1290 // This should fail with an exception
1291 // Gecko does not error, returns false instead
1292 matches.call( div, "[s!='']:x" );
1293 rbuggyMatches.push( "!=", pseudos );
1294 });
1295 }
1296
1297 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1298 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1299
1300 /* Contains
1301 ---------------------------------------------------------------------- */
1302 hasCompare = rnative.test( docElem.compareDocumentPosition );
1303
1304 // Element contains another
1305 // Purposefully does not implement inclusive descendent
1306 // As in, an element does not contain itself
1307 contains = hasCompare || rnative.test( docElem.contains ) ?
1308 function( a, b ) {
1309 var adown = a.nodeType === 9 ? a.documentElement : a,
1310 bup = b && b.parentNode;
1311 return a === bup || !!( bup && bup.nodeType === 1 && (
1312 adown.contains ?
1313 adown.contains( bup ) :
1314 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1315 ));
1316 } :
1317 function( a, b ) {
1318 if ( b ) {
1319 while ( (b = b.parentNode) ) {
1320 if ( b === a ) {
1321 return true;
1322 }
1323 }
1324 }
1325 return false;
1326 };
1327
1328 /* Sorting
1329 ---------------------------------------------------------------------- */
1330
1331 // Document order sorting
1332 sortOrder = hasCompare ?
1333 function( a, b ) {
1334
1335 // Flag for duplicate removal
1336 if ( a === b ) {
1337 hasDuplicate = true;
1338 return 0;
1339 }
1340
1341 // Sort on method existence if only one input has compareDocumentPosition
1342 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1343 if ( compare ) {
1344 return compare;
1345 }
1346
1347 // Calculate position if both inputs belong to the same document
1348 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1349 a.compareDocumentPosition( b ) :
1350
1351 // Otherwise we know they are disconnected
1352 1;
1353
1354 // Disconnected nodes
1355 if ( compare & 1 ||
1356 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1357
1358 // Choose the first element that is related to our preferred document
1359 if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1360 return -1;
1361 }
1362 if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1363 return 1;
1364 }
1365
1366 // Maintain original order
1367 return sortInput ?
1368 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1369 0;
1370 }
1371
1372 return compare & 4 ? -1 : 1;
1373 } :
1374 function( a, b ) {
1375 // Exit early if the nodes are identical
1376 if ( a === b ) {
1377 hasDuplicate = true;
1378 return 0;
1379 }
1380
1381 var cur,
1382 i = 0,
1383 aup = a.parentNode,
1384 bup = b.parentNode,
1385 ap = [ a ],
1386 bp = [ b ];
1387
1388 // Parentless nodes are either documents or disconnected
1389 if ( !aup || !bup ) {
1390 return a === doc ? -1 :
1391 b === doc ? 1 :
1392 aup ? -1 :
1393 bup ? 1 :
1394 sortInput ?
1395 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1396 0;
1397
1398 // If the nodes are siblings, we can do a quick check
1399 } else if ( aup === bup ) {
1400 return siblingCheck( a, b );
1401 }
1402
1403 // Otherwise we need full lists of their ancestors for comparison
1404 cur = a;
1405 while ( (cur = cur.parentNode) ) {
1406 ap.unshift( cur );
1407 }
1408 cur = b;
1409 while ( (cur = cur.parentNode) ) {
1410 bp.unshift( cur );
1411 }
1412
1413 // Walk down the tree looking for a discrepancy
1414 while ( ap[i] === bp[i] ) {
1415 i++;
1416 }
1417
1418 return i ?
1419 // Do a sibling check if the nodes have a common ancestor
1420 siblingCheck( ap[i], bp[i] ) :
1421
1422 // Otherwise nodes in our document sort first
1423 ap[i] === preferredDoc ? -1 :
1424 bp[i] === preferredDoc ? 1 :
1425 0;
1426 };
1427
1428 return doc;
1429 };
1430
1431 Sizzle.matches = function( expr, elements ) {
1432 return Sizzle( expr, null, null, elements );
1433 };
1434
1435 Sizzle.matchesSelector = function( elem, expr ) {
1436 // Set document vars if needed
1437 if ( ( elem.ownerDocument || elem ) !== document ) {
1438 setDocument( elem );
1439 }
1440
1441 // Make sure that attribute selectors are quoted
1442 expr = expr.replace( rattributeQuotes, "='$1']" );
1443
1444 if ( support.matchesSelector && documentIsHTML &&
1445 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1446 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1447
1448 try {
1449 var ret = matches.call( elem, expr );
1450
1451 // IE 9's matchesSelector returns false on disconnected nodes
1452 if ( ret || support.disconnectedMatch ||
1453 // As well, disconnected nodes are said to be in a document
1454 // fragment in IE 9
1455 elem.document && elem.document.nodeType !== 11 ) {
1456 return ret;
1457 }
1458 } catch (e) {}
1459 }
1460
1461 return Sizzle( expr, document, null, [ elem ] ).length > 0;
1462 };
1463
1464 Sizzle.contains = function( context, elem ) {
1465 // Set document vars if needed
1466 if ( ( context.ownerDocument || context ) !== document ) {
1467 setDocument( context );
1468 }
1469 return contains( context, elem );
1470 };
1471
1472 Sizzle.attr = function( elem, name ) {
1473 // Set document vars if needed
1474 if ( ( elem.ownerDocument || elem ) !== document ) {
1475 setDocument( elem );
1476 }
1477
1478 var fn = Expr.attrHandle[ name.toLowerCase() ],
1479 // Don't get fooled by Object.prototype properties (jQuery #13807)
1480 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1481 fn( elem, name, !documentIsHTML ) :
1482 undefined;
1483
1484 return val !== undefined ?
1485 val :
1486 support.attributes || !documentIsHTML ?
1487 elem.getAttribute( name ) :
1488 (val = elem.getAttributeNode(name)) && val.specified ?
1489 val.value :
1490 null;
1491 };
1492
1493 Sizzle.error = function( msg ) {
1494 throw new Error( "Syntax error, unrecognized expression: " + msg );
1495 };
1496
1497 /**
1498 * Document sorting and removing duplicates
1499 * @param {ArrayLike} results
1500 */
1501 Sizzle.uniqueSort = function( results ) {
1502 var elem,
1503 duplicates = [],
1504 j = 0,
1505 i = 0;
1506
1507 // Unless we *know* we can detect duplicates, assume their presence
1508 hasDuplicate = !support.detectDuplicates;
1509 sortInput = !support.sortStable && results.slice( 0 );
1510 results.sort( sortOrder );
1511
1512 if ( hasDuplicate ) {
1513 while ( (elem = results[i++]) ) {
1514 if ( elem === results[ i ] ) {
1515 j = duplicates.push( i );
1516 }
1517 }
1518 while ( j-- ) {
1519 results.splice( duplicates[ j ], 1 );
1520 }
1521 }
1522
1523 // Clear input after sorting to release objects
1524 // See https://github.com/jquery/sizzle/pull/225
1525 sortInput = null;
1526
1527 return results;
1528 };
1529
1530 /**
1531 * Utility function for retrieving the text value of an array of DOM nodes
1532 * @param {Array|Element} elem
1533 */
1534 getText = Sizzle.getText = function( elem ) {
1535 var node,
1536 ret = "",
1537 i = 0,
1538 nodeType = elem.nodeType;
1539
1540 if ( !nodeType ) {
1541 // If no nodeType, this is expected to be an array
1542 while ( (node = elem[i++]) ) {
1543 // Do not traverse comment nodes
1544 ret += getText( node );
1545 }
1546 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1547 // Use textContent for elements
1548 // innerText usage removed for consistency of new lines (jQuery #11153)
1549 if ( typeof elem.textContent === "string" ) {
1550 return elem.textContent;
1551 } else {
1552 // Traverse its children
1553 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1554 ret += getText( elem );
1555 }
1556 }
1557 } else if ( nodeType === 3 || nodeType === 4 ) {
1558 return elem.nodeValue;
1559 }
1560 // Do not include comment or processing instruction nodes
1561
1562 return ret;
1563 };
1564
1565 Expr = Sizzle.selectors = {
1566
1567 // Can be adjusted by the user
1568 cacheLength: 50,
1569
1570 createPseudo: markFunction,
1571
1572 match: matchExpr,
1573
1574 attrHandle: {},
1575
1576 find: {},
1577
1578 relative: {
1579 ">": { dir: "parentNode", first: true },
1580 " ": { dir: "parentNode" },
1581 "+": { dir: "previousSibling", first: true },
1582 "~": { dir: "previousSibling" }
1583 },
1584
1585 preFilter: {
1586 "ATTR": function( match ) {
1587 match[1] = match[1].replace( runescape, funescape );
1588
1589 // Move the given value to match[3] whether quoted or unquoted
1590 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1591
1592 if ( match[2] === "~=" ) {
1593 match[3] = " " + match[3] + " ";
1594 }
1595
1596 return match.slice( 0, 4 );
1597 },
1598
1599 "CHILD": function( match ) {
1600 /* matches from matchExpr["CHILD"]
1601 1 type (only|nth|...)
1602 2 what (child|of-type)
1603 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1604 4 xn-component of xn+y argument ([+-]?\d*n|)
1605 5 sign of xn-component
1606 6 x of xn-component
1607 7 sign of y-component
1608 8 y of y-component
1609 */
1610 match[1] = match[1].toLowerCase();
1611
1612 if ( match[1].slice( 0, 3 ) === "nth" ) {
1613 // nth-* requires argument
1614 if ( !match[3] ) {
1615 Sizzle.error( match[0] );
1616 }
1617
1618 // numeric x and y parameters for Expr.filter.CHILD
1619 // remember that false/true cast respectively to 0/1
1620 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1621 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1622
1623 // other types prohibit arguments
1624 } else if ( match[3] ) {
1625 Sizzle.error( match[0] );
1626 }
1627
1628 return match;
1629 },
1630
1631 "PSEUDO": function( match ) {
1632 var excess,
1633 unquoted = !match[6] && match[2];
1634
1635 if ( matchExpr["CHILD"].test( match[0] ) ) {
1636 return null;
1637 }
1638
1639 // Accept quoted arguments as-is
1640 if ( match[3] ) {
1641 match[2] = match[4] || match[5] || "";
1642
1643 // Strip excess characters from unquoted arguments
1644 } else if ( unquoted && rpseudo.test( unquoted ) &&
1645 // Get excess from tokenize (recursively)
1646 (excess = tokenize( unquoted, true )) &&
1647 // advance to the next closing parenthesis
1648 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1649
1650 // excess is a negative index
1651 match[0] = match[0].slice( 0, excess );
1652 match[2] = unquoted.slice( 0, excess );
1653 }
1654
1655 // Return only captures needed by the pseudo filter method (type and argument)
1656 return match.slice( 0, 3 );
1657 }
1658 },
1659
1660 filter: {
1661
1662 "TAG": function( nodeNameSelector ) {
1663 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1664 return nodeNameSelector === "*" ?
1665 function() { return true; } :
1666 function( elem ) {
1667 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1668 };
1669 },
1670
1671 "CLASS": function( className ) {
1672 var pattern = classCache[ className + " " ];
1673
1674 return pattern ||
1675 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1676 classCache( className, function( elem ) {
1677 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1678 });
1679 },
1680
1681 "ATTR": function( name, operator, check ) {
1682 return function( elem ) {
1683 var result = Sizzle.attr( elem, name );
1684
1685 if ( result == null ) {
1686 return operator === "!=";
1687 }
1688 if ( !operator ) {
1689 return true;
1690 }
1691
1692 result += "";
1693
1694 return operator === "=" ? result === check :
1695 operator === "!=" ? result !== check :
1696 operator === "^=" ? check && result.indexOf( check ) === 0 :
1697 operator === "*=" ? check && result.indexOf( check ) > -1 :
1698 operator === "$=" ? check && result.slice( -check.length ) === check :
1699 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1700 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1701 false;
1702 };
1703 },
1704
1705 "CHILD": function( type, what, argument, first, last ) {
1706 var simple = type.slice( 0, 3 ) !== "nth",
1707 forward = type.slice( -4 ) !== "last",
1708 ofType = what === "of-type";
1709
1710 return first === 1 && last === 0 ?
1711
1712 // Shortcut for :nth-*(n)
1713 function( elem ) {
1714 return !!elem.parentNode;
1715 } :
1716
1717 function( elem, context, xml ) {
1718 var cache, outerCache, node, diff, nodeIndex, start,
1719 dir = simple !== forward ? "nextSibling" : "previousSibling",
1720 parent = elem.parentNode,
1721 name = ofType && elem.nodeName.toLowerCase(),
1722 useCache = !xml && !ofType;
1723
1724 if ( parent ) {
1725
1726 // :(first|last|only)-(child|of-type)
1727 if ( simple ) {
1728 while ( dir ) {
1729 node = elem;
1730 while ( (node = node[ dir ]) ) {
1731 if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1732 return false;
1733 }
1734 }
1735 // Reverse direction for :only-* (if we haven't yet done so)
1736 start = dir = type === "only" && !start && "nextSibling";
1737 }
1738 return true;
1739 }
1740
1741 start = [ forward ? parent.firstChild : parent.lastChild ];
1742
1743 // non-xml :nth-child(...) stores cache data on `parent`
1744 if ( forward && useCache ) {
1745 // Seek `elem` from a previously-cached index
1746 outerCache = parent[ expando ] || (parent[ expando ] = {});
1747 cache = outerCache[ type ] || [];
1748 nodeIndex = cache[0] === dirruns && cache[1];
1749 diff = cache[0] === dirruns && cache[2];
1750 node = nodeIndex && parent.childNodes[ nodeIndex ];
1751
1752 while ( (node = ++nodeIndex && node && node[ dir ] ||
1753
1754 // Fallback to seeking `elem` from the start
1755 (diff = nodeIndex = 0) || start.pop()) ) {
1756
1757 // When found, cache indexes on `parent` and break
1758 if ( node.nodeType === 1 && ++diff && node === elem ) {
1759 outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1760 break;
1761 }
1762 }
1763
1764 // Use previously-cached element index if available
1765 } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1766 diff = cache[1];
1767
1768 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1769 } else {
1770 // Use the same loop as above to seek `elem` from the start
1771 while ( (node = ++nodeIndex && node && node[ dir ] ||
1772 (diff = nodeIndex = 0) || start.pop()) ) {
1773
1774 if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1775 // Cache the index of each encountered element
1776 if ( useCache ) {
1777 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1778 }
1779
1780 if ( node === elem ) {
1781 break;
1782 }
1783 }
1784 }
1785 }
1786
1787 // Incorporate the offset, then check against cycle size
1788 diff -= last;
1789 return diff === first || ( diff % first === 0 && diff / first >= 0 );
1790 }
1791 };
1792 },
1793
1794 "PSEUDO": function( pseudo, argument ) {
1795 // pseudo-class names are case-insensitive
1796 // http://www.w3.org/TR/selectors/#pseudo-classes
1797 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1798 // Remember that setFilters inherits from pseudos
1799 var args,
1800 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1801 Sizzle.error( "unsupported pseudo: " + pseudo );
1802
1803 // The user may use createPseudo to indicate that
1804 // arguments are needed to create the filter function
1805 // just as Sizzle does
1806 if ( fn[ expando ] ) {
1807 return fn( argument );
1808 }
1809
1810 // But maintain support for old signatures
1811 if ( fn.length > 1 ) {
1812 args = [ pseudo, pseudo, "", argument ];
1813 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1814 markFunction(function( seed, matches ) {
1815 var idx,
1816 matched = fn( seed, argument ),
1817 i = matched.length;
1818 while ( i-- ) {
1819 idx = indexOf( seed, matched[i] );
1820 seed[ idx ] = !( matches[ idx ] = matched[i] );
1821 }
1822 }) :
1823 function( elem ) {
1824 return fn( elem, 0, args );
1825 };
1826 }
1827
1828 return fn;
1829 }
1830 },
1831
1832 pseudos: {
1833 // Potentially complex pseudos
1834 "not": markFunction(function( selector ) {
1835 // Trim the selector passed to compile
1836 // to avoid treating leading and trailing
1837 // spaces as combinators
1838 var input = [],
1839 results = [],
1840 matcher = compile( selector.replace( rtrim, "$1" ) );
1841
1842 return matcher[ expando ] ?
1843 markFunction(function( seed, matches, context, xml ) {
1844 var elem,
1845 unmatched = matcher( seed, null, xml, [] ),
1846 i = seed.length;
1847
1848 // Match elements unmatched by `matcher`
1849 while ( i-- ) {
1850 if ( (elem = unmatched[i]) ) {
1851 seed[i] = !(matches[i] = elem);
1852 }
1853 }
1854 }) :
1855 function( elem, context, xml ) {
1856 input[0] = elem;
1857 matcher( input, null, xml, results );
1858 // Don't keep the element (issue #299)
1859 input[0] = null;
1860 return !results.pop();
1861 };
1862 }),
1863
1864 "has": markFunction(function( selector ) {
1865 return function( elem ) {
1866 return Sizzle( selector, elem ).length > 0;
1867 };
1868 }),
1869
1870 "contains": markFunction(function( text ) {
1871 text = text.replace( runescape, funescape );
1872 return function( elem ) {
1873 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1874 };
1875 }),
1876
1877 // "Whether an element is represented by a :lang() selector
1878 // is based solely on the element's language value
1879 // being equal to the identifier C,
1880 // or beginning with the identifier C immediately followed by "-".
1881 // The matching of C against the element's language value is performed case-insensitively.
1882 // The identifier C does not have to be a valid language name."
1883 // http://www.w3.org/TR/selectors/#lang-pseudo
1884 "lang": markFunction( function( lang ) {
1885 // lang value must be a valid identifier
1886 if ( !ridentifier.test(lang || "") ) {
1887 Sizzle.error( "unsupported lang: " + lang );
1888 }
1889 lang = lang.replace( runescape, funescape ).toLowerCase();
1890 return function( elem ) {
1891 var elemLang;
1892 do {
1893 if ( (elemLang = documentIsHTML ?
1894 elem.lang :
1895 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1896
1897 elemLang = elemLang.toLowerCase();
1898 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1899 }
1900 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1901 return false;
1902 };
1903 }),
1904
1905 // Miscellaneous
1906 "target": function( elem ) {
1907 var hash = window.location && window.location.hash;
1908 return hash && hash.slice( 1 ) === elem.id;
1909 },
1910
1911 "root": function( elem ) {
1912 return elem === docElem;
1913 },
1914
1915 "focus": function( elem ) {
1916 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1917 },
1918
1919 // Boolean properties
1920 "enabled": function( elem ) {
1921 return elem.disabled === false;
1922 },
1923
1924 "disabled": function( elem ) {
1925 return elem.disabled === true;
1926 },
1927
1928 "checked": function( elem ) {
1929 // In CSS3, :checked should return both checked and selected elements
1930 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1931 var nodeName = elem.nodeName.toLowerCase();
1932 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1933 },
1934
1935 "selected": function( elem ) {
1936 // Accessing this property makes selected-by-default
1937 // options in Safari work properly
1938 if ( elem.parentNode ) {
1939 elem.parentNode.selectedIndex;
1940 }
1941
1942 return elem.selected === true;
1943 },
1944
1945 // Contents
1946 "empty": function( elem ) {
1947 // http://www.w3.org/TR/selectors/#empty-pseudo
1948 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1949 // but not by others (comment: 8; processing instruction: 7; etc.)
1950 // nodeType < 6 works because attributes (2) do not appear as children
1951 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1952 if ( elem.nodeType < 6 ) {
1953 return false;
1954 }
1955 }
1956 return true;
1957 },
1958
1959 "parent": function( elem ) {
1960 return !Expr.pseudos["empty"]( elem );
1961 },
1962
1963 // Element/input types
1964 "header": function( elem ) {
1965 return rheader.test( elem.nodeName );
1966 },
1967
1968 "input": function( elem ) {
1969 return rinputs.test( elem.nodeName );
1970 },
1971
1972 "button": function( elem ) {
1973 var name = elem.nodeName.toLowerCase();
1974 return name === "input" && elem.type === "button" || name === "button";
1975 },
1976
1977 "text": function( elem ) {
1978 var attr;
1979 return elem.nodeName.toLowerCase() === "input" &&
1980 elem.type === "text" &&
1981
1982 // Support: IE<8
1983 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1984 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1985 },
1986
1987 // Position-in-collection
1988 "first": createPositionalPseudo(function() {
1989 return [ 0 ];
1990 }),
1991
1992 "last": createPositionalPseudo(function( matchIndexes, length ) {
1993 return [ length - 1 ];
1994 }),
1995
1996 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1997 return [ argument < 0 ? argument + length : argument ];
1998 }),
1999
2000 "even": createPositionalPseudo(function( matchIndexes, length ) {
2001 var i = 0;
2002 for ( ; i < length; i += 2 ) {
2003 matchIndexes.push( i );
2004 }
2005 return matchIndexes;
2006 }),
2007
2008 "odd": createPositionalPseudo(function( matchIndexes, length ) {
2009 var i = 1;
2010 for ( ; i < length; i += 2 ) {
2011 matchIndexes.push( i );
2012 }
2013 return matchIndexes;
2014 }),
2015
2016 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2017 var i = argument < 0 ? argument + length : argument;
2018 for ( ; --i >= 0; ) {
2019 matchIndexes.push( i );
2020 }
2021 return matchIndexes;
2022 }),
2023
2024 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2025 var i = argument < 0 ? argument + length : argument;
2026 for ( ; ++i < length; ) {
2027 matchIndexes.push( i );
2028 }
2029 return matchIndexes;
2030 })
2031 }
2032 };
2033
2034 Expr.pseudos["nth"] = Expr.pseudos["eq"];
2035
2036 // Add button/input type pseudos
2037 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2038 Expr.pseudos[ i ] = createInputPseudo( i );
2039 }
2040 for ( i in { submit: true, reset: true } ) {
2041 Expr.pseudos[ i ] = createButtonPseudo( i );
2042 }
2043
2044 // Easy API for creating new setFilters
2045 function setFilters() {}
2046 setFilters.prototype = Expr.filters = Expr.pseudos;
2047 Expr.setFilters = new setFilters();
2048
2049 tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2050 var matched, match, tokens, type,
2051 soFar, groups, preFilters,
2052 cached = tokenCache[ selector + " " ];
2053
2054 if ( cached ) {
2055 return parseOnly ? 0 : cached.slice( 0 );
2056 }
2057
2058 soFar = selector;
2059 groups = [];
2060 preFilters = Expr.preFilter;
2061
2062 while ( soFar ) {
2063
2064 // Comma and first run
2065 if ( !matched || (match = rcomma.exec( soFar )) ) {
2066 if ( match ) {
2067 // Don't consume trailing commas as valid
2068 soFar = soFar.slice( match[0].length ) || soFar;
2069 }
2070 groups.push( (tokens = []) );
2071 }
2072
2073 matched = false;
2074
2075 // Combinators
2076 if ( (match = rcombinators.exec( soFar )) ) {
2077 matched = match.shift();
2078 tokens.push({
2079 value: matched,
2080 // Cast descendant combinators to space
2081 type: match[0].replace( rtrim, " " )
2082 });
2083 soFar = soFar.slice( matched.length );
2084 }
2085
2086 // Filters
2087 for ( type in Expr.filter ) {
2088 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2089 (match = preFilters[ type ]( match ))) ) {
2090 matched = match.shift();
2091 tokens.push({
2092 value: matched,
2093 type: type,
2094 matches: match
2095 });
2096 soFar = soFar.slice( matched.length );
2097 }
2098 }
2099
2100 if ( !matched ) {
2101 break;
2102 }
2103 }
2104
2105 // Return the length of the invalid excess
2106 // if we're just parsing
2107 // Otherwise, throw an error or return tokens
2108 return parseOnly ?
2109 soFar.length :
2110 soFar ?
2111 Sizzle.error( selector ) :
2112 // Cache the tokens
2113 tokenCache( selector, groups ).slice( 0 );
2114 };
2115
2116 function toSelector( tokens ) {
2117 var i = 0,
2118 len = tokens.length,
2119 selector = "";
2120 for ( ; i < len; i++ ) {
2121 selector += tokens[i].value;
2122 }
2123 return selector;
2124 }
2125
2126 function addCombinator( matcher, combinator, base ) {
2127 var dir = combinator.dir,
2128 checkNonElements = base && dir === "parentNode",
2129 doneName = done++;
2130
2131 return combinator.first ?
2132 // Check against closest ancestor/preceding element
2133 function( elem, context, xml ) {
2134 while ( (elem = elem[ dir ]) ) {
2135 if ( elem.nodeType === 1 || checkNonElements ) {
2136 return matcher( elem, context, xml );
2137 }
2138 }
2139 } :
2140
2141 // Check against all ancestor/preceding elements
2142 function( elem, context, xml ) {
2143 var oldCache, outerCache,
2144 newCache = [ dirruns, doneName ];
2145
2146 // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2147 if ( xml ) {
2148 while ( (elem = elem[ dir ]) ) {
2149 if ( elem.nodeType === 1 || checkNonElements ) {
2150 if ( matcher( elem, context, xml ) ) {
2151 return true;
2152 }
2153 }
2154 }
2155 } else {
2156 while ( (elem = elem[ dir ]) ) {
2157 if ( elem.nodeType === 1 || checkNonElements ) {
2158 outerCache = elem[ expando ] || (elem[ expando ] = {});
2159 if ( (oldCache = outerCache[ dir ]) &&
2160 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2161
2162 // Assign to newCache so results back-propagate to previous elements
2163 return (newCache[ 2 ] = oldCache[ 2 ]);
2164 } else {
2165 // Reuse newcache so results back-propagate to previous elements
2166 outerCache[ dir ] = newCache;
2167
2168 // A match means we're done; a fail means we have to keep checking
2169 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2170 return true;
2171 }
2172 }
2173 }
2174 }
2175 }
2176 };
2177 }
2178
2179 function elementMatcher( matchers ) {
2180 return matchers.length > 1 ?
2181 function( elem, context, xml ) {
2182 var i = matchers.length;
2183 while ( i-- ) {
2184 if ( !matchers[i]( elem, context, xml ) ) {
2185 return false;
2186 }
2187 }
2188 return true;
2189 } :
2190 matchers[0];
2191 }
2192
2193 function multipleContexts( selector, contexts, results ) {
2194 var i = 0,
2195 len = contexts.length;
2196 for ( ; i < len; i++ ) {
2197 Sizzle( selector, contexts[i], results );
2198 }
2199 return results;
2200 }
2201
2202 function condense( unmatched, map, filter, context, xml ) {
2203 var elem,
2204 newUnmatched = [],
2205 i = 0,
2206 len = unmatched.length,
2207 mapped = map != null;
2208
2209 for ( ; i < len; i++ ) {
2210 if ( (elem = unmatched[i]) ) {
2211 if ( !filter || filter( elem, context, xml ) ) {
2212 newUnmatched.push( elem );
2213 if ( mapped ) {
2214 map.push( i );
2215 }
2216 }
2217 }
2218 }
2219
2220 return newUnmatched;
2221 }
2222
2223 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2224 if ( postFilter && !postFilter[ expando ] ) {
2225 postFilter = setMatcher( postFilter );
2226 }
2227 if ( postFinder && !postFinder[ expando ] ) {
2228 postFinder = setMatcher( postFinder, postSelector );
2229 }
2230 return markFunction(function( seed, results, context, xml ) {
2231 var temp, i, elem,
2232 preMap = [],
2233 postMap = [],
2234 preexisting = results.length,
2235
2236 // Get initial elements from seed or context
2237 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2238
2239 // Prefilter to get matcher input, preserving a map for seed-results synchronization
2240 matcherIn = preFilter && ( seed || !selector ) ?
2241 condense( elems, preMap, preFilter, context, xml ) :
2242 elems,
2243
2244 matcherOut = matcher ?
2245 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2246 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2247
2248 // ...intermediate processing is necessary
2249 [] :
2250
2251 // ...otherwise use results directly
2252 results :
2253 matcherIn;
2254
2255 // Find primary matches
2256 if ( matcher ) {
2257 matcher( matcherIn, matcherOut, context, xml );
2258 }
2259
2260 // Apply postFilter
2261 if ( postFilter ) {
2262 temp = condense( matcherOut, postMap );
2263 postFilter( temp, [], context, xml );
2264
2265 // Un-match failing elements by moving them back to matcherIn
2266 i = temp.length;
2267 while ( i-- ) {
2268 if ( (elem = temp[i]) ) {
2269 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2270 }
2271 }
2272 }
2273
2274 if ( seed ) {
2275 if ( postFinder || preFilter ) {
2276 if ( postFinder ) {
2277 // Get the final matcherOut by condensing this intermediate into postFinder contexts
2278 temp = [];
2279 i = matcherOut.length;
2280 while ( i-- ) {
2281 if ( (elem = matcherOut[i]) ) {
2282 // Restore matcherIn since elem is not yet a final match
2283 temp.push( (matcherIn[i] = elem) );
2284 }
2285 }
2286 postFinder( null, (matcherOut = []), temp, xml );
2287 }
2288
2289 // Move matched elements from seed to results to keep them synchronized
2290 i = matcherOut.length;
2291 while ( i-- ) {
2292 if ( (elem = matcherOut[i]) &&
2293 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2294
2295 seed[temp] = !(results[temp] = elem);
2296 }
2297 }
2298 }
2299
2300 // Add elements to results, through postFinder if defined
2301 } else {
2302 matcherOut = condense(
2303 matcherOut === results ?
2304 matcherOut.splice( preexisting, matcherOut.length ) :
2305 matcherOut
2306 );
2307 if ( postFinder ) {
2308 postFinder( null, results, matcherOut, xml );
2309 } else {
2310 push.apply( results, matcherOut );
2311 }
2312 }
2313 });
2314 }
2315
2316 function matcherFromTokens( tokens ) {
2317 var checkContext, matcher, j,
2318 len = tokens.length,
2319 leadingRelative = Expr.relative[ tokens[0].type ],
2320 implicitRelative = leadingRelative || Expr.relative[" "],
2321 i = leadingRelative ? 1 : 0,
2322
2323 // The foundational matcher ensures that elements are reachable from top-level context(s)
2324 matchContext = addCombinator( function( elem ) {
2325 return elem === checkContext;
2326 }, implicitRelative, true ),
2327 matchAnyContext = addCombinator( function( elem ) {
2328 return indexOf( checkContext, elem ) > -1;
2329 }, implicitRelative, true ),
2330 matchers = [ function( elem, context, xml ) {
2331 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2332 (checkContext = context).nodeType ?
2333 matchContext( elem, context, xml ) :
2334 matchAnyContext( elem, context, xml ) );
2335 // Avoid hanging onto element (issue #299)
2336 checkContext = null;
2337 return ret;
2338 } ];
2339
2340 for ( ; i < len; i++ ) {
2341 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2342 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2343 } else {
2344 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2345
2346 // Return special upon seeing a positional matcher
2347 if ( matcher[ expando ] ) {
2348 // Find the next relative operator (if any) for proper handling
2349 j = ++i;
2350 for ( ; j < len; j++ ) {
2351 if ( Expr.relative[ tokens[j].type ] ) {
2352 break;
2353 }
2354 }
2355 return setMatcher(
2356 i > 1 && elementMatcher( matchers ),
2357 i > 1 && toSelector(
2358 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2359 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2360 ).replace( rtrim, "$1" ),
2361 matcher,
2362 i < j && matcherFromTokens( tokens.slice( i, j ) ),
2363 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2364 j < len && toSelector( tokens )
2365 );
2366 }
2367 matchers.push( matcher );
2368 }
2369 }
2370
2371 return elementMatcher( matchers );
2372 }
2373
2374 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2375 var bySet = setMatchers.length > 0,
2376 byElement = elementMatchers.length > 0,
2377 superMatcher = function( seed, context, xml, results, outermost ) {
2378 var elem, j, matcher,
2379 matchedCount = 0,
2380 i = "0",
2381 unmatched = seed && [],
2382 setMatched = [],
2383 contextBackup = outermostContext,
2384 // We must always have either seed elements or outermost context
2385 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2386 // Use integer dirruns iff this is the outermost matcher
2387 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2388 len = elems.length;
2389
2390 if ( outermost ) {
2391 outermostContext = context !== document && context;
2392 }
2393
2394 // Add elements passing elementMatchers directly to results
2395 // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2396 // Support: IE<9, Safari
2397 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2398 for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2399 if ( byElement && elem ) {
2400 j = 0;
2401 while ( (matcher = elementMatchers[j++]) ) {
2402 if ( matcher( elem, context, xml ) ) {
2403 results.push( elem );
2404 break;
2405 }
2406 }
2407 if ( outermost ) {
2408 dirruns = dirrunsUnique;
2409 }
2410 }
2411
2412 // Track unmatched elements for set filters
2413 if ( bySet ) {
2414 // They will have gone through all possible matchers
2415 if ( (elem = !matcher && elem) ) {
2416 matchedCount--;
2417 }
2418
2419 // Lengthen the array for every element, matched or not
2420 if ( seed ) {
2421 unmatched.push( elem );
2422 }
2423 }
2424 }
2425
2426 // Apply set filters to unmatched elements
2427 matchedCount += i;
2428 if ( bySet && i !== matchedCount ) {
2429 j = 0;
2430 while ( (matcher = setMatchers[j++]) ) {
2431 matcher( unmatched, setMatched, context, xml );
2432 }
2433
2434 if ( seed ) {
2435 // Reintegrate element matches to eliminate the need for sorting
2436 if ( matchedCount > 0 ) {
2437 while ( i-- ) {
2438 if ( !(unmatched[i] || setMatched[i]) ) {
2439 setMatched[i] = pop.call( results );
2440 }
2441 }
2442 }
2443
2444 // Discard index placeholder values to get only actual matches
2445 setMatched = condense( setMatched );
2446 }
2447
2448 // Add matches to results
2449 push.apply( results, setMatched );
2450
2451 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2452 if ( outermost && !seed && setMatched.length > 0 &&
2453 ( matchedCount + setMatchers.length ) > 1 ) {
2454
2455 Sizzle.uniqueSort( results );
2456 }
2457 }
2458
2459 // Override manipulation of globals by nested matchers
2460 if ( outermost ) {
2461 dirruns = dirrunsUnique;
2462 outermostContext = contextBackup;
2463 }
2464
2465 return unmatched;
2466 };
2467
2468 return bySet ?
2469 markFunction( superMatcher ) :
2470 superMatcher;
2471 }
2472
2473 compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2474 var i,
2475 setMatchers = [],
2476 elementMatchers = [],
2477 cached = compilerCache[ selector + " " ];
2478
2479 if ( !cached ) {
2480 // Generate a function of recursive functions that can be used to check each element
2481 if ( !match ) {
2482 match = tokenize( selector );
2483 }
2484 i = match.length;
2485 while ( i-- ) {
2486 cached = matcherFromTokens( match[i] );
2487 if ( cached[ expando ] ) {
2488 setMatchers.push( cached );
2489 } else {
2490 elementMatchers.push( cached );
2491 }
2492 }
2493
2494 // Cache the compiled function
2495 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2496
2497 // Save selector and tokenization
2498 cached.selector = selector;
2499 }
2500 return cached;
2501 };
2502
2503 /**
2504 * A low-level selection function that works with Sizzle's compiled
2505 * selector functions
2506 * @param {String|Function} selector A selector or a pre-compiled
2507 * selector function built with Sizzle.compile
2508 * @param {Element} context
2509 * @param {Array} [results]
2510 * @param {Array} [seed] A set of elements to match against
2511 */
2512 select = Sizzle.select = function( selector, context, results, seed ) {
2513 var i, tokens, token, type, find,
2514 compiled = typeof selector === "function" && selector,
2515 match = !seed && tokenize( (selector = compiled.selector || selector) );
2516
2517 results = results || [];
2518
2519 // Try to minimize operations if there is no seed and only one group
2520 if ( match.length === 1 ) {
2521
2522 // Take a shortcut and set the context if the root selector is an ID
2523 tokens = match[0] = match[0].slice( 0 );
2524 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2525 support.getById && context.nodeType === 9 && documentIsHTML &&
2526 Expr.relative[ tokens[1].type ] ) {
2527
2528 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2529 if ( !context ) {
2530 return results;
2531
2532 // Precompiled matchers will still verify ancestry, so step up a level
2533 } else if ( compiled ) {
2534 context = context.parentNode;
2535 }
2536
2537 selector = selector.slice( tokens.shift().value.length );
2538 }
2539
2540 // Fetch a seed set for right-to-left matching
2541 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2542 while ( i-- ) {
2543 token = tokens[i];
2544
2545 // Abort if we hit a combinator
2546 if ( Expr.relative[ (type = token.type) ] ) {
2547 break;
2548 }
2549 if ( (find = Expr.find[ type ]) ) {
2550 // Search, expanding context for leading sibling combinators
2551 if ( (seed = find(
2552 token.matches[0].replace( runescape, funescape ),
2553 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2554 )) ) {
2555
2556 // If seed is empty or no tokens remain, we can return early
2557 tokens.splice( i, 1 );
2558 selector = seed.length && toSelector( tokens );
2559 if ( !selector ) {
2560 push.apply( results, seed );
2561 return results;
2562 }
2563
2564 break;
2565 }
2566 }
2567 }
2568 }
2569
2570 // Compile and execute a filtering function if one is not provided
2571 // Provide `match` to avoid retokenization if we modified the selector above
2572 ( compiled || compile( selector, match ) )(
2573 seed,
2574 context,
2575 !documentIsHTML,
2576 results,
2577 rsibling.test( selector ) && testContext( context.parentNode ) || context
2578 );
2579 return results;
2580 };
2581
2582 // One-time assignments
2583
2584 // Sort stability
2585 support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2586
2587 // Support: Chrome 14-35+
2588 // Always assume duplicates if they aren't passed to the comparison function
2589 support.detectDuplicates = !!hasDuplicate;
2590
2591 // Initialize against the default document
2592 setDocument();
2593
2594 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2595 // Detached nodes confoundingly follow *each other*
2596 support.sortDetached = assert(function( div1 ) {
2597 // Should return 1, but returns 4 (following)
2598 return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2599 });
2600
2601 // Support: IE<8
2602 // Prevent attribute/property "interpolation"
2603 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2604 if ( !assert(function( div ) {
2605 div.innerHTML = "<a href='#'></a>";
2606 return div.firstChild.getAttribute("href") === "#" ;
2607 }) ) {
2608 addHandle( "type|href|height|width", function( elem, name, isXML ) {
2609 if ( !isXML ) {
2610 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2611 }
2612 });
2613 }
2614
2615 // Support: IE<9
2616 // Use defaultValue in place of getAttribute("value")
2617 if ( !support.attributes || !assert(function( div ) {
2618 div.innerHTML = "<input/>";
2619 div.firstChild.setAttribute( "value", "" );
2620 return div.firstChild.getAttribute( "value" ) === "";
2621 }) ) {
2622 addHandle( "value", function( elem, name, isXML ) {
2623 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2624 return elem.defaultValue;
2625 }
2626 });
2627 }
2628
2629 // Support: IE<9
2630 // Use getAttributeNode to fetch booleans when getAttribute lies
2631 if ( !assert(function( div ) {
2632 return div.getAttribute("disabled") == null;
2633 }) ) {
2634 addHandle( booleans, function( elem, name, isXML ) {
2635 var val;
2636 if ( !isXML ) {
2637 return elem[ name ] === true ? name.toLowerCase() :
2638 (val = elem.getAttributeNode( name )) && val.specified ?
2639 val.value :
2640 null;
2641 }
2642 });
2643 }
2644
2645 return Sizzle;
2646
2647 })( window );
2648
2649
2650
2651 jQuery.find = Sizzle;
2652 jQuery.expr = Sizzle.selectors;
2653 jQuery.expr[":"] = jQuery.expr.pseudos;
2654 jQuery.unique = Sizzle.uniqueSort;
2655 jQuery.text = Sizzle.getText;
2656 jQuery.isXMLDoc = Sizzle.isXML;
2657 jQuery.contains = Sizzle.contains;
2658
2659
2660
2661 var rneedsContext = jQuery.expr.match.needsContext;
2662
2663 var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
2664
2665
2666
2667 var risSimple = /^.[^:#\[\.,]*$/;
2668
2669 // Implement the identical functionality for filter and not
2670 function winnow( elements, qualifier, not ) {
2671 if ( jQuery.isFunction( qualifier ) ) {
2672 return jQuery.grep( elements, function( elem, i ) {
2673 /* jshint -W018 */
2674 return !!qualifier.call( elem, i, elem ) !== not;
2675 });
2676
2677 }
2678
2679 if ( qualifier.nodeType ) {
2680 return jQuery.grep( elements, function( elem ) {
2681 return ( elem === qualifier ) !== not;
2682 });
2683
2684 }
2685
2686 if ( typeof qualifier === "string" ) {
2687 if ( risSimple.test( qualifier ) ) {
2688 return jQuery.filter( qualifier, elements, not );
2689 }
2690
2691 qualifier = jQuery.filter( qualifier, elements );
2692 }
2693
2694 return jQuery.grep( elements, function( elem ) {
2695 return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
2696 });
2697 }
2698
2699 jQuery.filter = function( expr, elems, not ) {
2700 var elem = elems[ 0 ];
2701
2702 if ( not ) {
2703 expr = ":not(" + expr + ")";
2704 }
2705
2706 return elems.length === 1 && elem.nodeType === 1 ?
2707 jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2708 jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2709 return elem.nodeType === 1;
2710 }));
2711 };
2712
2713 jQuery.fn.extend({
2714 find: function( selector ) {
2715 var i,
2716 ret = [],
2717 self = this,
2718 len = self.length;
2719
2720 if ( typeof selector !== "string" ) {
2721 return this.pushStack( jQuery( selector ).filter(function() {
2722 for ( i = 0; i < len; i++ ) {
2723 if ( jQuery.contains( self[ i ], this ) ) {
2724 return true;
2725 }
2726 }
2727 }) );
2728 }
2729
2730 for ( i = 0; i < len; i++ ) {
2731 jQuery.find( selector, self[ i ], ret );
2732 }
2733
2734 // Needed because $( selector, context ) becomes $( context ).find( selector )
2735 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2736 ret.selector = this.selector ? this.selector + " " + selector : selector;
2737 return ret;
2738 },
2739 filter: function( selector ) {
2740 return this.pushStack( winnow(this, selector || [], false) );
2741 },
2742 not: function( selector ) {
2743 return this.pushStack( winnow(this, selector || [], true) );
2744 },
2745 is: function( selector ) {
2746 return !!winnow(
2747 this,
2748
2749 // If this is a positional/relative selector, check membership in the returned set
2750 // so $("p:first").is("p:last") won't return true for a doc with two "p".
2751 typeof selector === "string" && rneedsContext.test( selector ) ?
2752 jQuery( selector ) :
2753 selector || [],
2754 false
2755 ).length;
2756 }
2757 });
2758
2759
2760 // Initialize a jQuery object
2761
2762
2763 // A central reference to the root jQuery(document)
2764 var rootjQuery,
2765
2766 // Use the correct document accordingly with window argument (sandbox)
2767 document = window.document,
2768
2769 // A simple way to check for HTML strings
2770 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2771 // Strict HTML recognition (#11290: must start with <)
2772 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2773
2774 init = jQuery.fn.init = function( selector, context ) {
2775 var match, elem;
2776
2777 // HANDLE: $(""), $(null), $(undefined), $(false)
2778 if ( !selector ) {
2779 return this;
2780 }
2781
2782 // Handle HTML strings
2783 if ( typeof selector === "string" ) {
2784 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
2785 // Assume that strings that start and end with <> are HTML and skip the regex check
2786 match = [ null, selector, null ];
2787
2788 } else {
2789 match = rquickExpr.exec( selector );
2790 }
2791
2792 // Match html or make sure no context is specified for #id
2793 if ( match && (match[1] || !context) ) {
2794
2795 // HANDLE: $(html) -> $(array)
2796 if ( match[1] ) {
2797 context = context instanceof jQuery ? context[0] : context;
2798
2799 // scripts is true for back-compat
2800 // Intentionally let the error be thrown if parseHTML is not present
2801 jQuery.merge( this, jQuery.parseHTML(
2802 match[1],
2803 context && context.nodeType ? context.ownerDocument || context : document,
2804 true
2805 ) );
2806
2807 // HANDLE: $(html, props)
2808 if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
2809 for ( match in context ) {
2810 // Properties of context are called as methods if possible
2811 if ( jQuery.isFunction( this[ match ] ) ) {
2812 this[ match ]( context[ match ] );
2813
2814 // ...and otherwise set as attributes
2815 } else {
2816 this.attr( match, context[ match ] );
2817 }
2818 }
2819 }
2820
2821 return this;
2822
2823 // HANDLE: $(#id)
2824 } else {
2825 elem = document.getElementById( match[2] );
2826
2827 // Check parentNode to catch when Blackberry 4.6 returns
2828 // nodes that are no longer in the document #6963
2829 if ( elem && elem.parentNode ) {
2830 // Handle the case where IE and Opera return items
2831 // by name instead of ID
2832 if ( elem.id !== match[2] ) {
2833 return rootjQuery.find( selector );
2834 }
2835
2836 // Otherwise, we inject the element directly into the jQuery object
2837 this.length = 1;
2838 this[0] = elem;
2839 }
2840
2841 this.context = document;
2842 this.selector = selector;
2843 return this;
2844 }
2845
2846 // HANDLE: $(expr, $(...))
2847 } else if ( !context || context.jquery ) {
2848 return ( context || rootjQuery ).find( selector );
2849
2850 // HANDLE: $(expr, context)
2851 // (which is just equivalent to: $(context).find(expr)
2852 } else {
2853 return this.constructor( context ).find( selector );
2854 }
2855
2856 // HANDLE: $(DOMElement)
2857 } else if ( selector.nodeType ) {
2858 this.context = this[0] = selector;
2859 this.length = 1;
2860 return this;
2861
2862 // HANDLE: $(function)
2863 // Shortcut for document ready
2864 } else if ( jQuery.isFunction( selector ) ) {
2865 return typeof rootjQuery.ready !== "undefined" ?
2866 rootjQuery.ready( selector ) :
2867 // Execute immediately if ready is not present
2868 selector( jQuery );
2869 }
2870
2871 if ( selector.selector !== undefined ) {
2872 this.selector = selector.selector;
2873 this.context = selector.context;
2874 }
2875
2876 return jQuery.makeArray( selector, this );
2877 };
2878
2879 // Give the init function the jQuery prototype for later instantiation
2880 init.prototype = jQuery.fn;
2881
2882 // Initialize central reference
2883 rootjQuery = jQuery( document );
2884
2885
2886 var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2887 // methods guaranteed to produce a unique set when starting from a unique set
2888 guaranteedUnique = {
2889 children: true,
2890 contents: true,
2891 next: true,
2892 prev: true
2893 };
2894
2895 jQuery.extend({
2896 dir: function( elem, dir, until ) {
2897 var matched = [],
2898 cur = elem[ dir ];
2899
2900 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
2901 if ( cur.nodeType === 1 ) {
2902 matched.push( cur );
2903 }
2904 cur = cur[dir];
2905 }
2906 return matched;
2907 },
2908
2909 sibling: function( n, elem ) {
2910 var r = [];
2911
2912 for ( ; n; n = n.nextSibling ) {
2913 if ( n.nodeType === 1 && n !== elem ) {
2914 r.push( n );
2915 }
2916 }
2917
2918 return r;
2919 }
2920 });
2921
2922 jQuery.fn.extend({
2923 has: function( target ) {
2924 var i,
2925 targets = jQuery( target, this ),
2926 len = targets.length;
2927
2928 return this.filter(function() {
2929 for ( i = 0; i < len; i++ ) {
2930 if ( jQuery.contains( this, targets[i] ) ) {
2931 return true;
2932 }
2933 }
2934 });
2935 },
2936
2937 closest: function( selectors, context ) {
2938 var cur,
2939 i = 0,
2940 l = this.length,
2941 matched = [],
2942 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2943 jQuery( selectors, context || this.context ) :
2944 0;
2945
2946 for ( ; i < l; i++ ) {
2947 for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
2948 // Always skip document fragments
2949 if ( cur.nodeType < 11 && (pos ?
2950 pos.index(cur) > -1 :
2951
2952 // Don't pass non-elements to Sizzle
2953 cur.nodeType === 1 &&
2954 jQuery.find.matchesSelector(cur, selectors)) ) {
2955
2956 matched.push( cur );
2957 break;
2958 }
2959 }
2960 }
2961
2962 return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
2963 },
2964
2965 // Determine the position of an element within
2966 // the matched set of elements
2967 index: function( elem ) {
2968
2969 // No argument, return index in parent
2970 if ( !elem ) {
2971 return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
2972 }
2973
2974 // index in selector
2975 if ( typeof elem === "string" ) {
2976 return jQuery.inArray( this[0], jQuery( elem ) );
2977 }
2978
2979 // Locate the position of the desired element
2980 return jQuery.inArray(
2981 // If it receives a jQuery object, the first element is used
2982 elem.jquery ? elem[0] : elem, this );
2983 },
2984
2985 add: function( selector, context ) {
2986 return this.pushStack(
2987 jQuery.unique(
2988 jQuery.merge( this.get(), jQuery( selector, context ) )
2989 )
2990 );
2991 },
2992
2993 addBack: function( selector ) {
2994 return this.add( selector == null ?
2995 this.prevObject : this.prevObject.filter(selector)
2996 );
2997 }
2998 });
2999
3000 function sibling( cur, dir ) {
3001 do {
3002 cur = cur[ dir ];
3003 } while ( cur && cur.nodeType !== 1 );
3004
3005 return cur;
3006 }
3007
3008 jQuery.each({
3009 parent: function( elem ) {
3010 var parent = elem.parentNode;
3011 return parent && parent.nodeType !== 11 ? parent : null;
3012 },
3013 parents: function( elem ) {
3014 return jQuery.dir( elem, "parentNode" );
3015 },
3016 parentsUntil: function( elem, i, until ) {
3017 return jQuery.dir( elem, "parentNode", until );
3018 },
3019 next: function( elem ) {
3020 return sibling( elem, "nextSibling" );
3021 },
3022 prev: function( elem ) {
3023 return sibling( elem, "previousSibling" );
3024 },
3025 nextAll: function( elem ) {
3026 return jQuery.dir( elem, "nextSibling" );
3027 },
3028 prevAll: function( elem ) {
3029 return jQuery.dir( elem, "previousSibling" );
3030 },
3031 nextUntil: function( elem, i, until ) {
3032 return jQuery.dir( elem, "nextSibling", until );
3033 },
3034 prevUntil: function( elem, i, until ) {
3035 return jQuery.dir( elem, "previousSibling", until );
3036 },
3037 siblings: function( elem ) {
3038 return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
3039 },
3040 children: function( elem ) {
3041 return jQuery.sibling( elem.firstChild );
3042 },
3043 contents: function( elem ) {
3044 return jQuery.nodeName( elem, "iframe" ) ?
3045 elem.contentDocument || elem.contentWindow.document :
3046 jQuery.merge( [], elem.childNodes );
3047 }
3048 }, function( name, fn ) {
3049 jQuery.fn[ name ] = function( until, selector ) {
3050 var ret = jQuery.map( this, fn, until );
3051
3052 if ( name.slice( -5 ) !== "Until" ) {
3053 selector = until;
3054 }
3055
3056 if ( selector && typeof selector === "string" ) {
3057 ret = jQuery.filter( selector, ret );
3058 }
3059
3060 if ( this.length > 1 ) {
3061 // Remove duplicates
3062 if ( !guaranteedUnique[ name ] ) {
3063 ret = jQuery.unique( ret );
3064 }
3065
3066 // Reverse order for parents* and prev-derivatives
3067 if ( rparentsprev.test( name ) ) {
3068 ret = ret.reverse();
3069 }
3070 }
3071
3072 return this.pushStack( ret );
3073 };
3074 });
3075 var rnotwhite = (/\S+/g);
3076
3077
3078
3079 // String to Object options format cache
3080 var optionsCache = {};
3081
3082 // Convert String-formatted options into Object-formatted ones and store in cache
3083 function createOptions( options ) {
3084 var object = optionsCache[ options ] = {};
3085 jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3086 object[ flag ] = true;
3087 });
3088 return object;
3089 }
3090
3091 /*
3092 * Create a callback list using the following parameters:
3093 *
3094 * options: an optional list of space-separated options that will change how
3095 * the callback list behaves or a more traditional option object
3096 *
3097 * By default a callback list will act like an event callback list and can be
3098 * "fired" multiple times.
3099 *
3100 * Possible options:
3101 *
3102 * once: will ensure the callback list can only be fired once (like a Deferred)
3103 *
3104 * memory: will keep track of previous values and will call any callback added
3105 * after the list has been fired right away with the latest "memorized"
3106 * values (like a Deferred)
3107 *
3108 * unique: will ensure a callback can only be added once (no duplicate in the list)
3109 *
3110 * stopOnFalse: interrupt callings when a callback returns false
3111 *
3112 */
3113 jQuery.Callbacks = function( options ) {
3114
3115 // Convert options from String-formatted to Object-formatted if needed
3116 // (we check in cache first)
3117 options = typeof options === "string" ?
3118 ( optionsCache[ options ] || createOptions( options ) ) :
3119 jQuery.extend( {}, options );
3120
3121 var // Flag to know if list is currently firing
3122 firing,
3123 // Last fire value (for non-forgettable lists)
3124 memory,
3125 // Flag to know if list was already fired
3126 fired,
3127 // End of the loop when firing
3128 firingLength,
3129 // Index of currently firing callback (modified by remove if needed)
3130 firingIndex,
3131 // First callback to fire (used internally by add and fireWith)
3132 firingStart,
3133 // Actual callback list
3134 list = [],
3135 // Stack of fire calls for repeatable lists
3136 stack = !options.once && [],
3137 // Fire callbacks
3138 fire = function( data ) {
3139 memory = options.memory && data;
3140 fired = true;
3141 firingIndex = firingStart || 0;
3142 firingStart = 0;
3143 firingLength = list.length;
3144 firing = true;
3145 for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3146 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3147 memory = false; // To prevent further calls using add
3148 break;
3149 }
3150 }
3151 firing = false;
3152 if ( list ) {
3153 if ( stack ) {
3154 if ( stack.length ) {
3155 fire( stack.shift() );
3156 }
3157 } else if ( memory ) {
3158 list = [];
3159 } else {
3160 self.disable();
3161 }
3162 }
3163 },
3164 // Actual Callbacks object
3165 self = {
3166 // Add a callback or a collection of callbacks to the list
3167 add: function() {
3168 if ( list ) {
3169 // First, we save the current length
3170 var start = list.length;
3171 (function add( args ) {
3172 jQuery.each( args, function( _, arg ) {
3173 var type = jQuery.type( arg );
3174 if ( type === "function" ) {
3175 if ( !options.unique || !self.has( arg ) ) {
3176 list.push( arg );
3177 }
3178 } else if ( arg && arg.length && type !== "string" ) {
3179 // Inspect recursively
3180 add( arg );
3181 }
3182 });
3183 })( arguments );
3184 // Do we need to add the callbacks to the
3185 // current firing batch?
3186 if ( firing ) {
3187 firingLength = list.length;
3188 // With memory, if we're not firing then
3189 // we should call right away
3190 } else if ( memory ) {
3191 firingStart = start;
3192 fire( memory );
3193 }
3194 }
3195 return this;
3196 },
3197 // Remove a callback from the list
3198 remove: function() {
3199 if ( list ) {
3200 jQuery.each( arguments, function( _, arg ) {
3201 var index;
3202 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3203 list.splice( index, 1 );
3204 // Handle firing indexes
3205 if ( firing ) {
3206 if ( index <= firingLength ) {
3207 firingLength--;
3208 }
3209 if ( index <= firingIndex ) {
3210 firingIndex--;
3211 }
3212 }
3213 }
3214 });
3215 }
3216 return this;
3217 },
3218 // Check if a given callback is in the list.
3219 // If no argument is given, return whether or not list has callbacks attached.
3220 has: function( fn ) {
3221 return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3222 },
3223 // Remove all callbacks from the list
3224 empty: function() {
3225 list = [];
3226 firingLength = 0;
3227 return this;
3228 },
3229 // Have the list do nothing anymore
3230 disable: function() {
3231 list = stack = memory = undefined;
3232 return this;
3233 },
3234 // Is it disabled?
3235 disabled: function() {
3236 return !list;
3237 },
3238 // Lock the list in its current state
3239 lock: function() {
3240 stack = undefined;
3241 if ( !memory ) {
3242 self.disable();
3243 }
3244 return this;
3245 },
3246 // Is it locked?
3247 locked: function() {
3248 return !stack;
3249 },
3250 // Call all callbacks with the given context and arguments
3251 fireWith: function( context, args ) {
3252 if ( list && ( !fired || stack ) ) {
3253 args = args || [];
3254 args = [ context, args.slice ? args.slice() : args ];
3255 if ( firing ) {
3256 stack.push( args );
3257 } else {
3258 fire( args );
3259 }
3260 }
3261 return this;
3262 },
3263 // Call all the callbacks with the given arguments
3264 fire: function() {
3265 self.fireWith( this, arguments );
3266 return this;
3267 },
3268 // To know if the callbacks have already been called at least once
3269 fired: function() {
3270 return !!fired;
3271 }
3272 };
3273
3274 return self;
3275 };
3276
3277
3278 jQuery.extend({
3279
3280 Deferred: function( func ) {
3281 var tuples = [
3282 // action, add listener, listener list, final state
3283 [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3284 [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3285 [ "notify", "progress", jQuery.Callbacks("memory") ]
3286 ],
3287 state = "pending",
3288 promise = {
3289 state: function() {
3290 return state;
3291 },
3292 always: function() {
3293 deferred.done( arguments ).fail( arguments );
3294 return this;
3295 },
3296 then: function( /* fnDone, fnFail, fnProgress */ ) {
3297 var fns = arguments;
3298 return jQuery.Deferred(function( newDefer ) {
3299 jQuery.each( tuples, function( i, tuple ) {
3300 var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3301 // deferred[ done | fail | progress ] for forwarding actions to newDefer
3302 deferred[ tuple[1] ](function() {
3303 var returned = fn && fn.apply( this, arguments );
3304 if ( returned && jQuery.isFunction( returned.promise ) ) {
3305 returned.promise()
3306 .done( newDefer.resolve )
3307 .fail( newDefer.reject )
3308 .progress( newDefer.notify );
3309 } else {
3310 newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3311 }
3312 });
3313 });
3314 fns = null;
3315 }).promise();
3316 },
3317 // Get a promise for this deferred
3318 // If obj is provided, the promise aspect is added to the object
3319 promise: function( obj ) {
3320 return obj != null ? jQuery.extend( obj, promise ) : promise;
3321 }
3322 },
3323 deferred = {};
3324
3325 // Keep pipe for back-compat
3326 promise.pipe = promise.then;
3327
3328 // Add list-specific methods
3329 jQuery.each( tuples, function( i, tuple ) {
3330 var list = tuple[ 2 ],
3331 stateString = tuple[ 3 ];
3332
3333 // promise[ done | fail | progress ] = list.add
3334 promise[ tuple[1] ] = list.add;
3335
3336 // Handle state
3337 if ( stateString ) {
3338 list.add(function() {
3339 // state = [ resolved | rejected ]
3340 state = stateString;
3341
3342 // [ reject_list | resolve_list ].disable; progress_list.lock
3343 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3344 }
3345
3346 // deferred[ resolve | reject | notify ]
3347 deferred[ tuple[0] ] = function() {
3348 deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3349 return this;
3350 };
3351 deferred[ tuple[0] + "With" ] = list.fireWith;
3352 });
3353
3354 // Make the deferred a promise
3355 promise.promise( deferred );
3356
3357 // Call given func if any
3358 if ( func ) {
3359 func.call( deferred, deferred );
3360 }
3361
3362 // All done!
3363 return deferred;
3364 },
3365
3366 // Deferred helper
3367 when: function( subordinate /* , ..., subordinateN */ ) {
3368 var i = 0,
3369 resolveValues = slice.call( arguments ),
3370 length = resolveValues.length,
3371
3372 // the count of uncompleted subordinates
3373 remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3374
3375 // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
3376 deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3377
3378 // Update function for both resolve and progress values
3379 updateFunc = function( i, contexts, values ) {
3380 return function( value ) {
3381 contexts[ i ] = this;
3382 values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3383 if ( values === progressValues ) {
3384 deferred.notifyWith( contexts, values );
3385
3386 } else if ( !(--remaining) ) {
3387 deferred.resolveWith( contexts, values );
3388 }
3389 };
3390 },
3391
3392 progressValues, progressContexts, resolveContexts;
3393
3394 // add listeners to Deferred subordinates; treat others as resolved
3395 if ( length > 1 ) {
3396 progressValues = new Array( length );
3397 progressContexts = new Array( length );
3398 resolveContexts = new Array( length );
3399 for ( ; i < length; i++ ) {
3400 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3401 resolveValues[ i ].promise()
3402 .done( updateFunc( i, resolveContexts, resolveValues ) )
3403 .fail( deferred.reject )
3404 .progress( updateFunc( i, progressContexts, progressValues ) );
3405 } else {
3406 --remaining;
3407 }
3408 }
3409 }
3410
3411 // if we're not waiting on anything, resolve the master
3412 if ( !remaining ) {
3413 deferred.resolveWith( resolveContexts, resolveValues );
3414 }
3415
3416 return deferred.promise();
3417 }
3418 });
3419
3420
3421 // The deferred used on DOM ready
3422 var readyList;
3423
3424 jQuery.fn.ready = function( fn ) {
3425 // Add the callback
3426 jQuery.ready.promise().done( fn );
3427
3428 return this;
3429 };
3430
3431 jQuery.extend({
3432 // Is the DOM ready to be used? Set to true once it occurs.
3433 isReady: false,
3434
3435 // A counter to track how many items to wait for before
3436 // the ready event fires. See #6781
3437 readyWait: 1,
3438
3439 // Hold (or release) the ready event
3440 holdReady: function( hold ) {
3441 if ( hold ) {
3442 jQuery.readyWait++;
3443 } else {
3444 jQuery.ready( true );
3445 }
3446 },
3447
3448 // Handle when the DOM is ready
3449 ready: function( wait ) {
3450
3451 // Abort if there are pending holds or we're already ready
3452 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3453 return;
3454 }
3455
3456 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
3457 if ( !document.body ) {
3458 return setTimeout( jQuery.ready );
3459 }
3460
3461 // Remember that the DOM is ready
3462 jQuery.isReady = true;
3463
3464 // If a normal DOM Ready event fired, decrement, and wait if need be
3465 if ( wait !== true && --jQuery.readyWait > 0 ) {
3466 return;
3467 }
3468
3469 // If there are functions bound, to execute
3470 readyList.resolveWith( document, [ jQuery ] );
3471
3472 // Trigger any bound ready events
3473 if ( jQuery.fn.triggerHandler ) {
3474 jQuery( document ).triggerHandler( "ready" );
3475 jQuery( document ).off( "ready" );
3476 }
3477 }
3478 });
3479
3480 /**
3481 * Clean-up method for dom ready events
3482 */
3483 function detach() {
3484 if ( document.addEventListener ) {
3485 document.removeEventListener( "DOMContentLoaded", completed, false );
3486 window.removeEventListener( "load", completed, false );
3487
3488 } else {
3489 document.detachEvent( "onreadystatechange", completed );
3490 window.detachEvent( "onload", completed );
3491 }
3492 }
3493
3494 /**
3495 * The ready event handler and self cleanup method
3496 */
3497 function completed() {
3498 // readyState === "complete" is good enough for us to call the dom ready in oldIE
3499 if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
3500 detach();
3501 jQuery.ready();
3502 }
3503 }
3504
3505 jQuery.ready.promise = function( obj ) {
3506 if ( !readyList ) {
3507
3508 readyList = jQuery.Deferred();
3509
3510 // Catch cases where $(document).ready() is called after the browser event has already occurred.
3511 // we once tried to use readyState "interactive" here, but it caused issues like the one
3512 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
3513 if ( document.readyState === "complete" ) {
3514 // Handle it asynchronously to allow scripts the opportunity to delay ready
3515 setTimeout( jQuery.ready );
3516
3517 // Standards-based browsers support DOMContentLoaded
3518 } else if ( document.addEventListener ) {
3519 // Use the handy event callback
3520 document.addEventListener( "DOMContentLoaded", completed, false );
3521
3522 // A fallback to window.onload, that will always work
3523 window.addEventListener( "load", completed, false );
3524
3525 // If IE event model is used
3526 } else {
3527 // Ensure firing before onload, maybe late but safe also for iframes
3528 document.attachEvent( "onreadystatechange", completed );
3529
3530 // A fallback to window.onload, that will always work
3531 window.attachEvent( "onload", completed );
3532
3533 // If IE and not a frame
3534 // continually check to see if the document is ready
3535 var top = false;
3536
3537 try {
3538 top = window.frameElement == null && document.documentElement;
3539 } catch(e) {}
3540
3541 if ( top && top.doScroll ) {
3542 (function doScrollCheck() {
3543 if ( !jQuery.isReady ) {
3544
3545 try {
3546 // Use the trick by Diego Perini
3547 // http://javascript.nwbox.com/IEContentLoaded/
3548 top.doScroll("left");
3549 } catch(e) {
3550 return setTimeout( doScrollCheck, 50 );
3551 }
3552
3553 // detach all dom ready events
3554 detach();
3555
3556 // and execute any waiting functions
3557 jQuery.ready();
3558 }
3559 })();
3560 }
3561 }
3562 }
3563 return readyList.promise( obj );
3564 };
3565
3566
3567 var strundefined = typeof undefined;
3568
3569
3570
3571 // Support: IE<9
3572 // Iteration over object's inherited properties before its own
3573 var i;
3574 for ( i in jQuery( support ) ) {
3575 break;
3576 }
3577 support.ownLast = i !== "0";
3578
3579 // Note: most support tests are defined in their respective modules.
3580 // false until the test is run
3581 support.inlineBlockNeedsLayout = false;
3582
3583 // Execute ASAP in case we need to set body.style.zoom
3584 jQuery(function() {
3585 // Minified: var a,b,c,d
3586 var val, div, body, container;
3587
3588 body = document.getElementsByTagName( "body" )[ 0 ];
3589 if ( !body || !body.style ) {
3590 // Return for frameset docs that don't have a body
3591 return;
3592 }
3593
3594 // Setup
3595 div = document.createElement( "div" );
3596 container = document.createElement( "div" );
3597 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
3598 body.appendChild( container ).appendChild( div );
3599
3600 if ( typeof div.style.zoom !== strundefined ) {
3601 // Support: IE<8
3602 // Check if natively block-level elements act like inline-block
3603 // elements when setting their display to 'inline' and giving
3604 // them layout
3605 div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
3606
3607 support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
3608 if ( val ) {
3609 // Prevent IE 6 from affecting layout for positioned elements #11048
3610 // Prevent IE from shrinking the body in IE 7 mode #12869
3611 // Support: IE<8
3612 body.style.zoom = 1;
3613 }
3614 }
3615
3616 body.removeChild( container );
3617 });
3618
3619
3620
3621
3622 (function() {
3623 var div = document.createElement( "div" );
3624
3625 // Execute the test only if not already executed in another module.
3626 if (support.deleteExpando == null) {
3627 // Support: IE<9
3628 support.deleteExpando = true;
3629 try {
3630 delete div.test;
3631 } catch( e ) {
3632 support.deleteExpando = false;
3633 }
3634 }
3635
3636 // Null elements to avoid leaks in IE.
3637 div = null;
3638 })();
3639
3640
3641 /**
3642 * Determines whether an object can have data
3643 */
3644 jQuery.acceptData = function( elem ) {
3645 var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ],
3646 nodeType = +elem.nodeType || 1;
3647
3648 // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
3649 return nodeType !== 1 && nodeType !== 9 ?
3650 false :
3651
3652 // Nodes accept data unless otherwise specified; rejection can be conditional
3653 !noData || noData !== true && elem.getAttribute("classid") === noData;
3654 };
3655
3656
3657 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3658 rmultiDash = /([A-Z])/g;
3659
3660 function dataAttr( elem, key, data ) {
3661 // If nothing was found internally, try to fetch any
3662 // data from the HTML5 data-* attribute
3663 if ( data === undefined && elem.nodeType === 1 ) {
3664
3665 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3666
3667 data = elem.getAttribute( name );
3668
3669 if ( typeof data === "string" ) {
3670 try {
3671 data = data === "true" ? true :
3672 data === "false" ? false :
3673 data === "null" ? null :
3674 // Only convert to a number if it doesn't change the string
3675 +data + "" === data ? +data :
3676 rbrace.test( data ) ? jQuery.parseJSON( data ) :
3677 data;
3678 } catch( e ) {}
3679
3680 // Make sure we set the data so it isn't changed later
3681 jQuery.data( elem, key, data );
3682
3683 } else {
3684 data = undefined;
3685 }
3686 }
3687
3688 return data;
3689 }
3690
3691 // checks a cache object for emptiness
3692 function isEmptyDataObject( obj ) {
3693 var name;
3694 for ( name in obj ) {
3695
3696 // if the public data object is empty, the private is still empty
3697 if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
3698 continue;
3699 }
3700 if ( name !== "toJSON" ) {
3701 return false;
3702 }
3703 }
3704
3705 return true;
3706 }
3707
3708 function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
3709 if ( !jQuery.acceptData( elem ) ) {
3710 return;
3711 }
3712
3713 var ret, thisCache,
3714 internalKey = jQuery.expando,
3715
3716 // We have to handle DOM nodes and JS objects differently because IE6-7
3717 // can't GC object references properly across the DOM-JS boundary
3718 isNode = elem.nodeType,
3719
3720 // Only DOM nodes need the global jQuery cache; JS object data is
3721 // attached directly to the object so GC can occur automatically
3722 cache = isNode ? jQuery.cache : elem,
3723
3724 // Only defining an ID for JS objects if its cache already exists allows
3725 // the code to shortcut on the same path as a DOM node with no cache
3726 id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
3727
3728 // Avoid doing any more work than we need to when trying to get data on an
3729 // object that has no data at all
3730 if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
3731 return;
3732 }
3733
3734 if ( !id ) {
3735 // Only DOM nodes need a new unique ID for each element since their data
3736 // ends up in the global cache
3737 if ( isNode ) {
3738 id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
3739 } else {
3740 id = internalKey;
3741 }
3742 }
3743
3744 if ( !cache[ id ] ) {
3745 // Avoid exposing jQuery metadata on plain JS objects when the object
3746 // is serialized using JSON.stringify
3747 cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
3748 }
3749
3750 // An object can be passed to jQuery.data instead of a key/value pair; this gets
3751 // shallow copied over onto the existing cache
3752 if ( typeof name === "object" || typeof name === "function" ) {
3753 if ( pvt ) {
3754 cache[ id ] = jQuery.extend( cache[ id ], name );
3755 } else {
3756 cache[ id ].data = jQuery.extend( cache[ id ].data, name );
3757 }
3758 }
3759
3760 thisCache = cache[ id ];
3761
3762 // jQuery data() is stored in a separate object inside the object's internal data
3763 // cache in order to avoid key collisions between internal data and user-defined
3764 // data.
3765 if ( !pvt ) {
3766 if ( !thisCache.data ) {
3767 thisCache.data = {};
3768 }
3769
3770 thisCache = thisCache.data;
3771 }
3772
3773 if ( data !== undefined ) {
3774 thisCache[ jQuery.camelCase( name ) ] = data;
3775 }
3776
3777 // Check for both converted-to-camel and non-converted data property names
3778 // If a data property was specified
3779 if ( typeof name === "string" ) {
3780
3781 // First Try to find as-is property data
3782 ret = thisCache[ name ];
3783
3784 // Test for null|undefined property data
3785 if ( ret == null ) {
3786
3787 // Try to find the camelCased property
3788 ret = thisCache[ jQuery.camelCase( name ) ];
3789 }
3790 } else {
3791 ret = thisCache;
3792 }
3793
3794 return ret;
3795 }
3796
3797 function internalRemoveData( elem, name, pvt ) {
3798 if ( !jQuery.acceptData( elem ) ) {
3799 return;
3800 }
3801
3802 var thisCache, i,
3803 isNode = elem.nodeType,
3804
3805 // See jQuery.data for more information
3806 cache = isNode ? jQuery.cache : elem,
3807 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
3808
3809 // If there is already no cache entry for this object, there is no
3810 // purpose in continuing
3811 if ( !cache[ id ] ) {
3812 return;
3813 }
3814
3815 if ( name ) {
3816
3817 thisCache = pvt ? cache[ id ] : cache[ id ].data;
3818
3819 if ( thisCache ) {
3820
3821 // Support array or space separated string names for data keys
3822 if ( !jQuery.isArray( name ) ) {
3823
3824 // try the string as a key before any manipulation
3825 if ( name in thisCache ) {
3826 name = [ name ];
3827 } else {
3828
3829 // split the camel cased version by spaces unless a key with the spaces exists
3830 name = jQuery.camelCase( name );
3831 if ( name in thisCache ) {
3832 name = [ name ];
3833 } else {
3834 name = name.split(" ");
3835 }
3836 }
3837 } else {
3838 // If "name" is an array of keys...
3839 // When data is initially created, via ("key", "val") signature,
3840 // keys will be converted to camelCase.
3841 // Since there is no way to tell _how_ a key was added, remove
3842 // both plain key and camelCase key. #12786
3843 // This will only penalize the array argument path.
3844 name = name.concat( jQuery.map( name, jQuery.camelCase ) );
3845 }
3846
3847 i = name.length;
3848 while ( i-- ) {
3849 delete thisCache[ name[i] ];
3850 }
3851
3852 // If there is no data left in the cache, we want to continue
3853 // and let the cache object itself get destroyed
3854 if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
3855 return;
3856 }
3857 }
3858 }
3859
3860 // See jQuery.data for more information
3861 if ( !pvt ) {
3862 delete cache[ id ].data;
3863
3864 // Don't destroy the parent cache unless the internal data object
3865 // had been the only thing left in it
3866 if ( !isEmptyDataObject( cache[ id ] ) ) {
3867 return;
3868 }
3869 }
3870
3871 // Destroy the cache
3872 if ( isNode ) {
3873 jQuery.cleanData( [ elem ], true );
3874
3875 // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
3876 /* jshint eqeqeq: false */
3877 } else if ( support.deleteExpando || cache != cache.window ) {
3878 /* jshint eqeqeq: true */
3879 delete cache[ id ];
3880
3881 // When all else fails, null
3882 } else {
3883 cache[ id ] = null;
3884 }
3885 }
3886
3887 jQuery.extend({
3888 cache: {},
3889
3890 // The following elements (space-suffixed to avoid Object.prototype collisions)
3891 // throw uncatchable exceptions if you attempt to set expando properties
3892 noData: {
3893 "applet ": true,
3894 "embed ": true,
3895 // ...but Flash objects (which have this classid) *can* handle expandos
3896 "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
3897 },
3898
3899 hasData: function( elem ) {
3900 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
3901 return !!elem && !isEmptyDataObject( elem );
3902 },
3903
3904 data: function( elem, name, data ) {
3905 return internalData( elem, name, data );
3906 },
3907
3908 removeData: function( elem, name ) {
3909 return internalRemoveData( elem, name );
3910 },
3911
3912 // For internal use only.
3913 _data: function( elem, name, data ) {
3914 return internalData( elem, name, data, true );
3915 },
3916
3917 _removeData: function( elem, name ) {
3918 return internalRemoveData( elem, name, true );
3919 }
3920 });
3921
3922 jQuery.fn.extend({
3923 data: function( key, value ) {
3924 var i, name, data,
3925 elem = this[0],
3926 attrs = elem && elem.attributes;
3927
3928 // Special expections of .data basically thwart jQuery.access,
3929 // so implement the relevant behavior ourselves
3930
3931 // Gets all values
3932 if ( key === undefined ) {
3933 if ( this.length ) {
3934 data = jQuery.data( elem );
3935
3936 if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
3937 i = attrs.length;
3938 while ( i-- ) {
3939
3940 // Support: IE11+
3941 // The attrs elements can be null (#14894)
3942 if ( attrs[ i ] ) {
3943 name = attrs[ i ].name;
3944 if ( name.indexOf( "data-" ) === 0 ) {
3945 name = jQuery.camelCase( name.slice(5) );
3946 dataAttr( elem, name, data[ name ] );
3947 }
3948 }
3949 }
3950 jQuery._data( elem, "parsedAttrs", true );
3951 }
3952 }
3953
3954 return data;
3955 }
3956
3957 // Sets multiple values
3958 if ( typeof key === "object" ) {
3959 return this.each(function() {
3960 jQuery.data( this, key );
3961 });
3962 }
3963
3964 return arguments.length > 1 ?
3965
3966 // Sets one value
3967 this.each(function() {
3968 jQuery.data( this, key, value );
3969 }) :
3970
3971 // Gets one value
3972 // Try to fetch any internally stored data first
3973 elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
3974 },
3975
3976 removeData: function( key ) {
3977 return this.each(function() {
3978 jQuery.removeData( this, key );
3979 });
3980 }
3981 });
3982
3983
3984 jQuery.extend({
3985 queue: function( elem, type, data ) {
3986 var queue;
3987
3988 if ( elem ) {
3989 type = ( type || "fx" ) + "queue";
3990 queue = jQuery._data( elem, type );
3991
3992 // Speed up dequeue by getting out quickly if this is just a lookup
3993 if ( data ) {
3994 if ( !queue || jQuery.isArray(data) ) {
3995 queue = jQuery._data( elem, type, jQuery.makeArray(data) );
3996 } else {
3997 queue.push( data );
3998 }
3999 }
4000 return queue || [];
4001 }
4002 },
4003
4004 dequeue: function( elem, type ) {
4005 type = type || "fx";
4006
4007 var queue = jQuery.queue( elem, type ),
4008 startLength = queue.length,
4009 fn = queue.shift(),
4010 hooks = jQuery._queueHooks( elem, type ),
4011 next = function() {
4012 jQuery.dequeue( elem, type );
4013 };
4014
4015 // If the fx queue is dequeued, always remove the progress sentinel
4016 if ( fn === "inprogress" ) {
4017 fn = queue.shift();
4018 startLength--;
4019 }
4020
4021 if ( fn ) {
4022
4023 // Add a progress sentinel to prevent the fx queue from being
4024 // automatically dequeued
4025 if ( type === "fx" ) {
4026 queue.unshift( "inprogress" );
4027 }
4028
4029 // clear up the last queue stop function
4030 delete hooks.stop;
4031 fn.call( elem, next, hooks );
4032 }
4033
4034 if ( !startLength && hooks ) {
4035 hooks.empty.fire();
4036 }
4037 },
4038
4039 // not intended for public consumption - generates a queueHooks object, or returns the current one
4040 _queueHooks: function( elem, type ) {
4041 var key = type + "queueHooks";
4042 return jQuery._data( elem, key ) || jQuery._data( elem, key, {
4043 empty: jQuery.Callbacks("once memory").add(function() {
4044 jQuery._removeData( elem, type + "queue" );
4045 jQuery._removeData( elem, key );
4046 })
4047 });
4048 }
4049 });
4050
4051 jQuery.fn.extend({
4052 queue: function( type, data ) {
4053 var setter = 2;
4054
4055 if ( typeof type !== "string" ) {
4056 data = type;
4057 type = "fx";
4058 setter--;
4059 }
4060
4061 if ( arguments.length < setter ) {
4062 return jQuery.queue( this[0], type );
4063 }
4064
4065 return data === undefined ?
4066 this :
4067 this.each(function() {
4068 var queue = jQuery.queue( this, type, data );
4069
4070 // ensure a hooks for this queue
4071 jQuery._queueHooks( this, type );
4072
4073 if ( type === "fx" && queue[0] !== "inprogress" ) {
4074 jQuery.dequeue( this, type );
4075 }
4076 });
4077 },
4078 dequeue: function( type ) {
4079 return this.each(function() {
4080 jQuery.dequeue( this, type );
4081 });
4082 },
4083 clearQueue: function( type ) {
4084 return this.queue( type || "fx", [] );
4085 },
4086 // Get a promise resolved when queues of a certain type
4087 // are emptied (fx is the type by default)
4088 promise: function( type, obj ) {
4089 var tmp,
4090 count = 1,
4091 defer = jQuery.Deferred(),
4092 elements = this,
4093 i = this.length,
4094 resolve = function() {
4095 if ( !( --count ) ) {
4096 defer.resolveWith( elements, [ elements ] );
4097 }
4098 };
4099
4100 if ( typeof type !== "string" ) {
4101 obj = type;
4102 type = undefined;
4103 }
4104 type = type || "fx";
4105
4106 while ( i-- ) {
4107 tmp = jQuery._data( elements[ i ], type + "queueHooks" );
4108 if ( tmp && tmp.empty ) {
4109 count++;
4110 tmp.empty.add( resolve );
4111 }
4112 }
4113 resolve();
4114 return defer.promise( obj );
4115 }
4116 });
4117 var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
4118
4119 var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4120
4121 var isHidden = function( elem, el ) {
4122 // isHidden might be called from jQuery#filter function;
4123 // in that case, element will be second argument
4124 elem = el || elem;
4125 return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
4126 };
4127
4128
4129
4130 // Multifunctional method to get and set values of a collection
4131 // The value/s can optionally be executed if it's a function
4132 var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4133 var i = 0,
4134 length = elems.length,
4135 bulk = key == null;
4136
4137 // Sets many values
4138 if ( jQuery.type( key ) === "object" ) {
4139 chainable = true;
4140 for ( i in key ) {
4141 jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
4142 }
4143
4144 // Sets one value
4145 } else if ( value !== undefined ) {
4146 chainable = true;
4147
4148 if ( !jQuery.isFunction( value ) ) {
4149 raw = true;
4150 }
4151
4152 if ( bulk ) {
4153 // Bulk operations run against the entire set
4154 if ( raw ) {
4155 fn.call( elems, value );
4156 fn = null;
4157
4158 // ...except when executing function values
4159 } else {
4160 bulk = fn;
4161 fn = function( elem, key, value ) {
4162 return bulk.call( jQuery( elem ), value );
4163 };
4164 }
4165 }
4166
4167 if ( fn ) {
4168 for ( ; i < length; i++ ) {
4169 fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
4170 }
4171 }
4172 }
4173
4174 return chainable ?
4175 elems :
4176
4177 // Gets
4178 bulk ?
4179 fn.call( elems ) :
4180 length ? fn( elems[0], key ) : emptyGet;
4181 };
4182 var rcheckableType = (/^(?:checkbox|radio)$/i);
4183
4184
4185
4186 (function() {
4187 // Minified: var a,b,c
4188 var input = document.createElement( "input" ),
4189 div = document.createElement( "div" ),
4190 fragment = document.createDocumentFragment();
4191
4192 // Setup
4193 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
4194
4195 // IE strips leading whitespace when .innerHTML is used
4196 support.leadingWhitespace = div.firstChild.nodeType === 3;
4197
4198 // Make sure that tbody elements aren't automatically inserted
4199 // IE will insert them into empty tables
4200 support.tbody = !div.getElementsByTagName( "tbody" ).length;
4201
4202 // Make sure that link elements get serialized correctly by innerHTML
4203 // This requires a wrapper element in IE
4204 support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
4205
4206 // Makes sure cloning an html5 element does not cause problems
4207 // Where outerHTML is undefined, this still works
4208 support.html5Clone =
4209 document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
4210
4211 // Check if a disconnected checkbox will retain its checked
4212 // value of true after appended to the DOM (IE6/7)
4213 input.type = "checkbox";
4214 input.checked = true;
4215 fragment.appendChild( input );
4216 support.appendChecked = input.checked;
4217
4218 // Make sure textarea (and checkbox) defaultValue is properly cloned
4219 // Support: IE6-IE11+
4220 div.innerHTML = "<textarea>x</textarea>";
4221 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4222
4223 // #11217 - WebKit loses check when the name is after the checked attribute
4224 fragment.appendChild( div );
4225 div.innerHTML = "<input type='radio' checked='checked' name='t'/>";
4226
4227 // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4228 // old WebKit doesn't clone checked state correctly in fragments
4229 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4230
4231 // Support: IE<9
4232 // Opera does not clone events (and typeof div.attachEvent === undefined).
4233 // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
4234 support.noCloneEvent = true;
4235 if ( div.attachEvent ) {
4236 div.attachEvent( "onclick", function() {
4237 support.noCloneEvent = false;
4238 });
4239
4240 div.cloneNode( true ).click();
4241 }
4242
4243 // Execute the test only if not already executed in another module.
4244 if (support.deleteExpando == null) {
4245 // Support: IE<9
4246 support.deleteExpando = true;
4247 try {
4248 delete div.test;
4249 } catch( e ) {
4250 support.deleteExpando = false;
4251 }
4252 }
4253 })();
4254
4255
4256 (function() {
4257 var i, eventName,
4258 div = document.createElement( "div" );
4259
4260 // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
4261 for ( i in { submit: true, change: true, focusin: true }) {
4262 eventName = "on" + i;
4263
4264 if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
4265 // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
4266 div.setAttribute( eventName, "t" );
4267 support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
4268 }
4269 }
4270
4271 // Null elements to avoid leaks in IE.
4272 div = null;
4273 })();
4274
4275
4276 var rformElems = /^(?:input|select|textarea)$/i,
4277 rkeyEvent = /^key/,
4278 rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
4279 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4280 rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
4281
4282 function returnTrue() {
4283 return true;
4284 }
4285
4286 function returnFalse() {
4287 return false;
4288 }
4289
4290 function safeActiveElement() {
4291 try {
4292 return document.activeElement;
4293 } catch ( err ) { }
4294 }
4295
4296 /*
4297 * Helper functions for managing events -- not part of the public interface.
4298 * Props to Dean Edwards' addEvent library for many of the ideas.
4299 */
4300 jQuery.event = {
4301
4302 global: {},
4303
4304 add: function( elem, types, handler, data, selector ) {
4305 var tmp, events, t, handleObjIn,
4306 special, eventHandle, handleObj,
4307 handlers, type, namespaces, origType,
4308 elemData = jQuery._data( elem );
4309
4310 // Don't attach events to noData or text/comment nodes (but allow plain objects)
4311 if ( !elemData ) {
4312 return;
4313 }
4314
4315 // Caller can pass in an object of custom data in lieu of the handler
4316 if ( handler.handler ) {
4317 handleObjIn = handler;
4318 handler = handleObjIn.handler;
4319 selector = handleObjIn.selector;
4320 }
4321
4322 // Make sure that the handler has a unique ID, used to find/remove it later
4323 if ( !handler.guid ) {
4324 handler.guid = jQuery.guid++;
4325 }
4326
4327 // Init the element's event structure and main handler, if this is the first
4328 if ( !(events = elemData.events) ) {
4329 events = elemData.events = {};
4330 }
4331 if ( !(eventHandle = elemData.handle) ) {
4332 eventHandle = elemData.handle = function( e ) {
4333 // Discard the second event of a jQuery.event.trigger() and
4334 // when an event is called after a page has unloaded
4335 return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
4336 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4337 undefined;
4338 };
4339 // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
4340 eventHandle.elem = elem;
4341 }
4342
4343 // Handle multiple events separated by a space
4344 types = ( types || "" ).match( rnotwhite ) || [ "" ];
4345 t = types.length;
4346 while ( t-- ) {
4347 tmp = rtypenamespace.exec( types[t] ) || [];
4348 type = origType = tmp[1];
4349 namespaces = ( tmp[2] || "" ).split( "." ).sort();
4350
4351 // There *must* be a type, no attaching namespace-only handlers
4352 if ( !type ) {
4353 continue;
4354 }
4355
4356 // If event changes its type, use the special event handlers for the changed type
4357 special = jQuery.event.special[ type ] || {};
4358
4359 // If selector defined, determine special event api type, otherwise given type
4360 type = ( selector ? special.delegateType : special.bindType ) || type;
4361
4362 // Update special based on newly reset type
4363 special = jQuery.event.special[ type ] || {};
4364
4365 // handleObj is passed to all event handlers
4366 handleObj = jQuery.extend({
4367 type: type,
4368 origType: origType,
4369 data: data,
4370 handler: handler,
4371 guid: handler.guid,
4372 selector: selector,
4373 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4374 namespace: namespaces.join(".")
4375 }, handleObjIn );
4376
4377 // Init the event handler queue if we're the first
4378 if ( !(handlers = events[ type ]) ) {
4379 handlers = events[ type ] = [];
4380 handlers.delegateCount = 0;
4381
4382 // Only use addEventListener/attachEvent if the special events handler returns false
4383 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4384 // Bind the global event handler to the element
4385 if ( elem.addEventListener ) {
4386 elem.addEventListener( type, eventHandle, false );
4387
4388 } else if ( elem.attachEvent ) {
4389 elem.attachEvent( "on" + type, eventHandle );
4390 }
4391 }
4392 }
4393
4394 if ( special.add ) {
4395 special.add.call( elem, handleObj );
4396
4397 if ( !handleObj.handler.guid ) {
4398 handleObj.handler.guid = handler.guid;
4399 }
4400 }
4401
4402 // Add to the element's handler list, delegates in front
4403 if ( selector ) {
4404 handlers.splice( handlers.delegateCount++, 0, handleObj );
4405 } else {
4406 handlers.push( handleObj );
4407 }
4408
4409 // Keep track of which events have ever been used, for event optimization
4410 jQuery.event.global[ type ] = true;
4411 }
4412
4413 // Nullify elem to prevent memory leaks in IE
4414 elem = null;
4415 },
4416
4417 // Detach an event or set of events from an element
4418 remove: function( elem, types, handler, selector, mappedTypes ) {
4419 var j, handleObj, tmp,
4420 origCount, t, events,
4421 special, handlers, type,
4422 namespaces, origType,
4423 elemData = jQuery.hasData( elem ) && jQuery._data( elem );
4424
4425 if ( !elemData || !(events = elemData.events) ) {
4426 return;
4427 }
4428
4429 // Once for each type.namespace in types; type may be omitted
4430 types = ( types || "" ).match( rnotwhite ) || [ "" ];
4431 t = types.length;
4432 while ( t-- ) {
4433 tmp = rtypenamespace.exec( types[t] ) || [];
4434 type = origType = tmp[1];
4435 namespaces = ( tmp[2] || "" ).split( "." ).sort();
4436
4437 // Unbind all events (on this namespace, if provided) for the element
4438 if ( !type ) {
4439 for ( type in events ) {
4440 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4441 }
4442 continue;
4443 }
4444
4445 special = jQuery.event.special[ type ] || {};
4446 type = ( selector ? special.delegateType : special.bindType ) || type;
4447 handlers = events[ type ] || [];
4448 tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
4449
4450 // Remove matching events
4451 origCount = j = handlers.length;
4452 while ( j-- ) {
4453 handleObj = handlers[ j ];
4454
4455 if ( ( mappedTypes || origType === handleObj.origType ) &&
4456 ( !handler || handler.guid === handleObj.guid ) &&
4457 ( !tmp || tmp.test( handleObj.namespace ) ) &&
4458 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
4459 handlers.splice( j, 1 );
4460
4461 if ( handleObj.selector ) {
4462 handlers.delegateCount--;
4463 }
4464 if ( special.remove ) {
4465 special.remove.call( elem, handleObj );
4466 }
4467 }
4468 }
4469
4470 // Remove generic event handler if we removed something and no more handlers exist
4471 // (avoids potential for endless recursion during removal of special event handlers)
4472 if ( origCount && !handlers.length ) {
4473 if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4474 jQuery.removeEvent( elem, type, elemData.handle );
4475 }
4476
4477 delete events[ type ];
4478 }
4479 }
4480
4481 // Remove the expando if it's no longer used
4482 if ( jQuery.isEmptyObject( events ) ) {
4483 delete elemData.handle;
4484
4485 // removeData also checks for emptiness and clears the expando if empty
4486 // so use it instead of delete
4487 jQuery._removeData( elem, "events" );
4488 }
4489 },
4490
4491 trigger: function( event, data, elem, onlyHandlers ) {
4492 var handle, ontype, cur,
4493 bubbleType, special, tmp, i,
4494 eventPath = [ elem || document ],
4495 type = hasOwn.call( event, "type" ) ? event.type : event,
4496 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
4497
4498 cur = tmp = elem = elem || document;
4499
4500 // Don't do events on text and comment nodes
4501 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4502 return;
4503 }
4504
4505 // focus/blur morphs to focusin/out; ensure we're not firing them right now
4506 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
4507 return;
4508 }
4509
4510 if ( type.indexOf(".") >= 0 ) {
4511 // Namespaced trigger; create a regexp to match event type in handle()
4512 namespaces = type.split(".");
4513 type = namespaces.shift();
4514 namespaces.sort();
4515 }
4516 ontype = type.indexOf(":") < 0 && "on" + type;
4517
4518 // Caller can pass in a jQuery.Event object, Object, or just an event type string
4519 event = event[ jQuery.expando ] ?
4520 event :
4521 new jQuery.Event( type, typeof event === "object" && event );
4522
4523 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4524 event.isTrigger = onlyHandlers ? 2 : 3;
4525 event.namespace = namespaces.join(".");
4526 event.namespace_re = event.namespace ?
4527 new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
4528 null;
4529
4530 // Clean up the event in case it is being reused
4531 event.result = undefined;
4532 if ( !event.target ) {
4533 event.target = elem;
4534 }
4535
4536 // Clone any incoming data and prepend the event, creating the handler arg list
4537 data = data == null ?
4538 [ event ] :
4539 jQuery.makeArray( data, [ event ] );
4540
4541 // Allow special events to draw outside the lines
4542 special = jQuery.event.special[ type ] || {};
4543 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
4544 return;
4545 }
4546
4547 // Determine event propagation path in advance, per W3C events spec (#9951)
4548 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4549 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
4550
4551 bubbleType = special.delegateType || type;
4552 if ( !rfocusMorph.test( bubbleType + type ) ) {
4553 cur = cur.parentNode;
4554 }
4555 for ( ; cur; cur = cur.parentNode ) {
4556 eventPath.push( cur );
4557 tmp = cur;
4558 }
4559
4560 // Only add window if we got to document (e.g., not plain obj or detached DOM)
4561 if ( tmp === (elem.ownerDocument || document) ) {
4562 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
4563 }
4564 }
4565
4566 // Fire handlers on the event path
4567 i = 0;
4568 while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
4569
4570 event.type = i > 1 ?
4571 bubbleType :
4572 special.bindType || type;
4573
4574 // jQuery handler
4575 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
4576 if ( handle ) {
4577 handle.apply( cur, data );
4578 }
4579
4580 // Native handler
4581 handle = ontype && cur[ ontype ];
4582 if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
4583 event.result = handle.apply( cur, data );
4584 if ( event.result === false ) {
4585 event.preventDefault();
4586 }
4587 }
4588 }
4589 event.type = type;
4590
4591 // If nobody prevented the default action, do it now
4592 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
4593
4594 if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
4595 jQuery.acceptData( elem ) ) {
4596
4597 // Call a native DOM method on the target with the same name name as the event.
4598 // Can't use an .isFunction() check here because IE6/7 fails that test.
4599 // Don't do default actions on window, that's where global variables be (#6170)
4600 if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
4601
4602 // Don't re-trigger an onFOO event when we call its FOO() method
4603 tmp = elem[ ontype ];
4604
4605 if ( tmp ) {
4606 elem[ ontype ] = null;
4607 }
4608
4609 // Prevent re-triggering of the same event, since we already bubbled it above
4610 jQuery.event.triggered = type;
4611 try {
4612 elem[ type ]();
4613 } catch ( e ) {
4614 // IE<9 dies on focus/blur to hidden element (#1486,#12518)
4615 // only reproducible on winXP IE8 native, not IE9 in IE8 mode
4616 }
4617 jQuery.event.triggered = undefined;
4618
4619 if ( tmp ) {
4620 elem[ ontype ] = tmp;
4621 }
4622 }
4623 }
4624 }
4625
4626 return event.result;
4627 },
4628
4629 dispatch: function( event ) {
4630
4631 // Make a writable jQuery.Event from the native event object
4632 event = jQuery.event.fix( event );
4633
4634 var i, ret, handleObj, matched, j,
4635 handlerQueue = [],
4636 args = slice.call( arguments ),
4637 handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
4638 special = jQuery.event.special[ event.type ] || {};
4639
4640 // Use the fix-ed jQuery.Event rather than the (read-only) native event
4641 args[0] = event;
4642 event.delegateTarget = this;
4643
4644 // Call the preDispatch hook for the mapped type, and let it bail if desired
4645 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4646 return;
4647 }
4648
4649 // Determine handlers
4650 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4651
4652 // Run delegates first; they may want to stop propagation beneath us
4653 i = 0;
4654 while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
4655 event.currentTarget = matched.elem;
4656
4657 j = 0;
4658 while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
4659
4660 // Triggered event must either 1) have no namespace, or
4661 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
4662 if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
4663
4664 event.handleObj = handleObj;
4665 event.data = handleObj.data;
4666
4667 ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
4668 .apply( matched.elem, args );
4669
4670 if ( ret !== undefined ) {
4671 if ( (event.result = ret) === false ) {
4672 event.preventDefault();
4673 event.stopPropagation();
4674 }
4675 }
4676 }
4677 }
4678 }
4679
4680 // Call the postDispatch hook for the mapped type
4681 if ( special.postDispatch ) {
4682 special.postDispatch.call( this, event );
4683 }
4684
4685 return event.result;
4686 },
4687
4688 handlers: function( event, handlers ) {
4689 var sel, handleObj, matches, i,
4690 handlerQueue = [],
4691 delegateCount = handlers.delegateCount,
4692 cur = event.target;
4693
4694 // Find delegate handlers
4695 // Black-hole SVG <use> instance trees (#13180)
4696 // Avoid non-left-click bubbling in Firefox (#3861)
4697 if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
4698
4699 /* jshint eqeqeq: false */
4700 for ( ; cur != this; cur = cur.parentNode || this ) {
4701 /* jshint eqeqeq: true */
4702
4703 // Don't check non-elements (#13208)
4704 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4705 if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
4706 matches = [];
4707 for ( i = 0; i < delegateCount; i++ ) {
4708 handleObj = handlers[ i ];
4709
4710 // Don't conflict with Object.prototype properties (#13203)
4711 sel = handleObj.selector + " ";
4712
4713 if ( matches[ sel ] === undefined ) {
4714 matches[ sel ] = handleObj.needsContext ?
4715 jQuery( sel, this ).index( cur ) >= 0 :
4716 jQuery.find( sel, this, null, [ cur ] ).length;
4717 }
4718 if ( matches[ sel ] ) {
4719 matches.push( handleObj );
4720 }
4721 }
4722 if ( matches.length ) {
4723 handlerQueue.push({ elem: cur, handlers: matches });
4724 }
4725 }
4726 }
4727 }
4728
4729 // Add the remaining (directly-bound) handlers
4730 if ( delegateCount < handlers.length ) {
4731 handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
4732 }
4733
4734 return handlerQueue;
4735 },
4736
4737 fix: function( event ) {
4738 if ( event[ jQuery.expando ] ) {
4739 return event;
4740 }
4741
4742 // Create a writable copy of the event object and normalize some properties
4743 var i, prop, copy,
4744 type = event.type,
4745 originalEvent = event,
4746 fixHook = this.fixHooks[ type ];
4747
4748 if ( !fixHook ) {
4749 this.fixHooks[ type ] = fixHook =
4750 rmouseEvent.test( type ) ? this.mouseHooks :
4751 rkeyEvent.test( type ) ? this.keyHooks :
4752 {};
4753 }
4754 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4755
4756 event = new jQuery.Event( originalEvent );
4757
4758 i = copy.length;
4759 while ( i-- ) {
4760 prop = copy[ i ];
4761 event[ prop ] = originalEvent[ prop ];
4762 }
4763
4764 // Support: IE<9
4765 // Fix target property (#1925)
4766 if ( !event.target ) {
4767 event.target = originalEvent.srcElement || document;
4768 }
4769
4770 // Support: Chrome 23+, Safari?
4771 // Target should not be a text node (#504, #13143)
4772 if ( event.target.nodeType === 3 ) {
4773 event.target = event.target.parentNode;
4774 }
4775
4776 // Support: IE<9
4777 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
4778 event.metaKey = !!event.metaKey;
4779
4780 return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4781 },
4782
4783 // Includes some event props shared by KeyEvent and MouseEvent
4784 props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
4785
4786 fixHooks: {},
4787
4788 keyHooks: {
4789 props: "char charCode key keyCode".split(" "),
4790 filter: function( event, original ) {
4791
4792 // Add which for key events
4793 if ( event.which == null ) {
4794 event.which = original.charCode != null ? original.charCode : original.keyCode;
4795 }
4796
4797 return event;
4798 }
4799 },
4800
4801 mouseHooks: {
4802 props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
4803 filter: function( event, original ) {
4804 var body, eventDoc, doc,
4805 button = original.button,
4806 fromElement = original.fromElement;
4807
4808 // Calculate pageX/Y if missing and clientX/Y available
4809 if ( event.pageX == null && original.clientX != null ) {
4810 eventDoc = event.target.ownerDocument || document;
4811 doc = eventDoc.documentElement;
4812 body = eventDoc.body;
4813
4814 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4815 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
4816 }
4817
4818 // Add relatedTarget, if necessary
4819 if ( !event.relatedTarget && fromElement ) {
4820 event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
4821 }
4822
4823 // Add which for click: 1 === left; 2 === middle; 3 === right
4824 // Note: button is not normalized, so don't use it
4825 if ( !event.which && button !== undefined ) {
4826 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4827 }
4828
4829 return event;
4830 }
4831 },
4832
4833 special: {
4834 load: {
4835 // Prevent triggered image.load events from bubbling to window.load
4836 noBubble: true
4837 },
4838 focus: {
4839 // Fire native event if possible so blur/focus sequence is correct
4840 trigger: function() {
4841 if ( this !== safeActiveElement() && this.focus ) {
4842 try {
4843 this.focus();
4844 return false;
4845 } catch ( e ) {
4846 // Support: IE<9
4847 // If we error on focus to hidden element (#1486, #12518),
4848 // let .trigger() run the handlers
4849 }
4850 }
4851 },
4852 delegateType: "focusin"
4853 },
4854 blur: {
4855 trigger: function() {
4856 if ( this === safeActiveElement() && this.blur ) {
4857 this.blur();
4858 return false;
4859 }
4860 },
4861 delegateType: "focusout"
4862 },
4863 click: {
4864 // For checkbox, fire native event so checked state will be right
4865 trigger: function() {
4866 if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
4867 this.click();
4868 return false;
4869 }
4870 },
4871
4872 // For cross-browser consistency, don't fire native .click() on links
4873 _default: function( event ) {
4874 return jQuery.nodeName( event.target, "a" );
4875 }
4876 },
4877
4878 beforeunload: {
4879 postDispatch: function( event ) {
4880
4881 // Support: Firefox 20+
4882 // Firefox doesn't alert if the returnValue field is not set.
4883 if ( event.result !== undefined && event.originalEvent ) {
4884 event.originalEvent.returnValue = event.result;
4885 }
4886 }
4887 }
4888 },
4889
4890 simulate: function( type, elem, event, bubble ) {
4891 // Piggyback on a donor event to simulate a different one.
4892 // Fake originalEvent to avoid donor's stopPropagation, but if the
4893 // simulated event prevents default then we do the same on the donor.
4894 var e = jQuery.extend(
4895 new jQuery.Event(),
4896 event,
4897 {
4898 type: type,
4899 isSimulated: true,
4900 originalEvent: {}
4901 }
4902 );
4903 if ( bubble ) {
4904 jQuery.event.trigger( e, null, elem );
4905 } else {
4906 jQuery.event.dispatch.call( elem, e );
4907 }
4908 if ( e.isDefaultPrevented() ) {
4909 event.preventDefault();
4910 }
4911 }
4912 };
4913
4914 jQuery.removeEvent = document.removeEventListener ?
4915 function( elem, type, handle ) {
4916 if ( elem.removeEventListener ) {
4917 elem.removeEventListener( type, handle, false );
4918 }
4919 } :
4920 function( elem, type, handle ) {
4921 var name = "on" + type;
4922
4923 if ( elem.detachEvent ) {
4924
4925 // #8545, #7054, preventing memory leaks for custom events in IE6-8
4926 // detachEvent needed property on element, by name of that event, to properly expose it to GC
4927 if ( typeof elem[ name ] === strundefined ) {
4928 elem[ name ] = null;
4929 }
4930
4931 elem.detachEvent( name, handle );
4932 }
4933 };
4934
4935 jQuery.Event = function( src, props ) {
4936 // Allow instantiation without the 'new' keyword
4937 if ( !(this instanceof jQuery.Event) ) {
4938 return new jQuery.Event( src, props );
4939 }
4940
4941 // Event object
4942 if ( src && src.type ) {
4943 this.originalEvent = src;
4944 this.type = src.type;
4945
4946 // Events bubbling up the document may have been marked as prevented
4947 // by a handler lower down the tree; reflect the correct value.
4948 this.isDefaultPrevented = src.defaultPrevented ||
4949 src.defaultPrevented === undefined &&
4950 // Support: IE < 9, Android < 4.0
4951 src.returnValue === false ?
4952 returnTrue :
4953 returnFalse;
4954
4955 // Event type
4956 } else {
4957 this.type = src;
4958 }
4959
4960 // Put explicitly provided properties onto the event object
4961 if ( props ) {
4962 jQuery.extend( this, props );
4963 }
4964
4965 // Create a timestamp if incoming event doesn't have one
4966 this.timeStamp = src && src.timeStamp || jQuery.now();
4967
4968 // Mark it as fixed
4969 this[ jQuery.expando ] = true;
4970 };
4971
4972 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
4973 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
4974 jQuery.Event.prototype = {
4975 isDefaultPrevented: returnFalse,
4976 isPropagationStopped: returnFalse,
4977 isImmediatePropagationStopped: returnFalse,
4978
4979 preventDefault: function() {
4980 var e = this.originalEvent;
4981
4982 this.isDefaultPrevented = returnTrue;
4983 if ( !e ) {
4984 return;
4985 }
4986
4987 // If preventDefault exists, run it on the original event
4988 if ( e.preventDefault ) {
4989 e.preventDefault();
4990
4991 // Support: IE
4992 // Otherwise set the returnValue property of the original event to false
4993 } else {
4994 e.returnValue = false;
4995 }
4996 },
4997 stopPropagation: function() {
4998 var e = this.originalEvent;
4999
5000 this.isPropagationStopped = returnTrue;
5001 if ( !e ) {
5002 return;
5003 }
5004 // If stopPropagation exists, run it on the original event
5005 if ( e.stopPropagation ) {
5006 e.stopPropagation();
5007 }
5008
5009 // Support: IE
5010 // Set the cancelBubble property of the original event to true
5011 e.cancelBubble = true;
5012 },
5013 stopImmediatePropagation: function() {
5014 var e = this.originalEvent;
5015
5016 this.isImmediatePropagationStopped = returnTrue;
5017
5018 if ( e && e.stopImmediatePropagation ) {
5019 e.stopImmediatePropagation();
5020 }
5021
5022 this.stopPropagation();
5023 }
5024 };
5025
5026 // Create mouseenter/leave events using mouseover/out and event-time checks
5027 jQuery.each({
5028 mouseenter: "mouseover",
5029 mouseleave: "mouseout",
5030 pointerenter: "pointerover",
5031 pointerleave: "pointerout"
5032 }, function( orig, fix ) {
5033 jQuery.event.special[ orig ] = {
5034 delegateType: fix,
5035 bindType: fix,
5036
5037 handle: function( event ) {
5038 var ret,
5039 target = this,
5040 related = event.relatedTarget,
5041 handleObj = event.handleObj;
5042
5043 // For mousenter/leave call the handler if related is outside the target.
5044 // NB: No relatedTarget if the mouse left/entered the browser window
5045 if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
5046 event.type = handleObj.origType;
5047 ret = handleObj.handler.apply( this, arguments );
5048 event.type = fix;
5049 }
5050 return ret;
5051 }
5052 };
5053 });
5054
5055 // IE submit delegation
5056 if ( !support.submitBubbles ) {
5057
5058 jQuery.event.special.submit = {
5059 setup: function() {
5060 // Only need this for delegated form submit events
5061 if ( jQuery.nodeName( this, "form" ) ) {
5062 return false;
5063 }
5064
5065 // Lazy-add a submit handler when a descendant form may potentially be submitted
5066 jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
5067 // Node name check avoids a VML-related crash in IE (#9807)
5068 var elem = e.target,
5069 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
5070 if ( form && !jQuery._data( form, "submitBubbles" ) ) {
5071 jQuery.event.add( form, "submit._submit", function( event ) {
5072 event._submit_bubble = true;
5073 });
5074 jQuery._data( form, "submitBubbles", true );
5075 }
5076 });
5077 // return undefined since we don't need an event listener
5078 },
5079
5080 postDispatch: function( event ) {
5081 // If form was submitted by the user, bubble the event up the tree
5082 if ( event._submit_bubble ) {
5083 delete event._submit_bubble;
5084 if ( this.parentNode && !event.isTrigger ) {
5085 jQuery.event.simulate( "submit", this.parentNode, event, true );
5086 }
5087 }
5088 },
5089
5090 teardown: function() {
5091 // Only need this for delegated form submit events
5092 if ( jQuery.nodeName( this, "form" ) ) {
5093 return false;
5094 }
5095
5096 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
5097 jQuery.event.remove( this, "._submit" );
5098 }
5099 };
5100 }
5101
5102 // IE change delegation and checkbox/radio fix
5103 if ( !support.changeBubbles ) {
5104
5105 jQuery.event.special.change = {
5106
5107 setup: function() {
5108
5109 if ( rformElems.test( this.nodeName ) ) {
5110 // IE doesn't fire change on a check/radio until blur; trigger it on click
5111 // after a propertychange. Eat the blur-change in special.change.handle.
5112 // This still fires onchange a second time for check/radio after blur.
5113 if ( this.type === "checkbox" || this.type === "radio" ) {
5114 jQuery.event.add( this, "propertychange._change", function( event ) {
5115 if ( event.originalEvent.propertyName === "checked" ) {
5116 this._just_changed = true;
5117 }
5118 });
5119 jQuery.event.add( this, "click._change", function( event ) {
5120 if ( this._just_changed && !event.isTrigger ) {
5121 this._just_changed = false;
5122 }
5123 // Allow triggered, simulated change events (#11500)
5124 jQuery.event.simulate( "change", this, event, true );
5125 });
5126 }
5127 return false;
5128 }
5129 // Delegated event; lazy-add a change handler on descendant inputs
5130 jQuery.event.add( this, "beforeactivate._change", function( e ) {
5131 var elem = e.target;
5132
5133 if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
5134 jQuery.event.add( elem, "change._change", function( event ) {
5135 if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
5136 jQuery.event.simulate( "change", this.parentNode, event, true );
5137 }
5138 });
5139 jQuery._data( elem, "changeBubbles", true );
5140 }
5141 });
5142 },
5143
5144 handle: function( event ) {
5145 var elem = event.target;
5146
5147 // Swallow native change events from checkbox/radio, we already triggered them above
5148 if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
5149 return event.handleObj.handler.apply( this, arguments );
5150 }
5151 },
5152
5153 teardown: function() {
5154 jQuery.event.remove( this, "._change" );
5155
5156 return !rformElems.test( this.nodeName );
5157 }
5158 };
5159 }
5160
5161 // Create "bubbling" focus and blur events
5162 if ( !support.focusinBubbles ) {
5163 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5164
5165 // Attach a single capturing handler on the document while someone wants focusin/focusout
5166 var handler = function( event ) {
5167 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
5168 };
5169
5170 jQuery.event.special[ fix ] = {
5171 setup: function() {
5172 var doc = this.ownerDocument || this,
5173 attaches = jQuery._data( doc, fix );
5174
5175 if ( !attaches ) {
5176 doc.addEventListener( orig, handler, true );
5177 }
5178 jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
5179 },
5180 teardown: function() {
5181 var doc = this.ownerDocument || this,
5182 attaches = jQuery._data( doc, fix ) - 1;
5183
5184 if ( !attaches ) {
5185 doc.removeEventListener( orig, handler, true );
5186 jQuery._removeData( doc, fix );
5187 } else {
5188 jQuery._data( doc, fix, attaches );
5189 }
5190 }
5191 };
5192 });
5193 }
5194
5195 jQuery.fn.extend({
5196
5197 on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
5198 var type, origFn;
5199
5200 // Types can be a map of types/handlers
5201 if ( typeof types === "object" ) {
5202 // ( types-Object, selector, data )
5203 if ( typeof selector !== "string" ) {
5204 // ( types-Object, data )
5205 data = data || selector;
5206 selector = undefined;
5207 }
5208 for ( type in types ) {
5209 this.on( type, selector, data, types[ type ], one );
5210 }
5211 return this;
5212 }
5213
5214 if ( data == null && fn == null ) {
5215 // ( types, fn )
5216 fn = selector;
5217 data = selector = undefined;
5218 } else if ( fn == null ) {
5219 if ( typeof selector === "string" ) {
5220 // ( types, selector, fn )
5221 fn = data;
5222 data = undefined;
5223 } else {
5224 // ( types, data, fn )
5225 fn = data;
5226 data = selector;
5227 selector = undefined;
5228 }
5229 }
5230 if ( fn === false ) {
5231 fn = returnFalse;
5232 } else if ( !fn ) {
5233 return this;
5234 }
5235
5236 if ( one === 1 ) {
5237 origFn = fn;
5238 fn = function( event ) {
5239 // Can use an empty set, since event contains the info
5240 jQuery().off( event );
5241 return origFn.apply( this, arguments );
5242 };
5243 // Use same guid so caller can remove using origFn
5244 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5245 }
5246 return this.each( function() {
5247 jQuery.event.add( this, types, fn, data, selector );
5248 });
5249 },
5250 one: function( types, selector, data, fn ) {
5251 return this.on( types, selector, data, fn, 1 );
5252 },
5253 off: function( types, selector, fn ) {
5254 var handleObj, type;
5255 if ( types && types.preventDefault && types.handleObj ) {
5256 // ( event ) dispatched jQuery.Event
5257 handleObj = types.handleObj;
5258 jQuery( types.delegateTarget ).off(
5259 handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
5260 handleObj.selector,
5261 handleObj.handler
5262 );
5263 return this;
5264 }
5265 if ( typeof types === "object" ) {
5266 // ( types-object [, selector] )
5267 for ( type in types ) {
5268 this.off( type, selector, types[ type ] );
5269 }
5270 return this;
5271 }
5272 if ( selector === false || typeof selector === "function" ) {
5273 // ( types [, fn] )
5274 fn = selector;
5275 selector = undefined;
5276 }
5277 if ( fn === false ) {
5278 fn = returnFalse;
5279 }
5280 return this.each(function() {
5281 jQuery.event.remove( this, types, fn, selector );
5282 });
5283 },
5284
5285 trigger: function( type, data ) {
5286 return this.each(function() {
5287 jQuery.event.trigger( type, data, this );
5288 });
5289 },
5290 triggerHandler: function( type, data ) {
5291 var elem = this[0];
5292 if ( elem ) {
5293 return jQuery.event.trigger( type, data, elem, true );
5294 }
5295 }
5296 });
5297
5298
5299 function createSafeFragment( document ) {
5300 var list = nodeNames.split( "|" ),
5301 safeFrag = document.createDocumentFragment();
5302
5303 if ( safeFrag.createElement ) {
5304 while ( list.length ) {
5305 safeFrag.createElement(
5306 list.pop()
5307 );
5308 }
5309 }
5310 return safeFrag;
5311 }
5312
5313 var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
5314 "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5315 rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5316 rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5317 rleadingWhitespace = /^\s+/,
5318 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
5319 rtagName = /<([\w:]+)/,
5320 rtbody = /<tbody/i,
5321 rhtml = /<|&#?\w+;/,
5322 rnoInnerhtml = /<(?:script|style|link)/i,
5323 // checked="checked" or checked
5324 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5325 rscriptType = /^$|\/(?:java|ecma)script/i,
5326 rscriptTypeMasked = /^true\/(.*)/,
5327 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5328
5329 // We have to close these tags to support XHTML (#13200)
5330 wrapMap = {
5331 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5332 legend: [ 1, "<fieldset>", "</fieldset>" ],
5333 area: [ 1, "<map>", "</map>" ],
5334 param: [ 1, "<object>", "</object>" ],
5335 thead: [ 1, "<table>", "</table>" ],
5336 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5337 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5338 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5339
5340 // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
5341 // unless wrapped in a div with non-breaking characters in front of it.
5342 _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
5343 },
5344 safeFragment = createSafeFragment( document ),
5345 fragmentDiv = safeFragment.appendChild( document.createElement("div") );
5346
5347 wrapMap.optgroup = wrapMap.option;
5348 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5349 wrapMap.th = wrapMap.td;
5350
5351 function getAll( context, tag ) {
5352 var elems, elem,
5353 i = 0,
5354 found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) :
5355 typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) :
5356 undefined;
5357
5358 if ( !found ) {
5359 for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
5360 if ( !tag || jQuery.nodeName( elem, tag ) ) {
5361 found.push( elem );
5362 } else {
5363 jQuery.merge( found, getAll( elem, tag ) );
5364 }
5365 }
5366 }
5367
5368 return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
5369 jQuery.merge( [ context ], found ) :
5370 found;
5371 }
5372
5373 // Used in buildFragment, fixes the defaultChecked property
5374 function fixDefaultChecked( elem ) {
5375 if ( rcheckableType.test( elem.type ) ) {
5376 elem.defaultChecked = elem.checked;
5377 }
5378 }
5379
5380 // Support: IE<8
5381 // Manipulating tables requires a tbody
5382 function manipulationTarget( elem, content ) {
5383 return jQuery.nodeName( elem, "table" ) &&
5384 jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5385
5386 elem.getElementsByTagName("tbody")[0] ||
5387 elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
5388 elem;
5389 }
5390
5391 // Replace/restore the type attribute of script elements for safe DOM manipulation
5392 function disableScript( elem ) {
5393 elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
5394 return elem;
5395 }
5396 function restoreScript( elem ) {
5397 var match = rscriptTypeMasked.exec( elem.type );
5398 if ( match ) {
5399 elem.type = match[1];
5400 } else {
5401 elem.removeAttribute("type");
5402 }
5403 return elem;
5404 }
5405
5406 // Mark scripts as having already been evaluated
5407 function setGlobalEval( elems, refElements ) {
5408 var elem,
5409 i = 0;
5410 for ( ; (elem = elems[i]) != null; i++ ) {
5411 jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
5412 }
5413 }
5414
5415 function cloneCopyEvent( src, dest ) {
5416
5417 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5418 return;
5419 }
5420
5421 var type, i, l,
5422 oldData = jQuery._data( src ),
5423 curData = jQuery._data( dest, oldData ),
5424 events = oldData.events;
5425
5426 if ( events ) {
5427 delete curData.handle;
5428 curData.events = {};
5429
5430 for ( type in events ) {
5431 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5432 jQuery.event.add( dest, type, events[ type ][ i ] );
5433 }
5434 }
5435 }
5436
5437 // make the cloned public data object a copy from the original
5438 if ( curData.data ) {
5439 curData.data = jQuery.extend( {}, curData.data );
5440 }
5441 }
5442
5443 function fixCloneNodeIssues( src, dest ) {
5444 var nodeName, e, data;
5445
5446 // We do not need to do anything for non-Elements
5447 if ( dest.nodeType !== 1 ) {
5448 return;
5449 }
5450
5451 nodeName = dest.nodeName.toLowerCase();
5452
5453 // IE6-8 copies events bound via attachEvent when using cloneNode.
5454 if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
5455 data = jQuery._data( dest );
5456
5457 for ( e in data.events ) {
5458 jQuery.removeEvent( dest, e, data.handle );
5459 }
5460
5461 // Event data gets referenced instead of copied if the expando gets copied too
5462 dest.removeAttribute( jQuery.expando );
5463 }
5464
5465 // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
5466 if ( nodeName === "script" && dest.text !== src.text ) {
5467 disableScript( dest ).text = src.text;
5468 restoreScript( dest );
5469
5470 // IE6-10 improperly clones children of object elements using classid.
5471 // IE10 throws NoModificationAllowedError if parent is null, #12132.
5472 } else if ( nodeName === "object" ) {
5473 if ( dest.parentNode ) {
5474 dest.outerHTML = src.outerHTML;
5475 }
5476
5477 // This path appears unavoidable for IE9. When cloning an object
5478 // element in IE9, the outerHTML strategy above is not sufficient.
5479 // If the src has innerHTML and the destination does not,
5480 // copy the src.innerHTML into the dest.innerHTML. #10324
5481 if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
5482 dest.innerHTML = src.innerHTML;
5483 }
5484
5485 } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5486 // IE6-8 fails to persist the checked state of a cloned checkbox
5487 // or radio button. Worse, IE6-7 fail to give the cloned element
5488 // a checked appearance if the defaultChecked value isn't also set
5489
5490 dest.defaultChecked = dest.checked = src.checked;
5491
5492 // IE6-7 get confused and end up setting the value of a cloned
5493 // checkbox/radio button to an empty string instead of "on"
5494 if ( dest.value !== src.value ) {
5495 dest.value = src.value;
5496 }
5497
5498 // IE6-8 fails to return the selected option to the default selected
5499 // state when cloning options
5500 } else if ( nodeName === "option" ) {
5501 dest.defaultSelected = dest.selected = src.defaultSelected;
5502
5503 // IE6-8 fails to set the defaultValue to the correct value when
5504 // cloning other types of input fields
5505 } else if ( nodeName === "input" || nodeName === "textarea" ) {
5506 dest.defaultValue = src.defaultValue;
5507 }
5508 }
5509
5510 jQuery.extend({
5511 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5512 var destElements, node, clone, i, srcElements,
5513 inPage = jQuery.contains( elem.ownerDocument, elem );
5514
5515 if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
5516 clone = elem.cloneNode( true );
5517
5518 // IE<=8 does not properly clone detached, unknown element nodes
5519 } else {
5520 fragmentDiv.innerHTML = elem.outerHTML;
5521 fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
5522 }
5523
5524 if ( (!support.noCloneEvent || !support.noCloneChecked) &&
5525 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
5526
5527 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5528 destElements = getAll( clone );
5529 srcElements = getAll( elem );
5530
5531 // Fix all IE cloning issues
5532 for ( i = 0; (node = srcElements[i]) != null; ++i ) {
5533 // Ensure that the destination node is not null; Fixes #9587
5534 if ( destElements[i] ) {
5535 fixCloneNodeIssues( node, destElements[i] );
5536 }
5537 }
5538 }
5539
5540 // Copy the events from the original to the clone
5541 if ( dataAndEvents ) {
5542 if ( deepDataAndEvents ) {
5543 srcElements = srcElements || getAll( elem );
5544 destElements = destElements || getAll( clone );
5545
5546 for ( i = 0; (node = srcElements[i]) != null; i++ ) {
5547 cloneCopyEvent( node, destElements[i] );
5548 }
5549 } else {
5550 cloneCopyEvent( elem, clone );
5551 }
5552 }
5553
5554 // Preserve script evaluation history
5555 destElements = getAll( clone, "script" );
5556 if ( destElements.length > 0 ) {
5557 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5558 }
5559
5560 destElements = srcElements = node = null;
5561
5562 // Return the cloned set
5563 return clone;
5564 },
5565
5566 buildFragment: function( elems, context, scripts, selection ) {
5567 var j, elem, contains,
5568 tmp, tag, tbody, wrap,
5569 l = elems.length,
5570
5571 // Ensure a safe fragment
5572 safe = createSafeFragment( context ),
5573
5574 nodes = [],
5575 i = 0;
5576
5577 for ( ; i < l; i++ ) {
5578 elem = elems[ i ];
5579
5580 if ( elem || elem === 0 ) {
5581
5582 // Add nodes directly
5583 if ( jQuery.type( elem ) === "object" ) {
5584 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5585
5586 // Convert non-html into a text node
5587 } else if ( !rhtml.test( elem ) ) {
5588 nodes.push( context.createTextNode( elem ) );
5589
5590 // Convert html into DOM nodes
5591 } else {
5592 tmp = tmp || safe.appendChild( context.createElement("div") );
5593
5594 // Deserialize a standard representation
5595 tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase();
5596 wrap = wrapMap[ tag ] || wrapMap._default;
5597
5598 tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
5599
5600 // Descend through wrappers to the right content
5601 j = wrap[0];
5602 while ( j-- ) {
5603 tmp = tmp.lastChild;
5604 }
5605
5606 // Manually add leading whitespace removed by IE
5607 if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
5608 nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
5609 }
5610
5611 // Remove IE's autoinserted <tbody> from table fragments
5612 if ( !support.tbody ) {
5613
5614 // String was a <table>, *may* have spurious <tbody>
5615 elem = tag === "table" && !rtbody.test( elem ) ?
5616 tmp.firstChild :
5617
5618 // String was a bare <thead> or <tfoot>
5619 wrap[1] === "<table>" && !rtbody.test( elem ) ?
5620 tmp :
5621 0;
5622
5623 j = elem && elem.childNodes.length;
5624 while ( j-- ) {
5625 if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
5626 elem.removeChild( tbody );
5627 }
5628 }
5629 }
5630
5631 jQuery.merge( nodes, tmp.childNodes );
5632
5633 // Fix #12392 for WebKit and IE > 9
5634 tmp.textContent = "";
5635
5636 // Fix #12392 for oldIE
5637 while ( tmp.firstChild ) {
5638 tmp.removeChild( tmp.firstChild );
5639 }
5640
5641 // Remember the top-level container for proper cleanup
5642 tmp = safe.lastChild;
5643 }
5644 }
5645 }
5646
5647 // Fix #11356: Clear elements from fragment
5648 if ( tmp ) {
5649 safe.removeChild( tmp );
5650 }
5651
5652 // Reset defaultChecked for any radios and checkboxes
5653 // about to be appended to the DOM in IE 6/7 (#8060)
5654 if ( !support.appendChecked ) {
5655 jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
5656 }
5657
5658 i = 0;
5659 while ( (elem = nodes[ i++ ]) ) {
5660
5661 // #4087 - If origin and destination elements are the same, and this is
5662 // that element, do not do anything
5663 if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
5664 continue;
5665 }
5666
5667 contains = jQuery.contains( elem.ownerDocument, elem );
5668
5669 // Append to fragment
5670 tmp = getAll( safe.appendChild( elem ), "script" );
5671
5672 // Preserve script evaluation history
5673 if ( contains ) {
5674 setGlobalEval( tmp );
5675 }
5676
5677 // Capture executables
5678 if ( scripts ) {
5679 j = 0;
5680 while ( (elem = tmp[ j++ ]) ) {
5681 if ( rscriptType.test( elem.type || "" ) ) {
5682 scripts.push( elem );
5683 }
5684 }
5685 }
5686 }
5687
5688 tmp = null;
5689
5690 return safe;
5691 },
5692
5693 cleanData: function( elems, /* internal */ acceptData ) {
5694 var elem, type, id, data,
5695 i = 0,
5696 internalKey = jQuery.expando,
5697 cache = jQuery.cache,
5698 deleteExpando = support.deleteExpando,
5699 special = jQuery.event.special;
5700
5701 for ( ; (elem = elems[i]) != null; i++ ) {
5702 if ( acceptData || jQuery.acceptData( elem ) ) {
5703
5704 id = elem[ internalKey ];
5705 data = id && cache[ id ];
5706
5707 if ( data ) {
5708 if ( data.events ) {
5709 for ( type in data.events ) {
5710 if ( special[ type ] ) {
5711 jQuery.event.remove( elem, type );
5712
5713 // This is a shortcut to avoid jQuery.event.remove's overhead
5714 } else {
5715 jQuery.removeEvent( elem, type, data.handle );
5716 }
5717 }
5718 }
5719
5720 // Remove cache only if it was not already removed by jQuery.event.remove
5721 if ( cache[ id ] ) {
5722
5723 delete cache[ id ];
5724
5725 // IE does not allow us to delete expando properties from nodes,
5726 // nor does it have a removeAttribute function on Document nodes;
5727 // we must handle all of these cases
5728 if ( deleteExpando ) {
5729 delete elem[ internalKey ];
5730
5731 } else if ( typeof elem.removeAttribute !== strundefined ) {
5732 elem.removeAttribute( internalKey );
5733
5734 } else {
5735 elem[ internalKey ] = null;
5736 }
5737
5738 deletedIds.push( id );
5739 }
5740 }
5741 }
5742 }
5743 }
5744 });
5745
5746 jQuery.fn.extend({
5747 text: function( value ) {
5748 return access( this, function( value ) {
5749 return value === undefined ?
5750 jQuery.text( this ) :
5751 this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
5752 }, null, value, arguments.length );
5753 },
5754
5755 append: function() {
5756 return this.domManip( arguments, function( elem ) {
5757 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5758 var target = manipulationTarget( this, elem );
5759 target.appendChild( elem );
5760 }
5761 });
5762 },
5763
5764 prepend: function() {
5765 return this.domManip( arguments, function( elem ) {
5766 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5767 var target = manipulationTarget( this, elem );
5768 target.insertBefore( elem, target.firstChild );
5769 }
5770 });
5771 },
5772
5773 before: function() {
5774 return this.domManip( arguments, function( elem ) {
5775 if ( this.parentNode ) {
5776 this.parentNode.insertBefore( elem, this );
5777 }
5778 });
5779 },
5780
5781 after: function() {
5782 return this.domManip( arguments, function( elem ) {
5783 if ( this.parentNode ) {
5784 this.parentNode.insertBefore( elem, this.nextSibling );
5785 }
5786 });
5787 },
5788
5789 remove: function( selector, keepData /* Internal Use Only */ ) {
5790 var elem,
5791 elems = selector ? jQuery.filter( selector, this ) : this,
5792 i = 0;
5793
5794 for ( ; (elem = elems[i]) != null; i++ ) {
5795
5796 if ( !keepData && elem.nodeType === 1 ) {
5797 jQuery.cleanData( getAll( elem ) );
5798 }
5799
5800 if ( elem.parentNode ) {
5801 if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
5802 setGlobalEval( getAll( elem, "script" ) );
5803 }
5804 elem.parentNode.removeChild( elem );
5805 }
5806 }
5807
5808 return this;
5809 },
5810
5811 empty: function() {
5812 var elem,
5813 i = 0;
5814
5815 for ( ; (elem = this[i]) != null; i++ ) {
5816 // Remove element nodes and prevent memory leaks
5817 if ( elem.nodeType === 1 ) {
5818 jQuery.cleanData( getAll( elem, false ) );
5819 }
5820
5821 // Remove any remaining nodes
5822 while ( elem.firstChild ) {
5823 elem.removeChild( elem.firstChild );
5824 }
5825
5826 // If this is a select, ensure that it displays empty (#12336)
5827 // Support: IE<9
5828 if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
5829 elem.options.length = 0;
5830 }
5831 }
5832
5833 return this;
5834 },
5835
5836 clone: function( dataAndEvents, deepDataAndEvents ) {
5837 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5838 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5839
5840 return this.map(function() {
5841 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5842 });
5843 },
5844
5845 html: function( value ) {
5846 return access( this, function( value ) {
5847 var elem = this[ 0 ] || {},
5848 i = 0,
5849 l = this.length;
5850
5851 if ( value === undefined ) {
5852 return elem.nodeType === 1 ?
5853 elem.innerHTML.replace( rinlinejQuery, "" ) :
5854 undefined;
5855 }
5856
5857 // See if we can take a shortcut and just use innerHTML
5858 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5859 ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
5860 ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
5861 !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
5862
5863 value = value.replace( rxhtmlTag, "<$1></$2>" );
5864
5865 try {
5866 for (; i < l; i++ ) {
5867 // Remove element nodes and prevent memory leaks
5868 elem = this[i] || {};
5869 if ( elem.nodeType === 1 ) {
5870 jQuery.cleanData( getAll( elem, false ) );
5871 elem.innerHTML = value;
5872 }
5873 }
5874
5875 elem = 0;
5876
5877 // If using innerHTML throws an exception, use the fallback method
5878 } catch(e) {}
5879 }
5880
5881 if ( elem ) {
5882 this.empty().append( value );
5883 }
5884 }, null, value, arguments.length );
5885 },
5886
5887 replaceWith: function() {
5888 var arg = arguments[ 0 ];
5889
5890 // Make the changes, replacing each context element with the new content
5891 this.domManip( arguments, function( elem ) {
5892 arg = this.parentNode;
5893
5894 jQuery.cleanData( getAll( this ) );
5895
5896 if ( arg ) {
5897 arg.replaceChild( elem, this );
5898 }
5899 });
5900
5901 // Force removal if there was no new content (e.g., from empty arguments)
5902 return arg && (arg.length || arg.nodeType) ? this : this.remove();
5903 },
5904
5905 detach: function( selector ) {
5906 return this.remove( selector, true );
5907 },
5908
5909 domManip: function( args, callback ) {
5910
5911 // Flatten any nested arrays
5912 args = concat.apply( [], args );
5913
5914 var first, node, hasScripts,
5915 scripts, doc, fragment,
5916 i = 0,
5917 l = this.length,
5918 set = this,
5919 iNoClone = l - 1,
5920 value = args[0],
5921 isFunction = jQuery.isFunction( value );
5922
5923 // We can't cloneNode fragments that contain checked, in WebKit
5924 if ( isFunction ||
5925 ( l > 1 && typeof value === "string" &&
5926 !support.checkClone && rchecked.test( value ) ) ) {
5927 return this.each(function( index ) {
5928 var self = set.eq( index );
5929 if ( isFunction ) {
5930 args[0] = value.call( this, index, self.html() );
5931 }
5932 self.domManip( args, callback );
5933 });
5934 }
5935
5936 if ( l ) {
5937 fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
5938 first = fragment.firstChild;
5939
5940 if ( fragment.childNodes.length === 1 ) {
5941 fragment = first;
5942 }
5943
5944 if ( first ) {
5945 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5946 hasScripts = scripts.length;
5947
5948 // Use the original fragment for the last item instead of the first because it can end up
5949 // being emptied incorrectly in certain situations (#8070).
5950 for ( ; i < l; i++ ) {
5951 node = fragment;
5952
5953 if ( i !== iNoClone ) {
5954 node = jQuery.clone( node, true, true );
5955
5956 // Keep references to cloned scripts for later restoration
5957 if ( hasScripts ) {
5958 jQuery.merge( scripts, getAll( node, "script" ) );
5959 }
5960 }
5961
5962 callback.call( this[i], node, i );
5963 }
5964
5965 if ( hasScripts ) {
5966 doc = scripts[ scripts.length - 1 ].ownerDocument;
5967
5968 // Reenable scripts
5969 jQuery.map( scripts, restoreScript );
5970
5971 // Evaluate executable scripts on first document insertion
5972 for ( i = 0; i < hasScripts; i++ ) {
5973 node = scripts[ i ];
5974 if ( rscriptType.test( node.type || "" ) &&
5975 !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
5976
5977 if ( node.src ) {
5978 // Optional AJAX dependency, but won't run scripts if not present
5979 if ( jQuery._evalUrl ) {
5980 jQuery._evalUrl( node.src );
5981 }
5982 } else {
5983 jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
5984 }
5985 }
5986 }
5987 }
5988
5989 // Fix #11809: Avoid leaking memory
5990 fragment = first = null;
5991 }
5992 }
5993
5994 return this;
5995 }
5996 });
5997
5998 jQuery.each({
5999 appendTo: "append",
6000 prependTo: "prepend",
6001 insertBefore: "before",
6002 insertAfter: "after",
6003 replaceAll: "replaceWith"
6004 }, function( name, original ) {
6005 jQuery.fn[ name ] = function( selector ) {
6006 var elems,
6007 i = 0,
6008 ret = [],
6009 insert = jQuery( selector ),
6010 last = insert.length - 1;
6011
6012 for ( ; i <= last; i++ ) {
6013 elems = i === last ? this : this.clone(true);
6014 jQuery( insert[i] )[ original ]( elems );
6015
6016 // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
6017 push.apply( ret, elems.get() );
6018 }
6019
6020 return this.pushStack( ret );
6021 };
6022 });
6023
6024
6025 var iframe,
6026 elemdisplay = {};
6027
6028 /**
6029 * Retrieve the actual display of a element
6030 * @param {String} name nodeName of the element
6031 * @param {Object} doc Document object
6032 */
6033 // Called only from within defaultDisplay
6034 function actualDisplay( name, doc ) {
6035 var style,
6036 elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
6037
6038 // getDefaultComputedStyle might be reliably used only on attached element
6039 display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
6040
6041 // Use of this method is a temporary fix (more like optmization) until something better comes along,
6042 // since it was removed from specification and supported only in FF
6043 style.display : jQuery.css( elem[ 0 ], "display" );
6044
6045 // We don't have any data stored on the element,
6046 // so use "detach" method as fast way to get rid of the element
6047 elem.detach();
6048
6049 return display;
6050 }
6051
6052 /**
6053 * Try to determine the default display value of an element
6054 * @param {String} nodeName
6055 */
6056 function defaultDisplay( nodeName ) {
6057 var doc = document,
6058 display = elemdisplay[ nodeName ];
6059
6060 if ( !display ) {
6061 display = actualDisplay( nodeName, doc );
6062
6063 // If the simple way fails, read from inside an iframe
6064 if ( display === "none" || !display ) {
6065
6066 // Use the already-created iframe if possible
6067 iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
6068
6069 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6070 doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
6071
6072 // Support: IE
6073 doc.write();
6074 doc.close();
6075
6076 display = actualDisplay( nodeName, doc );
6077 iframe.detach();
6078 }
6079
6080 // Store the correct default display
6081 elemdisplay[ nodeName ] = display;
6082 }
6083
6084 return display;
6085 }
6086
6087
6088 (function() {
6089 var shrinkWrapBlocksVal;
6090
6091 support.shrinkWrapBlocks = function() {
6092 if ( shrinkWrapBlocksVal != null ) {
6093 return shrinkWrapBlocksVal;
6094 }
6095
6096 // Will be changed later if needed.
6097 shrinkWrapBlocksVal = false;
6098
6099 // Minified: var b,c,d
6100 var div, body, container;
6101
6102 body = document.getElementsByTagName( "body" )[ 0 ];
6103 if ( !body || !body.style ) {
6104 // Test fired too early or in an unsupported environment, exit.
6105 return;
6106 }
6107
6108 // Setup
6109 div = document.createElement( "div" );
6110 container = document.createElement( "div" );
6111 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
6112 body.appendChild( container ).appendChild( div );
6113
6114 // Support: IE6
6115 // Check if elements with layout shrink-wrap their children
6116 if ( typeof div.style.zoom !== strundefined ) {
6117 // Reset CSS: box-sizing; display; margin; border
6118 div.style.cssText =
6119 // Support: Firefox<29, Android 2.3
6120 // Vendor-prefix box-sizing
6121 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
6122 "box-sizing:content-box;display:block;margin:0;border:0;" +
6123 "padding:1px;width:1px;zoom:1";
6124 div.appendChild( document.createElement( "div" ) ).style.width = "5px";
6125 shrinkWrapBlocksVal = div.offsetWidth !== 3;
6126 }
6127
6128 body.removeChild( container );
6129
6130 return shrinkWrapBlocksVal;
6131 };
6132
6133 })();
6134 var rmargin = (/^margin/);
6135
6136 var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6137
6138
6139
6140 var getStyles, curCSS,
6141 rposition = /^(top|right|bottom|left)$/;
6142
6143 if ( window.getComputedStyle ) {
6144 getStyles = function( elem ) {
6145 // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
6146 // IE throws on elements created in popups
6147 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6148 if ( elem.ownerDocument.defaultView.opener ) {
6149 return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
6150 }
6151
6152 return window.getComputedStyle( elem, null );
6153 };
6154
6155 curCSS = function( elem, name, computed ) {
6156 var width, minWidth, maxWidth, ret,
6157 style = elem.style;
6158
6159 computed = computed || getStyles( elem );
6160
6161 // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6162 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
6163
6164 if ( computed ) {
6165
6166 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6167 ret = jQuery.style( elem, name );
6168 }
6169
6170 // A tribute to the "awesome hack by Dean Edwards"
6171 // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
6172 // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
6173 // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6174 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6175
6176 // Remember the original values
6177 width = style.width;
6178 minWidth = style.minWidth;
6179 maxWidth = style.maxWidth;
6180
6181 // Put in the new values to get a computed value out
6182 style.minWidth = style.maxWidth = style.width = ret;
6183 ret = computed.width;
6184
6185 // Revert the changed values
6186 style.width = width;
6187 style.minWidth = minWidth;
6188 style.maxWidth = maxWidth;
6189 }
6190 }
6191
6192 // Support: IE
6193 // IE returns zIndex value as an integer.
6194 return ret === undefined ?
6195 ret :
6196 ret + "";
6197 };
6198 } else if ( document.documentElement.currentStyle ) {
6199 getStyles = function( elem ) {
6200 return elem.currentStyle;
6201 };
6202
6203 curCSS = function( elem, name, computed ) {
6204 var left, rs, rsLeft, ret,
6205 style = elem.style;
6206
6207 computed = computed || getStyles( elem );
6208 ret = computed ? computed[ name ] : undefined;
6209
6210 // Avoid setting ret to empty string here
6211 // so we don't default to auto
6212 if ( ret == null && style && style[ name ] ) {
6213 ret = style[ name ];
6214 }
6215
6216 // From the awesome hack by Dean Edwards
6217 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6218
6219 // If we're not dealing with a regular pixel number
6220 // but a number that has a weird ending, we need to convert it to pixels
6221 // but not position css attributes, as those are proportional to the parent element instead
6222 // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
6223 if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6224
6225 // Remember the original values
6226 left = style.left;
6227 rs = elem.runtimeStyle;
6228 rsLeft = rs && rs.left;
6229
6230 // Put in the new values to get a computed value out
6231 if ( rsLeft ) {
6232 rs.left = elem.currentStyle.left;
6233 }
6234 style.left = name === "fontSize" ? "1em" : ret;
6235 ret = style.pixelLeft + "px";
6236
6237 // Revert the changed values
6238 style.left = left;
6239 if ( rsLeft ) {
6240 rs.left = rsLeft;
6241 }
6242 }
6243
6244 // Support: IE
6245 // IE returns zIndex value as an integer.
6246 return ret === undefined ?
6247 ret :
6248 ret + "" || "auto";
6249 };
6250 }
6251
6252
6253
6254
6255 function addGetHookIf( conditionFn, hookFn ) {
6256 // Define the hook, we'll check on the first run if it's really needed.
6257 return {
6258 get: function() {
6259 var condition = conditionFn();
6260
6261 if ( condition == null ) {
6262 // The test was not ready at this point; screw the hook this time
6263 // but check again when needed next time.
6264 return;
6265 }
6266
6267 if ( condition ) {
6268 // Hook not needed (or it's not possible to use it due to missing dependency),
6269 // remove it.
6270 // Since there are no other hooks for marginRight, remove the whole object.
6271 delete this.get;
6272 return;
6273 }
6274
6275 // Hook needed; redefine it so that the support test is not executed again.
6276
6277 return (this.get = hookFn).apply( this, arguments );
6278 }
6279 };
6280 }
6281
6282
6283 (function() {
6284 // Minified: var b,c,d,e,f,g, h,i
6285 var div, style, a, pixelPositionVal, boxSizingReliableVal,
6286 reliableHiddenOffsetsVal, reliableMarginRightVal;
6287
6288 // Setup
6289 div = document.createElement( "div" );
6290 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
6291 a = div.getElementsByTagName( "a" )[ 0 ];
6292 style = a && a.style;
6293
6294 // Finish early in limited (non-browser) environments
6295 if ( !style ) {
6296 return;
6297 }
6298
6299 style.cssText = "float:left;opacity:.5";
6300
6301 // Support: IE<9
6302 // Make sure that element opacity exists (as opposed to filter)
6303 support.opacity = style.opacity === "0.5";
6304
6305 // Verify style float existence
6306 // (IE uses styleFloat instead of cssFloat)
6307 support.cssFloat = !!style.cssFloat;
6308
6309 div.style.backgroundClip = "content-box";
6310 div.cloneNode( true ).style.backgroundClip = "";
6311 support.clearCloneStyle = div.style.backgroundClip === "content-box";
6312
6313 // Support: Firefox<29, Android 2.3
6314 // Vendor-prefix box-sizing
6315 support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" ||
6316 style.WebkitBoxSizing === "";
6317
6318 jQuery.extend(support, {
6319 reliableHiddenOffsets: function() {
6320 if ( reliableHiddenOffsetsVal == null ) {
6321 computeStyleTests();
6322 }
6323 return reliableHiddenOffsetsVal;
6324 },
6325
6326 boxSizingReliable: function() {
6327 if ( boxSizingReliableVal == null ) {
6328 computeStyleTests();
6329 }
6330 return boxSizingReliableVal;
6331 },
6332
6333 pixelPosition: function() {
6334 if ( pixelPositionVal == null ) {
6335 computeStyleTests();
6336 }
6337 return pixelPositionVal;
6338 },
6339
6340 // Support: Android 2.3
6341 reliableMarginRight: function() {
6342 if ( reliableMarginRightVal == null ) {
6343 computeStyleTests();
6344 }
6345 return reliableMarginRightVal;
6346 }
6347 });
6348
6349 function computeStyleTests() {
6350 // Minified: var b,c,d,j
6351 var div, body, container, contents;
6352
6353 body = document.getElementsByTagName( "body" )[ 0 ];
6354 if ( !body || !body.style ) {
6355 // Test fired too early or in an unsupported environment, exit.
6356 return;
6357 }
6358
6359 // Setup
6360 div = document.createElement( "div" );
6361 container = document.createElement( "div" );
6362 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
6363 body.appendChild( container ).appendChild( div );
6364
6365 div.style.cssText =
6366 // Support: Firefox<29, Android 2.3
6367 // Vendor-prefix box-sizing
6368 "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
6369 "box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
6370 "border:1px;padding:1px;width:4px;position:absolute";
6371
6372 // Support: IE<9
6373 // Assume reasonable values in the absence of getComputedStyle
6374 pixelPositionVal = boxSizingReliableVal = false;
6375 reliableMarginRightVal = true;
6376
6377 // Check for getComputedStyle so that this code is not run in IE<9.
6378 if ( window.getComputedStyle ) {
6379 pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
6380 boxSizingReliableVal =
6381 ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
6382
6383 // Support: Android 2.3
6384 // Div with explicit width and no margin-right incorrectly
6385 // gets computed margin-right based on width of container (#3333)
6386 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6387 contents = div.appendChild( document.createElement( "div" ) );
6388
6389 // Reset CSS: box-sizing; display; margin; border; padding
6390 contents.style.cssText = div.style.cssText =
6391 // Support: Firefox<29, Android 2.3
6392 // Vendor-prefix box-sizing
6393 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
6394 "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
6395 contents.style.marginRight = contents.style.width = "0";
6396 div.style.width = "1px";
6397
6398 reliableMarginRightVal =
6399 !parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );
6400
6401 div.removeChild( contents );
6402 }
6403
6404 // Support: IE8
6405 // Check if table cells still have offsetWidth/Height when they are set
6406 // to display:none and there are still other visible table cells in a
6407 // table row; if so, offsetWidth/Height are not reliable for use when
6408 // determining if an element has been hidden directly using
6409 // display:none (it is still safe to use offsets if a parent element is
6410 // hidden; don safety goggles and see bug #4512 for more information).
6411 div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
6412 contents = div.getElementsByTagName( "td" );
6413 contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
6414 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6415 if ( reliableHiddenOffsetsVal ) {
6416 contents[ 0 ].style.display = "";
6417 contents[ 1 ].style.display = "none";
6418 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6419 }
6420
6421 body.removeChild( container );
6422 }
6423
6424 })();
6425
6426
6427 // A method for quickly swapping in/out CSS properties to get correct calculations.
6428 jQuery.swap = function( elem, options, callback, args ) {
6429 var ret, name,
6430 old = {};
6431
6432 // Remember the old values, and insert the new ones
6433 for ( name in options ) {
6434 old[ name ] = elem.style[ name ];
6435 elem.style[ name ] = options[ name ];
6436 }
6437
6438 ret = callback.apply( elem, args || [] );
6439
6440 // Revert the old values
6441 for ( name in options ) {
6442 elem.style[ name ] = old[ name ];
6443 }
6444
6445 return ret;
6446 };
6447
6448
6449 var
6450 ralpha = /alpha\([^)]*\)/i,
6451 ropacity = /opacity\s*=\s*([^)]*)/,
6452
6453 // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6454 // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6455 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6456 rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
6457 rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
6458
6459 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6460 cssNormalTransform = {
6461 letterSpacing: "0",
6462 fontWeight: "400"
6463 },
6464
6465 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
6466
6467
6468 // return a css property mapped to a potentially vendor prefixed property
6469 function vendorPropName( style, name ) {
6470
6471 // shortcut for names that are not vendor prefixed
6472 if ( name in style ) {
6473 return name;
6474 }
6475
6476 // check for vendor prefixed names
6477 var capName = name.charAt(0).toUpperCase() + name.slice(1),
6478 origName = name,
6479 i = cssPrefixes.length;
6480
6481 while ( i-- ) {
6482 name = cssPrefixes[ i ] + capName;
6483 if ( name in style ) {
6484 return name;
6485 }
6486 }
6487
6488 return origName;
6489 }
6490
6491 function showHide( elements, show ) {
6492 var display, elem, hidden,
6493 values = [],
6494 index = 0,
6495 length = elements.length;
6496
6497 for ( ; index < length; index++ ) {
6498 elem = elements[ index ];
6499 if ( !elem.style ) {
6500 continue;
6501 }
6502
6503 values[ index ] = jQuery._data( elem, "olddisplay" );
6504 display = elem.style.display;
6505 if ( show ) {
6506 // Reset the inline display of this element to learn if it is
6507 // being hidden by cascaded rules or not
6508 if ( !values[ index ] && display === "none" ) {
6509 elem.style.display = "";
6510 }
6511
6512 // Set elements which have been overridden with display: none
6513 // in a stylesheet to whatever the default browser style is
6514 // for such an element
6515 if ( elem.style.display === "" && isHidden( elem ) ) {
6516 values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
6517 }
6518 } else {
6519 hidden = isHidden( elem );
6520
6521 if ( display && display !== "none" || !hidden ) {
6522 jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
6523 }
6524 }
6525 }
6526
6527 // Set the display of most of the elements in a second loop
6528 // to avoid the constant reflow
6529 for ( index = 0; index < length; index++ ) {
6530 elem = elements[ index ];
6531 if ( !elem.style ) {
6532 continue;
6533 }
6534 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6535 elem.style.display = show ? values[ index ] || "" : "none";
6536 }
6537 }
6538
6539 return elements;
6540 }
6541
6542 function setPositiveNumber( elem, value, subtract ) {
6543 var matches = rnumsplit.exec( value );
6544 return matches ?
6545 // Guard against undefined "subtract", e.g., when used as in cssHooks
6546 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6547 value;
6548 }
6549
6550 function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6551 var i = extra === ( isBorderBox ? "border" : "content" ) ?
6552 // If we already have the right measurement, avoid augmentation
6553 4 :
6554 // Otherwise initialize for horizontal or vertical properties
6555 name === "width" ? 1 : 0,
6556
6557 val = 0;
6558
6559 for ( ; i < 4; i += 2 ) {
6560 // both box models exclude margin, so add it if we want it
6561 if ( extra === "margin" ) {
6562 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6563 }
6564
6565 if ( isBorderBox ) {
6566 // border-box includes padding, so remove it if we want content
6567 if ( extra === "content" ) {
6568 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6569 }
6570
6571 // at this point, extra isn't border nor margin, so remove border
6572 if ( extra !== "margin" ) {
6573 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6574 }
6575 } else {
6576 // at this point, extra isn't content, so add padding
6577 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6578
6579 // at this point, extra isn't content nor padding, so add border
6580 if ( extra !== "padding" ) {
6581 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6582 }
6583 }
6584 }
6585
6586 return val;
6587 }
6588
6589 function getWidthOrHeight( elem, name, extra ) {
6590
6591 // Start with offset property, which is equivalent to the border-box value
6592 var valueIsBorderBox = true,
6593 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6594 styles = getStyles( elem ),
6595 isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6596
6597 // some non-html elements return undefined for offsetWidth, so check for null/undefined
6598 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6599 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6600 if ( val <= 0 || val == null ) {
6601 // Fall back to computed then uncomputed css if necessary
6602 val = curCSS( elem, name, styles );
6603 if ( val < 0 || val == null ) {
6604 val = elem.style[ name ];
6605 }
6606
6607 // Computed unit is not pixels. Stop here and return.
6608 if ( rnumnonpx.test(val) ) {
6609 return val;
6610 }
6611
6612 // we need the check for style in case a browser which returns unreliable values
6613 // for getComputedStyle silently falls back to the reliable elem.style
6614 valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
6615
6616 // Normalize "", auto, and prepare for extra
6617 val = parseFloat( val ) || 0;
6618 }
6619
6620 // use the active box-sizing model to add/subtract irrelevant styles
6621 return ( val +
6622 augmentWidthOrHeight(
6623 elem,
6624 name,
6625 extra || ( isBorderBox ? "border" : "content" ),
6626 valueIsBorderBox,
6627 styles
6628 )
6629 ) + "px";
6630 }
6631
6632 jQuery.extend({
6633 // Add in style property hooks for overriding the default
6634 // behavior of getting and setting a style property
6635 cssHooks: {
6636 opacity: {
6637 get: function( elem, computed ) {
6638 if ( computed ) {
6639 // We should always get a number back from opacity
6640 var ret = curCSS( elem, "opacity" );
6641 return ret === "" ? "1" : ret;
6642 }
6643 }
6644 }
6645 },
6646
6647 // Don't automatically add "px" to these possibly-unitless properties
6648 cssNumber: {
6649 "columnCount": true,
6650 "fillOpacity": true,
6651 "flexGrow": true,
6652 "flexShrink": true,
6653 "fontWeight": true,
6654 "lineHeight": true,
6655 "opacity": true,
6656 "order": true,
6657 "orphans": true,
6658 "widows": true,
6659 "zIndex": true,
6660 "zoom": true
6661 },
6662
6663 // Add in properties whose names you wish to fix before
6664 // setting or getting the value
6665 cssProps: {
6666 // normalize float css property
6667 "float": support.cssFloat ? "cssFloat" : "styleFloat"
6668 },
6669
6670 // Get and set the style property on a DOM Node
6671 style: function( elem, name, value, extra ) {
6672 // Don't set styles on text and comment nodes
6673 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6674 return;
6675 }
6676
6677 // Make sure that we're working with the right name
6678 var ret, type, hooks,
6679 origName = jQuery.camelCase( name ),
6680 style = elem.style;
6681
6682 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
6683
6684 // gets hook for the prefixed version
6685 // followed by the unprefixed version
6686 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6687
6688 // Check if we're setting a value
6689 if ( value !== undefined ) {
6690 type = typeof value;
6691
6692 // convert relative number strings (+= or -=) to relative numbers. #7345
6693 if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6694 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
6695 // Fixes bug #9237
6696 type = "number";
6697 }
6698
6699 // Make sure that null and NaN values aren't set. See: #7116
6700 if ( value == null || value !== value ) {
6701 return;
6702 }
6703
6704 // If a number was passed in, add 'px' to the (except for certain CSS properties)
6705 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6706 value += "px";
6707 }
6708
6709 // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
6710 // but it would mean to define eight (for every problematic property) identical functions
6711 if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
6712 style[ name ] = "inherit";
6713 }
6714
6715 // If a hook was provided, use that value, otherwise just set the specified value
6716 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
6717
6718 // Support: IE
6719 // Swallow errors from 'invalid' CSS values (#5509)
6720 try {
6721 style[ name ] = value;
6722 } catch(e) {}
6723 }
6724
6725 } else {
6726 // If a hook was provided get the non-computed value from there
6727 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6728 return ret;
6729 }
6730
6731 // Otherwise just get the value from the style object
6732 return style[ name ];
6733 }
6734 },
6735
6736 css: function( elem, name, extra, styles ) {
6737 var num, val, hooks,
6738 origName = jQuery.camelCase( name );
6739
6740 // Make sure that we're working with the right name
6741 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6742
6743 // gets hook for the prefixed version
6744 // followed by the unprefixed version
6745 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6746
6747 // If a hook was provided get the computed value from there
6748 if ( hooks && "get" in hooks ) {
6749 val = hooks.get( elem, true, extra );
6750 }
6751
6752 // Otherwise, if a way to get the computed value exists, use that
6753 if ( val === undefined ) {
6754 val = curCSS( elem, name, styles );
6755 }
6756
6757 //convert "normal" to computed value
6758 if ( val === "normal" && name in cssNormalTransform ) {
6759 val = cssNormalTransform[ name ];
6760 }
6761
6762 // Return, converting to number if forced or a qualifier was provided and val looks numeric
6763 if ( extra === "" || extra ) {
6764 num = parseFloat( val );
6765 return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
6766 }
6767 return val;
6768 }
6769 });
6770
6771 jQuery.each([ "height", "width" ], function( i, name ) {
6772 jQuery.cssHooks[ name ] = {
6773 get: function( elem, computed, extra ) {
6774 if ( computed ) {
6775 // certain elements can have dimension info if we invisibly show them
6776 // however, it must have a current display style that would benefit from this
6777 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
6778 jQuery.swap( elem, cssShow, function() {
6779 return getWidthOrHeight( elem, name, extra );
6780 }) :
6781 getWidthOrHeight( elem, name, extra );
6782 }
6783 },
6784
6785 set: function( elem, value, extra ) {
6786 var styles = extra && getStyles( elem );
6787 return setPositiveNumber( elem, value, extra ?
6788 augmentWidthOrHeight(
6789 elem,
6790 name,
6791 extra,
6792 support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6793 styles
6794 ) : 0
6795 );
6796 }
6797 };
6798 });
6799
6800 if ( !support.opacity ) {
6801 jQuery.cssHooks.opacity = {
6802 get: function( elem, computed ) {
6803 // IE uses filters for opacity
6804 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6805 ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
6806 computed ? "1" : "";
6807 },
6808
6809 set: function( elem, value ) {
6810 var style = elem.style,
6811 currentStyle = elem.currentStyle,
6812 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
6813 filter = currentStyle && currentStyle.filter || style.filter || "";
6814
6815 // IE has trouble with opacity if it does not have layout
6816 // Force it by setting the zoom level
6817 style.zoom = 1;
6818
6819 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6820 // if value === "", then remove inline opacity #12685
6821 if ( ( value >= 1 || value === "" ) &&
6822 jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
6823 style.removeAttribute ) {
6824
6825 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6826 // if "filter:" is present at all, clearType is disabled, we want to avoid this
6827 // style.removeAttribute is IE Only, but so apparently is this code path...
6828 style.removeAttribute( "filter" );
6829
6830 // if there is no filter style applied in a css rule or unset inline opacity, we are done
6831 if ( value === "" || currentStyle && !currentStyle.filter ) {
6832 return;
6833 }
6834 }
6835
6836 // otherwise, set new filter values
6837 style.filter = ralpha.test( filter ) ?
6838 filter.replace( ralpha, opacity ) :
6839 filter + " " + opacity;
6840 }
6841 };
6842 }
6843
6844 jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6845 function( elem, computed ) {
6846 if ( computed ) {
6847 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6848 // Work around by temporarily setting element display to inline-block
6849 return jQuery.swap( elem, { "display": "inline-block" },
6850 curCSS, [ elem, "marginRight" ] );
6851 }
6852 }
6853 );
6854
6855 // These hooks are used by animate to expand properties
6856 jQuery.each({
6857 margin: "",
6858 padding: "",
6859 border: "Width"
6860 }, function( prefix, suffix ) {
6861 jQuery.cssHooks[ prefix + suffix ] = {
6862 expand: function( value ) {
6863 var i = 0,
6864 expanded = {},
6865
6866 // assumes a single number if not a string
6867 parts = typeof value === "string" ? value.split(" ") : [ value ];
6868
6869 for ( ; i < 4; i++ ) {
6870 expanded[ prefix + cssExpand[ i ] + suffix ] =
6871 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6872 }
6873
6874 return expanded;
6875 }
6876 };
6877
6878 if ( !rmargin.test( prefix ) ) {
6879 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6880 }
6881 });
6882
6883 jQuery.fn.extend({
6884 css: function( name, value ) {
6885 return access( this, function( elem, name, value ) {
6886 var styles, len,
6887 map = {},
6888 i = 0;
6889
6890 if ( jQuery.isArray( name ) ) {
6891 styles = getStyles( elem );
6892 len = name.length;
6893
6894 for ( ; i < len; i++ ) {
6895 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6896 }
6897
6898 return map;
6899 }
6900
6901 return value !== undefined ?
6902 jQuery.style( elem, name, value ) :
6903 jQuery.css( elem, name );
6904 }, name, value, arguments.length > 1 );
6905 },
6906 show: function() {
6907 return showHide( this, true );
6908 },
6909 hide: function() {
6910 return showHide( this );
6911 },
6912 toggle: function( state ) {
6913 if ( typeof state === "boolean" ) {
6914 return state ? this.show() : this.hide();
6915 }
6916
6917 return this.each(function() {
6918 if ( isHidden( this ) ) {
6919 jQuery( this ).show();
6920 } else {
6921 jQuery( this ).hide();
6922 }
6923 });
6924 }
6925 });
6926
6927
6928 function Tween( elem, options, prop, end, easing ) {
6929 return new Tween.prototype.init( elem, options, prop, end, easing );
6930 }
6931 jQuery.Tween = Tween;
6932
6933 Tween.prototype = {
6934 constructor: Tween,
6935 init: function( elem, options, prop, end, easing, unit ) {
6936 this.elem = elem;
6937 this.prop = prop;
6938 this.easing = easing || "swing";
6939 this.options = options;
6940 this.start = this.now = this.cur();
6941 this.end = end;
6942 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6943 },
6944 cur: function() {
6945 var hooks = Tween.propHooks[ this.prop ];
6946
6947 return hooks && hooks.get ?
6948 hooks.get( this ) :
6949 Tween.propHooks._default.get( this );
6950 },
6951 run: function( percent ) {
6952 var eased,
6953 hooks = Tween.propHooks[ this.prop ];
6954
6955 if ( this.options.duration ) {
6956 this.pos = eased = jQuery.easing[ this.easing ](
6957 percent, this.options.duration * percent, 0, 1, this.options.duration
6958 );
6959 } else {
6960 this.pos = eased = percent;
6961 }
6962 this.now = ( this.end - this.start ) * eased + this.start;
6963
6964 if ( this.options.step ) {
6965 this.options.step.call( this.elem, this.now, this );
6966 }
6967
6968 if ( hooks && hooks.set ) {
6969 hooks.set( this );
6970 } else {
6971 Tween.propHooks._default.set( this );
6972 }
6973 return this;
6974 }
6975 };
6976
6977 Tween.prototype.init.prototype = Tween.prototype;
6978
6979 Tween.propHooks = {
6980 _default: {
6981 get: function( tween ) {
6982 var result;
6983
6984 if ( tween.elem[ tween.prop ] != null &&
6985 (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
6986 return tween.elem[ tween.prop ];
6987 }
6988
6989 // passing an empty string as a 3rd parameter to .css will automatically
6990 // attempt a parseFloat and fallback to a string if the parse fails
6991 // so, simple values such as "10px" are parsed to Float.
6992 // complex values such as "rotate(1rad)" are returned as is.
6993 result = jQuery.css( tween.elem, tween.prop, "" );
6994 // Empty strings, null, undefined and "auto" are converted to 0.
6995 return !result || result === "auto" ? 0 : result;
6996 },
6997 set: function( tween ) {
6998 // use step hook for back compat - use cssHook if its there - use .style if its
6999 // available and use plain properties where available
7000 if ( jQuery.fx.step[ tween.prop ] ) {
7001 jQuery.fx.step[ tween.prop ]( tween );
7002 } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
7003 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7004 } else {
7005 tween.elem[ tween.prop ] = tween.now;
7006 }
7007 }
7008 }
7009 };
7010
7011 // Support: IE <=9
7012 // Panic based approach to setting things on disconnected nodes
7013
7014 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7015 set: function( tween ) {
7016 if ( tween.elem.nodeType && tween.elem.parentNode ) {
7017 tween.elem[ tween.prop ] = tween.now;
7018 }
7019 }
7020 };
7021
7022 jQuery.easing = {
7023 linear: function( p ) {
7024 return p;
7025 },
7026 swing: function( p ) {
7027 return 0.5 - Math.cos( p * Math.PI ) / 2;
7028 }
7029 };
7030
7031 jQuery.fx = Tween.prototype.init;
7032
7033 // Back Compat <1.8 extension point
7034 jQuery.fx.step = {};
7035
7036
7037
7038
7039 var
7040 fxNow, timerId,
7041 rfxtypes = /^(?:toggle|show|hide)$/,
7042 rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
7043 rrun = /queueHooks$/,
7044 animationPrefilters = [ defaultPrefilter ],
7045 tweeners = {
7046 "*": [ function( prop, value ) {
7047 var tween = this.createTween( prop, value ),
7048 target = tween.cur(),
7049 parts = rfxnum.exec( value ),
7050 unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
7051
7052 // Starting value computation is required for potential unit mismatches
7053 start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
7054 rfxnum.exec( jQuery.css( tween.elem, prop ) ),
7055 scale = 1,
7056 maxIterations = 20;
7057
7058 if ( start && start[ 3 ] !== unit ) {
7059 // Trust units reported by jQuery.css
7060 unit = unit || start[ 3 ];
7061
7062 // Make sure we update the tween properties later on
7063 parts = parts || [];
7064
7065 // Iteratively approximate from a nonzero starting point
7066 start = +target || 1;
7067
7068 do {
7069 // If previous iteration zeroed out, double until we get *something*
7070 // Use a string for doubling factor so we don't accidentally see scale as unchanged below
7071 scale = scale || ".5";
7072
7073 // Adjust and apply
7074 start = start / scale;
7075 jQuery.style( tween.elem, prop, start + unit );
7076
7077 // Update scale, tolerating zero or NaN from tween.cur()
7078 // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
7079 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
7080 }
7081
7082 // Update tween properties
7083 if ( parts ) {
7084 start = tween.start = +start || +target || 0;
7085 tween.unit = unit;
7086 // If a +=/-= token was provided, we're doing a relative animation
7087 tween.end = parts[ 1 ] ?
7088 start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
7089 +parts[ 2 ];
7090 }
7091
7092 return tween;
7093 } ]
7094 };
7095
7096 // Animations created synchronously will run synchronously
7097 function createFxNow() {
7098 setTimeout(function() {
7099 fxNow = undefined;
7100 });
7101 return ( fxNow = jQuery.now() );
7102 }
7103
7104 // Generate parameters to create a standard animation
7105 function genFx( type, includeWidth ) {
7106 var which,
7107 attrs = { height: type },
7108 i = 0;
7109
7110 // if we include width, step value is 1 to do all cssExpand values,
7111 // if we don't include width, step value is 2 to skip over Left and Right
7112 includeWidth = includeWidth ? 1 : 0;
7113 for ( ; i < 4 ; i += 2 - includeWidth ) {
7114 which = cssExpand[ i ];
7115 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7116 }
7117
7118 if ( includeWidth ) {
7119 attrs.opacity = attrs.width = type;
7120 }
7121
7122 return attrs;
7123 }
7124
7125 function createTween( value, prop, animation ) {
7126 var tween,
7127 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
7128 index = 0,
7129 length = collection.length;
7130 for ( ; index < length; index++ ) {
7131 if ( (tween = collection[ index ].call( animation, prop, value )) ) {
7132
7133 // we're done with this property
7134 return tween;
7135 }
7136 }
7137 }
7138
7139 function defaultPrefilter( elem, props, opts ) {
7140 /* jshint validthis: true */
7141 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
7142 anim = this,
7143 orig = {},
7144 style = elem.style,
7145 hidden = elem.nodeType && isHidden( elem ),
7146 dataShow = jQuery._data( elem, "fxshow" );
7147
7148 // handle queue: false promises
7149 if ( !opts.queue ) {
7150 hooks = jQuery._queueHooks( elem, "fx" );
7151 if ( hooks.unqueued == null ) {
7152 hooks.unqueued = 0;
7153 oldfire = hooks.empty.fire;
7154 hooks.empty.fire = function() {
7155 if ( !hooks.unqueued ) {
7156 oldfire();
7157 }
7158 };
7159 }
7160 hooks.unqueued++;
7161
7162 anim.always(function() {
7163 // doing this makes sure that the complete handler will be called
7164 // before this completes
7165 anim.always(function() {
7166 hooks.unqueued--;
7167 if ( !jQuery.queue( elem, "fx" ).length ) {
7168 hooks.empty.fire();
7169 }
7170 });
7171 });
7172 }
7173
7174 // height/width overflow pass
7175 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
7176 // Make sure that nothing sneaks out
7177 // Record all 3 overflow attributes because IE does not
7178 // change the overflow attribute when overflowX and
7179 // overflowY are set to the same value
7180 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7181
7182 // Set display property to inline-block for height/width
7183 // animations on inline elements that are having width/height animated
7184 display = jQuery.css( elem, "display" );
7185
7186 // Test default display if display is currently "none"
7187 checkDisplay = display === "none" ?
7188 jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
7189
7190 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
7191
7192 // inline-level elements accept inline-block;
7193 // block-level elements need to be inline with layout
7194 if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
7195 style.display = "inline-block";
7196 } else {
7197 style.zoom = 1;
7198 }
7199 }
7200 }
7201
7202 if ( opts.overflow ) {
7203 style.overflow = "hidden";
7204 if ( !support.shrinkWrapBlocks() ) {
7205 anim.always(function() {
7206 style.overflow = opts.overflow[ 0 ];
7207 style.overflowX = opts.overflow[ 1 ];
7208 style.overflowY = opts.overflow[ 2 ];
7209 });
7210 }
7211 }
7212
7213 // show/hide pass
7214 for ( prop in props ) {
7215 value = props[ prop ];
7216 if ( rfxtypes.exec( value ) ) {
7217 delete props[ prop ];
7218 toggle = toggle || value === "toggle";
7219 if ( value === ( hidden ? "hide" : "show" ) ) {
7220
7221 // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
7222 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7223 hidden = true;
7224 } else {
7225 continue;
7226 }
7227 }
7228 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7229
7230 // Any non-fx value stops us from restoring the original display value
7231 } else {
7232 display = undefined;
7233 }
7234 }
7235
7236 if ( !jQuery.isEmptyObject( orig ) ) {
7237 if ( dataShow ) {
7238 if ( "hidden" in dataShow ) {
7239 hidden = dataShow.hidden;
7240 }
7241 } else {
7242 dataShow = jQuery._data( elem, "fxshow", {} );
7243 }
7244
7245 // store state if its toggle - enables .stop().toggle() to "reverse"
7246 if ( toggle ) {
7247 dataShow.hidden = !hidden;
7248 }
7249 if ( hidden ) {
7250 jQuery( elem ).show();
7251 } else {
7252 anim.done(function() {
7253 jQuery( elem ).hide();
7254 });
7255 }
7256 anim.done(function() {
7257 var prop;
7258 jQuery._removeData( elem, "fxshow" );
7259 for ( prop in orig ) {
7260 jQuery.style( elem, prop, orig[ prop ] );
7261 }
7262 });
7263 for ( prop in orig ) {
7264 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7265
7266 if ( !( prop in dataShow ) ) {
7267 dataShow[ prop ] = tween.start;
7268 if ( hidden ) {
7269 tween.end = tween.start;
7270 tween.start = prop === "width" || prop === "height" ? 1 : 0;
7271 }
7272 }
7273 }
7274
7275 // If this is a noop like .hide().hide(), restore an overwritten display value
7276 } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
7277 style.display = display;
7278 }
7279 }
7280
7281 function propFilter( props, specialEasing ) {
7282 var index, name, easing, value, hooks;
7283
7284 // camelCase, specialEasing and expand cssHook pass
7285 for ( index in props ) {
7286 name = jQuery.camelCase( index );
7287 easing = specialEasing[ name ];
7288 value = props[ index ];
7289 if ( jQuery.isArray( value ) ) {
7290 easing = value[ 1 ];
7291 value = props[ index ] = value[ 0 ];
7292 }
7293
7294 if ( index !== name ) {
7295 props[ name ] = value;
7296 delete props[ index ];
7297 }
7298
7299 hooks = jQuery.cssHooks[ name ];
7300 if ( hooks && "expand" in hooks ) {
7301 value = hooks.expand( value );
7302 delete props[ name ];
7303
7304 // not quite $.extend, this wont overwrite keys already present.
7305 // also - reusing 'index' from above because we have the correct "name"
7306 for ( index in value ) {
7307 if ( !( index in props ) ) {
7308 props[ index ] = value[ index ];
7309 specialEasing[ index ] = easing;
7310 }
7311 }
7312 } else {
7313 specialEasing[ name ] = easing;
7314 }
7315 }
7316 }
7317
7318 function Animation( elem, properties, options ) {
7319 var result,
7320 stopped,
7321 index = 0,
7322 length = animationPrefilters.length,
7323 deferred = jQuery.Deferred().always( function() {
7324 // don't match elem in the :animated selector
7325 delete tick.elem;
7326 }),
7327 tick = function() {
7328 if ( stopped ) {
7329 return false;
7330 }
7331 var currentTime = fxNow || createFxNow(),
7332 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7333 // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
7334 temp = remaining / animation.duration || 0,
7335 percent = 1 - temp,
7336 index = 0,
7337 length = animation.tweens.length;
7338
7339 for ( ; index < length ; index++ ) {
7340 animation.tweens[ index ].run( percent );
7341 }
7342
7343 deferred.notifyWith( elem, [ animation, percent, remaining ]);
7344
7345 if ( percent < 1 && length ) {
7346 return remaining;
7347 } else {
7348 deferred.resolveWith( elem, [ animation ] );
7349 return false;
7350 }
7351 },
7352 animation = deferred.promise({
7353 elem: elem,
7354 props: jQuery.extend( {}, properties ),
7355 opts: jQuery.extend( true, { specialEasing: {} }, options ),
7356 originalProperties: properties,
7357 originalOptions: options,
7358 startTime: fxNow || createFxNow(),
7359 duration: options.duration,
7360 tweens: [],
7361 createTween: function( prop, end ) {
7362 var tween = jQuery.Tween( elem, animation.opts, prop, end,
7363 animation.opts.specialEasing[ prop ] || animation.opts.easing );
7364 animation.tweens.push( tween );
7365 return tween;
7366 },
7367 stop: function( gotoEnd ) {
7368 var index = 0,
7369 // if we are going to the end, we want to run all the tweens
7370 // otherwise we skip this part
7371 length = gotoEnd ? animation.tweens.length : 0;
7372 if ( stopped ) {
7373 return this;
7374 }
7375 stopped = true;
7376 for ( ; index < length ; index++ ) {
7377 animation.tweens[ index ].run( 1 );
7378 }
7379
7380 // resolve when we played the last frame
7381 // otherwise, reject
7382 if ( gotoEnd ) {
7383 deferred.resolveWith( elem, [ animation, gotoEnd ] );
7384 } else {
7385 deferred.rejectWith( elem, [ animation, gotoEnd ] );
7386 }
7387 return this;
7388 }
7389 }),
7390 props = animation.props;
7391
7392 propFilter( props, animation.opts.specialEasing );
7393
7394 for ( ; index < length ; index++ ) {
7395 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
7396 if ( result ) {
7397 return result;
7398 }
7399 }
7400
7401 jQuery.map( props, createTween, animation );
7402
7403 if ( jQuery.isFunction( animation.opts.start ) ) {
7404 animation.opts.start.call( elem, animation );
7405 }
7406
7407 jQuery.fx.timer(
7408 jQuery.extend( tick, {
7409 elem: elem,
7410 anim: animation,
7411 queue: animation.opts.queue
7412 })
7413 );
7414
7415 // attach callbacks from options
7416 return animation.progress( animation.opts.progress )
7417 .done( animation.opts.done, animation.opts.complete )
7418 .fail( animation.opts.fail )
7419 .always( animation.opts.always );
7420 }
7421
7422 jQuery.Animation = jQuery.extend( Animation, {
7423 tweener: function( props, callback ) {
7424 if ( jQuery.isFunction( props ) ) {
7425 callback = props;
7426 props = [ "*" ];
7427 } else {
7428 props = props.split(" ");
7429 }
7430
7431 var prop,
7432 index = 0,
7433 length = props.length;
7434
7435 for ( ; index < length ; index++ ) {
7436 prop = props[ index ];
7437 tweeners[ prop ] = tweeners[ prop ] || [];
7438 tweeners[ prop ].unshift( callback );
7439 }
7440 },
7441
7442 prefilter: function( callback, prepend ) {
7443 if ( prepend ) {
7444 animationPrefilters.unshift( callback );
7445 } else {
7446 animationPrefilters.push( callback );
7447 }
7448 }
7449 });
7450
7451 jQuery.speed = function( speed, easing, fn ) {
7452 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7453 complete: fn || !fn && easing ||
7454 jQuery.isFunction( speed ) && speed,
7455 duration: speed,
7456 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7457 };
7458
7459 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
7460 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
7461
7462 // normalize opt.queue - true/undefined/null -> "fx"
7463 if ( opt.queue == null || opt.queue === true ) {
7464 opt.queue = "fx";
7465 }
7466
7467 // Queueing
7468 opt.old = opt.complete;
7469
7470 opt.complete = function() {
7471 if ( jQuery.isFunction( opt.old ) ) {
7472 opt.old.call( this );
7473 }
7474
7475 if ( opt.queue ) {
7476 jQuery.dequeue( this, opt.queue );
7477 }
7478 };
7479
7480 return opt;
7481 };
7482
7483 jQuery.fn.extend({
7484 fadeTo: function( speed, to, easing, callback ) {
7485
7486 // show any hidden elements after setting opacity to 0
7487 return this.filter( isHidden ).css( "opacity", 0 ).show()
7488
7489 // animate to the value specified
7490 .end().animate({ opacity: to }, speed, easing, callback );
7491 },
7492 animate: function( prop, speed, easing, callback ) {
7493 var empty = jQuery.isEmptyObject( prop ),
7494 optall = jQuery.speed( speed, easing, callback ),
7495 doAnimation = function() {
7496 // Operate on a copy of prop so per-property easing won't be lost
7497 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7498
7499 // Empty animations, or finishing resolves immediately
7500 if ( empty || jQuery._data( this, "finish" ) ) {
7501 anim.stop( true );
7502 }
7503 };
7504 doAnimation.finish = doAnimation;
7505
7506 return empty || optall.queue === false ?
7507 this.each( doAnimation ) :
7508 this.queue( optall.queue, doAnimation );
7509 },
7510 stop: function( type, clearQueue, gotoEnd ) {
7511 var stopQueue = function( hooks ) {
7512 var stop = hooks.stop;
7513 delete hooks.stop;
7514 stop( gotoEnd );
7515 };
7516
7517 if ( typeof type !== "string" ) {
7518 gotoEnd = clearQueue;
7519 clearQueue = type;
7520 type = undefined;
7521 }
7522 if ( clearQueue && type !== false ) {
7523 this.queue( type || "fx", [] );
7524 }
7525
7526 return this.each(function() {
7527 var dequeue = true,
7528 index = type != null && type + "queueHooks",
7529 timers = jQuery.timers,
7530 data = jQuery._data( this );
7531
7532 if ( index ) {
7533 if ( data[ index ] && data[ index ].stop ) {
7534 stopQueue( data[ index ] );
7535 }
7536 } else {
7537 for ( index in data ) {
7538 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7539 stopQueue( data[ index ] );
7540 }
7541 }
7542 }
7543
7544 for ( index = timers.length; index--; ) {
7545 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
7546 timers[ index ].anim.stop( gotoEnd );
7547 dequeue = false;
7548 timers.splice( index, 1 );
7549 }
7550 }
7551
7552 // start the next in the queue if the last step wasn't forced
7553 // timers currently will call their complete callbacks, which will dequeue
7554 // but only if they were gotoEnd
7555 if ( dequeue || !gotoEnd ) {
7556 jQuery.dequeue( this, type );
7557 }
7558 });
7559 },
7560 finish: function( type ) {
7561 if ( type !== false ) {
7562 type = type || "fx";
7563 }
7564 return this.each(function() {
7565 var index,
7566 data = jQuery._data( this ),
7567 queue = data[ type + "queue" ],
7568 hooks = data[ type + "queueHooks" ],
7569 timers = jQuery.timers,
7570 length = queue ? queue.length : 0;
7571
7572 // enable finishing flag on private data
7573 data.finish = true;
7574
7575 // empty the queue first
7576 jQuery.queue( this, type, [] );
7577
7578 if ( hooks && hooks.stop ) {
7579 hooks.stop.call( this, true );
7580 }
7581
7582 // look for any active animations, and finish them
7583 for ( index = timers.length; index--; ) {
7584 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7585 timers[ index ].anim.stop( true );
7586 timers.splice( index, 1 );
7587 }
7588 }
7589
7590 // look for any animations in the old queue and finish them
7591 for ( index = 0; index < length; index++ ) {
7592 if ( queue[ index ] && queue[ index ].finish ) {
7593 queue[ index ].finish.call( this );
7594 }
7595 }
7596
7597 // turn off finishing flag
7598 delete data.finish;
7599 });
7600 }
7601 });
7602
7603 jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
7604 var cssFn = jQuery.fn[ name ];
7605 jQuery.fn[ name ] = function( speed, easing, callback ) {
7606 return speed == null || typeof speed === "boolean" ?
7607 cssFn.apply( this, arguments ) :
7608 this.animate( genFx( name, true ), speed, easing, callback );
7609 };
7610 });
7611
7612 // Generate shortcuts for custom animations
7613 jQuery.each({
7614 slideDown: genFx("show"),
7615 slideUp: genFx("hide"),
7616 slideToggle: genFx("toggle"),
7617 fadeIn: { opacity: "show" },
7618 fadeOut: { opacity: "hide" },
7619 fadeToggle: { opacity: "toggle" }
7620 }, function( name, props ) {
7621 jQuery.fn[ name ] = function( speed, easing, callback ) {
7622 return this.animate( props, speed, easing, callback );
7623 };
7624 });
7625
7626 jQuery.timers = [];
7627 jQuery.fx.tick = function() {
7628 var timer,
7629 timers = jQuery.timers,
7630 i = 0;
7631
7632 fxNow = jQuery.now();
7633
7634 for ( ; i < timers.length; i++ ) {
7635 timer = timers[ i ];
7636 // Checks the timer has not already been removed
7637 if ( !timer() && timers[ i ] === timer ) {
7638 timers.splice( i--, 1 );
7639 }
7640 }
7641
7642 if ( !timers.length ) {
7643 jQuery.fx.stop();
7644 }
7645 fxNow = undefined;
7646 };
7647
7648 jQuery.fx.timer = function( timer ) {
7649 jQuery.timers.push( timer );
7650 if ( timer() ) {
7651 jQuery.fx.start();
7652 } else {
7653 jQuery.timers.pop();
7654 }
7655 };
7656
7657 jQuery.fx.interval = 13;
7658
7659 jQuery.fx.start = function() {
7660 if ( !timerId ) {
7661 timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
7662 }
7663 };
7664
7665 jQuery.fx.stop = function() {
7666 clearInterval( timerId );
7667 timerId = null;
7668 };
7669
7670 jQuery.fx.speeds = {
7671 slow: 600,
7672 fast: 200,
7673 // Default speed
7674 _default: 400
7675 };
7676
7677
7678 // Based off of the plugin by Clint Helfers, with permission.
7679 // http://blindsignals.com/index.php/2009/07/jquery-delay/
7680 jQuery.fn.delay = function( time, type ) {
7681 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7682 type = type || "fx";
7683
7684 return this.queue( type, function( next, hooks ) {
7685 var timeout = setTimeout( next, time );
7686 hooks.stop = function() {
7687 clearTimeout( timeout );
7688 };
7689 });
7690 };
7691
7692
7693 (function() {
7694 // Minified: var a,b,c,d,e
7695 var input, div, select, a, opt;
7696
7697 // Setup
7698 div = document.createElement( "div" );
7699 div.setAttribute( "className", "t" );
7700 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
7701 a = div.getElementsByTagName("a")[ 0 ];
7702
7703 // First batch of tests.
7704 select = document.createElement("select");
7705 opt = select.appendChild( document.createElement("option") );
7706 input = div.getElementsByTagName("input")[ 0 ];
7707
7708 a.style.cssText = "top:1px";
7709
7710 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
7711 support.getSetAttribute = div.className !== "t";
7712
7713 // Get the style information from getAttribute
7714 // (IE uses .cssText instead)
7715 support.style = /top/.test( a.getAttribute("style") );
7716
7717 // Make sure that URLs aren't manipulated
7718 // (IE normalizes it by default)
7719 support.hrefNormalized = a.getAttribute("href") === "/a";
7720
7721 // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
7722 support.checkOn = !!input.value;
7723
7724 // Make sure that a selected-by-default option has a working selected property.
7725 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
7726 support.optSelected = opt.selected;
7727
7728 // Tests for enctype support on a form (#6743)
7729 support.enctype = !!document.createElement("form").enctype;
7730
7731 // Make sure that the options inside disabled selects aren't marked as disabled
7732 // (WebKit marks them as disabled)
7733 select.disabled = true;
7734 support.optDisabled = !opt.disabled;
7735
7736 // Support: IE8 only
7737 // Check if we can trust getAttribute("value")
7738 input = document.createElement( "input" );
7739 input.setAttribute( "value", "" );
7740 support.input = input.getAttribute( "value" ) === "";
7741
7742 // Check if an input maintains its value after becoming a radio
7743 input.value = "t";
7744 input.setAttribute( "type", "radio" );
7745 support.radioValue = input.value === "t";
7746 })();
7747
7748
7749 var rreturn = /\r/g;
7750
7751 jQuery.fn.extend({
7752 val: function( value ) {
7753 var hooks, ret, isFunction,
7754 elem = this[0];
7755
7756 if ( !arguments.length ) {
7757 if ( elem ) {
7758 hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7759
7760 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
7761 return ret;
7762 }
7763
7764 ret = elem.value;
7765
7766 return typeof ret === "string" ?
7767 // handle most common string cases
7768 ret.replace(rreturn, "") :
7769 // handle cases where value is null/undef or number
7770 ret == null ? "" : ret;
7771 }
7772
7773 return;
7774 }
7775
7776 isFunction = jQuery.isFunction( value );
7777
7778 return this.each(function( i ) {
7779 var val;
7780
7781 if ( this.nodeType !== 1 ) {
7782 return;
7783 }
7784
7785 if ( isFunction ) {
7786 val = value.call( this, i, jQuery( this ).val() );
7787 } else {
7788 val = value;
7789 }
7790
7791 // Treat null/undefined as ""; convert numbers to string
7792 if ( val == null ) {
7793 val = "";
7794 } else if ( typeof val === "number" ) {
7795 val += "";
7796 } else if ( jQuery.isArray( val ) ) {
7797 val = jQuery.map( val, function( value ) {
7798 return value == null ? "" : value + "";
7799 });
7800 }
7801
7802 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7803
7804 // If set returns undefined, fall back to normal setting
7805 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
7806 this.value = val;
7807 }
7808 });
7809 }
7810 });
7811
7812 jQuery.extend({
7813 valHooks: {
7814 option: {
7815 get: function( elem ) {
7816 var val = jQuery.find.attr( elem, "value" );
7817 return val != null ?
7818 val :
7819 // Support: IE10-11+
7820 // option.text throws exceptions (#14686, #14858)
7821 jQuery.trim( jQuery.text( elem ) );
7822 }
7823 },
7824 select: {
7825 get: function( elem ) {
7826 var value, option,
7827 options = elem.options,
7828 index = elem.selectedIndex,
7829 one = elem.type === "select-one" || index < 0,
7830 values = one ? null : [],
7831 max = one ? index + 1 : options.length,
7832 i = index < 0 ?
7833 max :
7834 one ? index : 0;
7835
7836 // Loop through all the selected options
7837 for ( ; i < max; i++ ) {
7838 option = options[ i ];
7839
7840 // oldIE doesn't update selected after form reset (#2551)
7841 if ( ( option.selected || i === index ) &&
7842 // Don't return options that are disabled or in a disabled optgroup
7843 ( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
7844 ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7845
7846 // Get the specific value for the option
7847 value = jQuery( option ).val();
7848
7849 // We don't need an array for one selects
7850 if ( one ) {
7851 return value;
7852 }
7853
7854 // Multi-Selects return an array
7855 values.push( value );
7856 }
7857 }
7858
7859 return values;
7860 },
7861
7862 set: function( elem, value ) {
7863 var optionSet, option,
7864 options = elem.options,
7865 values = jQuery.makeArray( value ),
7866 i = options.length;
7867
7868 while ( i-- ) {
7869 option = options[ i ];
7870
7871 if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
7872
7873 // Support: IE6
7874 // When new option element is added to select box we need to
7875 // force reflow of newly added node in order to workaround delay
7876 // of initialization properties
7877 try {
7878 option.selected = optionSet = true;
7879
7880 } catch ( _ ) {
7881
7882 // Will be executed only in IE6
7883 option.scrollHeight;
7884 }
7885
7886 } else {
7887 option.selected = false;
7888 }
7889 }
7890
7891 // Force browsers to behave consistently when non-matching value is set
7892 if ( !optionSet ) {
7893 elem.selectedIndex = -1;
7894 }
7895
7896 return options;
7897 }
7898 }
7899 }
7900 });
7901
7902 // Radios and checkboxes getter/setter
7903 jQuery.each([ "radio", "checkbox" ], function() {
7904 jQuery.valHooks[ this ] = {
7905 set: function( elem, value ) {
7906 if ( jQuery.isArray( value ) ) {
7907 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
7908 }
7909 }
7910 };
7911 if ( !support.checkOn ) {
7912 jQuery.valHooks[ this ].get = function( elem ) {
7913 // Support: Webkit
7914 // "" is returned instead of "on" if a value isn't specified
7915 return elem.getAttribute("value") === null ? "on" : elem.value;
7916 };
7917 }
7918 });
7919
7920
7921
7922
7923 var nodeHook, boolHook,
7924 attrHandle = jQuery.expr.attrHandle,
7925 ruseDefault = /^(?:checked|selected)$/i,
7926 getSetAttribute = support.getSetAttribute,
7927 getSetInput = support.input;
7928
7929 jQuery.fn.extend({
7930 attr: function( name, value ) {
7931 return access( this, jQuery.attr, name, value, arguments.length > 1 );
7932 },
7933
7934 removeAttr: function( name ) {
7935 return this.each(function() {
7936 jQuery.removeAttr( this, name );
7937 });
7938 }
7939 });
7940
7941 jQuery.extend({
7942 attr: function( elem, name, value ) {
7943 var hooks, ret,
7944 nType = elem.nodeType;
7945
7946 // don't get/set attributes on text, comment and attribute nodes
7947 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
7948 return;
7949 }
7950
7951 // Fallback to prop when attributes are not supported
7952 if ( typeof elem.getAttribute === strundefined ) {
7953 return jQuery.prop( elem, name, value );
7954 }
7955
7956 // All attributes are lowercase
7957 // Grab necessary hook if one is defined
7958 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7959 name = name.toLowerCase();
7960 hooks = jQuery.attrHooks[ name ] ||
7961 ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
7962 }
7963
7964 if ( value !== undefined ) {
7965
7966 if ( value === null ) {
7967 jQuery.removeAttr( elem, name );
7968
7969 } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
7970 return ret;
7971
7972 } else {
7973 elem.setAttribute( name, value + "" );
7974 return value;
7975 }
7976
7977 } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
7978 return ret;
7979
7980 } else {
7981 ret = jQuery.find.attr( elem, name );
7982
7983 // Non-existent attributes return null, we normalize to undefined
7984 return ret == null ?
7985 undefined :
7986 ret;
7987 }
7988 },
7989
7990 removeAttr: function( elem, value ) {
7991 var name, propName,
7992 i = 0,
7993 attrNames = value && value.match( rnotwhite );
7994
7995 if ( attrNames && elem.nodeType === 1 ) {
7996 while ( (name = attrNames[i++]) ) {
7997 propName = jQuery.propFix[ name ] || name;
7998
7999 // Boolean attributes get special treatment (#10870)
8000 if ( jQuery.expr.match.bool.test( name ) ) {
8001 // Set corresponding property to false
8002 if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8003 elem[ propName ] = false;
8004 // Support: IE<9
8005 // Also clear defaultChecked/defaultSelected (if appropriate)
8006 } else {
8007 elem[ jQuery.camelCase( "default-" + name ) ] =
8008 elem[ propName ] = false;
8009 }
8010
8011 // See #9699 for explanation of this approach (setting first, then removal)
8012 } else {
8013 jQuery.attr( elem, name, "" );
8014 }
8015
8016 elem.removeAttribute( getSetAttribute ? name : propName );
8017 }
8018 }
8019 },
8020
8021 attrHooks: {
8022 type: {
8023 set: function( elem, value ) {
8024 if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
8025 // Setting the type on a radio button after the value resets the value in IE6-9
8026 // Reset value to default in case type is set after value during creation
8027 var val = elem.value;
8028 elem.setAttribute( "type", value );
8029 if ( val ) {
8030 elem.value = val;
8031 }
8032 return value;
8033 }
8034 }
8035 }
8036 }
8037 });
8038
8039 // Hook for boolean attributes
8040 boolHook = {
8041 set: function( elem, value, name ) {
8042 if ( value === false ) {
8043 // Remove boolean attributes when set to false
8044 jQuery.removeAttr( elem, name );
8045 } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8046 // IE<8 needs the *property* name
8047 elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
8048
8049 // Use defaultChecked and defaultSelected for oldIE
8050 } else {
8051 elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
8052 }
8053
8054 return name;
8055 }
8056 };
8057
8058 // Retrieve booleans specially
8059 jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
8060
8061 var getter = attrHandle[ name ] || jQuery.find.attr;
8062
8063 attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
8064 function( elem, name, isXML ) {
8065 var ret, handle;
8066 if ( !isXML ) {
8067 // Avoid an infinite loop by temporarily removing this function from the getter
8068 handle = attrHandle[ name ];
8069 attrHandle[ name ] = ret;
8070 ret = getter( elem, name, isXML ) != null ?
8071 name.toLowerCase() :
8072 null;
8073 attrHandle[ name ] = handle;
8074 }
8075 return ret;
8076 } :
8077 function( elem, name, isXML ) {
8078 if ( !isXML ) {
8079 return elem[ jQuery.camelCase( "default-" + name ) ] ?
8080 name.toLowerCase() :
8081 null;
8082 }
8083 };
8084 });
8085
8086 // fix oldIE attroperties
8087 if ( !getSetInput || !getSetAttribute ) {
8088 jQuery.attrHooks.value = {
8089 set: function( elem, value, name ) {
8090 if ( jQuery.nodeName( elem, "input" ) ) {
8091 // Does not return so that setAttribute is also used
8092 elem.defaultValue = value;
8093 } else {
8094 // Use nodeHook if defined (#1954); otherwise setAttribute is fine
8095 return nodeHook && nodeHook.set( elem, value, name );
8096 }
8097 }
8098 };
8099 }
8100
8101 // IE6/7 do not support getting/setting some attributes with get/setAttribute
8102 if ( !getSetAttribute ) {
8103
8104 // Use this for any attribute in IE6/7
8105 // This fixes almost every IE6/7 issue
8106 nodeHook = {
8107 set: function( elem, value, name ) {
8108 // Set the existing or create a new attribute node
8109 var ret = elem.getAttributeNode( name );
8110 if ( !ret ) {
8111 elem.setAttributeNode(
8112 (ret = elem.ownerDocument.createAttribute( name ))
8113 );
8114 }
8115
8116 ret.value = value += "";
8117
8118 // Break association with cloned elements by also using setAttribute (#9646)
8119 if ( name === "value" || value === elem.getAttribute( name ) ) {
8120 return value;
8121 }
8122 }
8123 };
8124
8125 // Some attributes are constructed with empty-string values when not defined
8126 attrHandle.id = attrHandle.name = attrHandle.coords =
8127 function( elem, name, isXML ) {
8128 var ret;
8129 if ( !isXML ) {
8130 return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
8131 ret.value :
8132 null;
8133 }
8134 };
8135
8136 // Fixing value retrieval on a button requires this module
8137 jQuery.valHooks.button = {
8138 get: function( elem, name ) {
8139 var ret = elem.getAttributeNode( name );
8140 if ( ret && ret.specified ) {
8141 return ret.value;
8142 }
8143 },
8144 set: nodeHook.set
8145 };
8146
8147 // Set contenteditable to false on removals(#10429)
8148 // Setting to empty string throws an error as an invalid value
8149 jQuery.attrHooks.contenteditable = {
8150 set: function( elem, value, name ) {
8151 nodeHook.set( elem, value === "" ? false : value, name );
8152 }
8153 };
8154
8155 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
8156 // This is for removals
8157 jQuery.each([ "width", "height" ], function( i, name ) {
8158 jQuery.attrHooks[ name ] = {
8159 set: function( elem, value ) {
8160 if ( value === "" ) {
8161 elem.setAttribute( name, "auto" );
8162 return value;
8163 }
8164 }
8165 };
8166 });
8167 }
8168
8169 if ( !support.style ) {
8170 jQuery.attrHooks.style = {
8171 get: function( elem ) {
8172 // Return undefined in the case of empty string
8173 // Note: IE uppercases css property names, but if we were to .toLowerCase()
8174 // .cssText, that would destroy case senstitivity in URL's, like in "background"
8175 return elem.style.cssText || undefined;
8176 },
8177 set: function( elem, value ) {
8178 return ( elem.style.cssText = value + "" );
8179 }
8180 };
8181 }
8182
8183
8184
8185
8186 var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8187 rclickable = /^(?:a|area)$/i;
8188
8189 jQuery.fn.extend({
8190 prop: function( name, value ) {
8191 return access( this, jQuery.prop, name, value, arguments.length > 1 );
8192 },
8193
8194 removeProp: function( name ) {
8195 name = jQuery.propFix[ name ] || name;
8196 return this.each(function() {
8197 // try/catch handles cases where IE balks (such as removing a property on window)
8198 try {
8199 this[ name ] = undefined;
8200 delete this[ name ];
8201 } catch( e ) {}
8202 });
8203 }
8204 });
8205
8206 jQuery.extend({
8207 propFix: {
8208 "for": "htmlFor",
8209 "class": "className"
8210 },
8211
8212 prop: function( elem, name, value ) {
8213 var ret, hooks, notxml,
8214 nType = elem.nodeType;
8215
8216 // don't get/set properties on text, comment and attribute nodes
8217 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
8218 return;
8219 }
8220
8221 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
8222
8223 if ( notxml ) {
8224 // Fix name and attach hooks
8225 name = jQuery.propFix[ name ] || name;
8226 hooks = jQuery.propHooks[ name ];
8227 }
8228
8229 if ( value !== undefined ) {
8230 return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
8231 ret :
8232 ( elem[ name ] = value );
8233
8234 } else {
8235 return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
8236 ret :
8237 elem[ name ];
8238 }
8239 },
8240
8241 propHooks: {
8242 tabIndex: {
8243 get: function( elem ) {
8244 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
8245 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8246 // Use proper attribute retrieval(#12072)
8247 var tabindex = jQuery.find.attr( elem, "tabindex" );
8248
8249 return tabindex ?
8250 parseInt( tabindex, 10 ) :
8251 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
8252 0 :
8253 -1;
8254 }
8255 }
8256 }
8257 });
8258
8259 // Some attributes require a special call on IE
8260 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8261 if ( !support.hrefNormalized ) {
8262 // href/src property should get the full normalized URL (#10299/#12915)
8263 jQuery.each([ "href", "src" ], function( i, name ) {
8264 jQuery.propHooks[ name ] = {
8265 get: function( elem ) {
8266 return elem.getAttribute( name, 4 );
8267 }
8268 };
8269 });
8270 }
8271
8272 // Support: Safari, IE9+
8273 // mis-reports the default selected property of an option
8274 // Accessing the parent's selectedIndex property fixes it
8275 if ( !support.optSelected ) {
8276 jQuery.propHooks.selected = {
8277 get: function( elem ) {
8278 var parent = elem.parentNode;
8279
8280 if ( parent ) {
8281 parent.selectedIndex;
8282
8283 // Make sure that it also works with optgroups, see #5701
8284 if ( parent.parentNode ) {
8285 parent.parentNode.selectedIndex;
8286 }
8287 }
8288 return null;
8289 }
8290 };
8291 }
8292
8293 jQuery.each([
8294 "tabIndex",
8295 "readOnly",
8296 "maxLength",
8297 "cellSpacing",
8298 "cellPadding",
8299 "rowSpan",
8300 "colSpan",
8301 "useMap",
8302 "frameBorder",
8303 "contentEditable"
8304 ], function() {
8305 jQuery.propFix[ this.toLowerCase() ] = this;
8306 });
8307
8308 // IE6/7 call enctype encoding
8309 if ( !support.enctype ) {
8310 jQuery.propFix.enctype = "encoding";
8311 }
8312
8313
8314
8315
8316 var rclass = /[\t\r\n\f]/g;
8317
8318 jQuery.fn.extend({
8319 addClass: function( value ) {
8320 var classes, elem, cur, clazz, j, finalValue,
8321 i = 0,
8322 len = this.length,
8323 proceed = typeof value === "string" && value;
8324
8325 if ( jQuery.isFunction( value ) ) {
8326 return this.each(function( j ) {
8327 jQuery( this ).addClass( value.call( this, j, this.className ) );
8328 });
8329 }
8330
8331 if ( proceed ) {
8332 // The disjunction here is for better compressibility (see removeClass)
8333 classes = ( value || "" ).match( rnotwhite ) || [];
8334
8335 for ( ; i < len; i++ ) {
8336 elem = this[ i ];
8337 cur = elem.nodeType === 1 && ( elem.className ?
8338 ( " " + elem.className + " " ).replace( rclass, " " ) :
8339 " "
8340 );
8341
8342 if ( cur ) {
8343 j = 0;
8344 while ( (clazz = classes[j++]) ) {
8345 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8346 cur += clazz + " ";
8347 }
8348 }
8349
8350 // only assign if different to avoid unneeded rendering.
8351 finalValue = jQuery.trim( cur );
8352 if ( elem.className !== finalValue ) {
8353 elem.className = finalValue;
8354 }
8355 }
8356 }
8357 }
8358
8359 return this;
8360 },
8361
8362 removeClass: function( value ) {
8363 var classes, elem, cur, clazz, j, finalValue,
8364 i = 0,
8365 len = this.length,
8366 proceed = arguments.length === 0 || typeof value === "string" && value;
8367
8368 if ( jQuery.isFunction( value ) ) {
8369 return this.each(function( j ) {
8370 jQuery( this ).removeClass( value.call( this, j, this.className ) );
8371 });
8372 }
8373 if ( proceed ) {
8374 classes = ( value || "" ).match( rnotwhite ) || [];
8375
8376 for ( ; i < len; i++ ) {
8377 elem = this[ i ];
8378 // This expression is here for better compressibility (see addClass)
8379 cur = elem.nodeType === 1 && ( elem.className ?
8380 ( " " + elem.className + " " ).replace( rclass, " " ) :
8381 ""
8382 );
8383
8384 if ( cur ) {
8385 j = 0;
8386 while ( (clazz = classes[j++]) ) {
8387 // Remove *all* instances
8388 while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
8389 cur = cur.replace( " " + clazz + " ", " " );
8390 }
8391 }
8392
8393 // only assign if different to avoid unneeded rendering.
8394 finalValue = value ? jQuery.trim( cur ) : "";
8395 if ( elem.className !== finalValue ) {
8396 elem.className = finalValue;
8397 }
8398 }
8399 }
8400 }
8401
8402 return this;
8403 },
8404
8405 toggleClass: function( value, stateVal ) {
8406 var type = typeof value;
8407
8408 if ( typeof stateVal === "boolean" && type === "string" ) {
8409 return stateVal ? this.addClass( value ) : this.removeClass( value );
8410 }
8411
8412 if ( jQuery.isFunction( value ) ) {
8413 return this.each(function( i ) {
8414 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
8415 });
8416 }
8417
8418 return this.each(function() {
8419 if ( type === "string" ) {
8420 // toggle individual class names
8421 var className,
8422 i = 0,
8423 self = jQuery( this ),
8424 classNames = value.match( rnotwhite ) || [];
8425
8426 while ( (className = classNames[ i++ ]) ) {
8427 // check each className given, space separated list
8428 if ( self.hasClass( className ) ) {
8429 self.removeClass( className );
8430 } else {
8431 self.addClass( className );
8432 }
8433 }
8434
8435 // Toggle whole class name
8436 } else if ( type === strundefined || type === "boolean" ) {
8437 if ( this.className ) {
8438 // store className if set
8439 jQuery._data( this, "__className__", this.className );
8440 }
8441
8442 // If the element has a class name or if we're passed "false",
8443 // then remove the whole classname (if there was one, the above saved it).
8444 // Otherwise bring back whatever was previously saved (if anything),
8445 // falling back to the empty string if nothing was stored.
8446 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
8447 }
8448 });
8449 },
8450
8451 hasClass: function( selector ) {
8452 var className = " " + selector + " ",
8453 i = 0,
8454 l = this.length;
8455 for ( ; i < l; i++ ) {
8456 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
8457 return true;
8458 }
8459 }
8460
8461 return false;
8462 }
8463 });
8464
8465
8466
8467
8468 // Return jQuery for attributes-only inclusion
8469
8470
8471 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
8472 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8473 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
8474
8475 // Handle event binding
8476 jQuery.fn[ name ] = function( data, fn ) {
8477 return arguments.length > 0 ?
8478 this.on( name, null, data, fn ) :
8479 this.trigger( name );
8480 };
8481 });
8482
8483 jQuery.fn.extend({
8484 hover: function( fnOver, fnOut ) {
8485 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8486 },
8487
8488 bind: function( types, data, fn ) {
8489 return this.on( types, null, data, fn );
8490 },
8491 unbind: function( types, fn ) {
8492 return this.off( types, null, fn );
8493 },
8494
8495 delegate: function( selector, types, data, fn ) {
8496 return this.on( types, selector, data, fn );
8497 },
8498 undelegate: function( selector, types, fn ) {
8499 // ( namespace ) or ( selector, types [, fn] )
8500 return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
8501 }
8502 });
8503
8504
8505 var nonce = jQuery.now();
8506
8507 var rquery = (/\?/);
8508
8509
8510
8511 var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
8512
8513 jQuery.parseJSON = function( data ) {
8514 // Attempt to parse using the native JSON parser first
8515 if ( window.JSON && window.JSON.parse ) {
8516 // Support: Android 2.3
8517 // Workaround failure to string-cast null input
8518 return window.JSON.parse( data + "" );
8519 }
8520
8521 var requireNonComma,
8522 depth = null,
8523 str = jQuery.trim( data + "" );
8524
8525 // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
8526 // after removing valid tokens
8527 return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
8528
8529 // Force termination if we see a misplaced comma
8530 if ( requireNonComma && comma ) {
8531 depth = 0;
8532 }
8533
8534 // Perform no more replacements after returning to outermost depth
8535 if ( depth === 0 ) {
8536 return token;
8537 }
8538
8539 // Commas must not follow "[", "{", or ","
8540 requireNonComma = open || comma;
8541
8542 // Determine new depth
8543 // array/object open ("[" or "{"): depth += true - false (increment)
8544 // array/object close ("]" or "}"): depth += false - true (decrement)
8545 // other cases ("," or primitive): depth += true - true (numeric cast)
8546 depth += !close - !open;
8547
8548 // Remove this token
8549 return "";
8550 }) ) ?
8551 ( Function( "return " + str ) )() :
8552 jQuery.error( "Invalid JSON: " + data );
8553 };
8554
8555
8556 // Cross-browser xml parsing
8557 jQuery.parseXML = function( data ) {
8558 var xml, tmp;
8559 if ( !data || typeof data !== "string" ) {
8560 return null;
8561 }
8562 try {
8563 if ( window.DOMParser ) { // Standard
8564 tmp = new DOMParser();
8565 xml = tmp.parseFromString( data, "text/xml" );
8566 } else { // IE
8567 xml = new ActiveXObject( "Microsoft.XMLDOM" );
8568 xml.async = "false";
8569 xml.loadXML( data );
8570 }
8571 } catch( e ) {
8572 xml = undefined;
8573 }
8574 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
8575 jQuery.error( "Invalid XML: " + data );
8576 }
8577 return xml;
8578 };
8579
8580
8581 var
8582 // Document location
8583 ajaxLocParts,
8584 ajaxLocation,
8585
8586 rhash = /#.*$/,
8587 rts = /([?&])_=[^&]*/,
8588 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
8589 // #7653, #8125, #8152: local protocol detection
8590 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8591 rnoContent = /^(?:GET|HEAD)$/,
8592 rprotocol = /^\/\//,
8593 rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
8594
8595 /* Prefilters
8596 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8597 * 2) These are called:
8598 * - BEFORE asking for a transport
8599 * - AFTER param serialization (s.data is a string if s.processData is true)
8600 * 3) key is the dataType
8601 * 4) the catchall symbol "*" can be used
8602 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8603 */
8604 prefilters = {},
8605
8606 /* Transports bindings
8607 * 1) key is the dataType
8608 * 2) the catchall symbol "*" can be used
8609 * 3) selection will start with transport dataType and THEN go to "*" if needed
8610 */
8611 transports = {},
8612
8613 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8614 allTypes = "*/".concat("*");
8615
8616 // #8138, IE may throw an exception when accessing
8617 // a field from window.location if document.domain has been set
8618 try {
8619 ajaxLocation = location.href;
8620 } catch( e ) {
8621 // Use the href attribute of an A element
8622 // since IE will modify it given document.location
8623 ajaxLocation = document.createElement( "a" );
8624 ajaxLocation.href = "";
8625 ajaxLocation = ajaxLocation.href;
8626 }
8627
8628 // Segment location into parts
8629 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
8630
8631 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8632 function addToPrefiltersOrTransports( structure ) {
8633
8634 // dataTypeExpression is optional and defaults to "*"
8635 return function( dataTypeExpression, func ) {
8636
8637 if ( typeof dataTypeExpression !== "string" ) {
8638 func = dataTypeExpression;
8639 dataTypeExpression = "*";
8640 }
8641
8642 var dataType,
8643 i = 0,
8644 dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
8645
8646 if ( jQuery.isFunction( func ) ) {
8647 // For each dataType in the dataTypeExpression
8648 while ( (dataType = dataTypes[i++]) ) {
8649 // Prepend if requested
8650 if ( dataType.charAt( 0 ) === "+" ) {
8651 dataType = dataType.slice( 1 ) || "*";
8652 (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
8653
8654 // Otherwise append
8655 } else {
8656 (structure[ dataType ] = structure[ dataType ] || []).push( func );
8657 }
8658 }
8659 }
8660 };
8661 }
8662
8663 // Base inspection function for prefilters and transports
8664 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8665
8666 var inspected = {},
8667 seekingTransport = ( structure === transports );
8668
8669 function inspect( dataType ) {
8670 var selected;
8671 inspected[ dataType ] = true;
8672 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8673 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8674 if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8675 options.dataTypes.unshift( dataTypeOrTransport );
8676 inspect( dataTypeOrTransport );
8677 return false;
8678 } else if ( seekingTransport ) {
8679 return !( selected = dataTypeOrTransport );
8680 }
8681 });
8682 return selected;
8683 }
8684
8685 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8686 }
8687
8688 // A special extend for ajax options
8689 // that takes "flat" options (not to be deep extended)
8690 // Fixes #9887
8691 function ajaxExtend( target, src ) {
8692 var deep, key,
8693 flatOptions = jQuery.ajaxSettings.flatOptions || {};
8694
8695 for ( key in src ) {
8696 if ( src[ key ] !== undefined ) {
8697 ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
8698 }
8699 }
8700 if ( deep ) {
8701 jQuery.extend( true, target, deep );
8702 }
8703
8704 return target;
8705 }
8706
8707 /* Handles responses to an ajax request:
8708 * - finds the right dataType (mediates between content-type and expected dataType)
8709 * - returns the corresponding response
8710 */
8711 function ajaxHandleResponses( s, jqXHR, responses ) {
8712 var firstDataType, ct, finalDataType, type,
8713 contents = s.contents,
8714 dataTypes = s.dataTypes;
8715
8716 // Remove auto dataType and get content-type in the process
8717 while ( dataTypes[ 0 ] === "*" ) {
8718 dataTypes.shift();
8719 if ( ct === undefined ) {
8720 ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
8721 }
8722 }
8723
8724 // Check if we're dealing with a known content-type
8725 if ( ct ) {
8726 for ( type in contents ) {
8727 if ( contents[ type ] && contents[ type ].test( ct ) ) {
8728 dataTypes.unshift( type );
8729 break;
8730 }
8731 }
8732 }
8733
8734 // Check to see if we have a response for the expected dataType
8735 if ( dataTypes[ 0 ] in responses ) {
8736 finalDataType = dataTypes[ 0 ];
8737 } else {
8738 // Try convertible dataTypes
8739 for ( type in responses ) {
8740 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
8741 finalDataType = type;
8742 break;
8743 }
8744 if ( !firstDataType ) {
8745 firstDataType = type;
8746 }
8747 }
8748 // Or just use first one
8749 finalDataType = finalDataType || firstDataType;
8750 }
8751
8752 // If we found a dataType
8753 // We add the dataType to the list if needed
8754 // and return the corresponding response
8755 if ( finalDataType ) {
8756 if ( finalDataType !== dataTypes[ 0 ] ) {
8757 dataTypes.unshift( finalDataType );
8758 }
8759 return responses[ finalDataType ];
8760 }
8761 }
8762
8763 /* Chain conversions given the request and the original response
8764 * Also sets the responseXXX fields on the jqXHR instance
8765 */
8766 function ajaxConvert( s, response, jqXHR, isSuccess ) {
8767 var conv2, current, conv, tmp, prev,
8768 converters = {},
8769 // Work with a copy of dataTypes in case we need to modify it for conversion
8770 dataTypes = s.dataTypes.slice();
8771
8772 // Create converters map with lowercased keys
8773 if ( dataTypes[ 1 ] ) {
8774 for ( conv in s.converters ) {
8775 converters[ conv.toLowerCase() ] = s.converters[ conv ];
8776 }
8777 }
8778
8779 current = dataTypes.shift();
8780
8781 // Convert to each sequential dataType
8782 while ( current ) {
8783
8784 if ( s.responseFields[ current ] ) {
8785 jqXHR[ s.responseFields[ current ] ] = response;
8786 }
8787
8788 // Apply the dataFilter if provided
8789 if ( !prev && isSuccess && s.dataFilter ) {
8790 response = s.dataFilter( response, s.dataType );
8791 }
8792
8793 prev = current;
8794 current = dataTypes.shift();
8795
8796 if ( current ) {
8797
8798 // There's only work to do if current dataType is non-auto
8799 if ( current === "*" ) {
8800
8801 current = prev;
8802
8803 // Convert response if prev dataType is non-auto and differs from current
8804 } else if ( prev !== "*" && prev !== current ) {
8805
8806 // Seek a direct converter
8807 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8808
8809 // If none found, seek a pair
8810 if ( !conv ) {
8811 for ( conv2 in converters ) {
8812
8813 // If conv2 outputs current
8814 tmp = conv2.split( " " );
8815 if ( tmp[ 1 ] === current ) {
8816
8817 // If prev can be converted to accepted input
8818 conv = converters[ prev + " " + tmp[ 0 ] ] ||
8819 converters[ "* " + tmp[ 0 ] ];
8820 if ( conv ) {
8821 // Condense equivalence converters
8822 if ( conv === true ) {
8823 conv = converters[ conv2 ];
8824
8825 // Otherwise, insert the intermediate dataType
8826 } else if ( converters[ conv2 ] !== true ) {
8827 current = tmp[ 0 ];
8828 dataTypes.unshift( tmp[ 1 ] );
8829 }
8830 break;
8831 }
8832 }
8833 }
8834 }
8835
8836 // Apply converter (if not an equivalence)
8837 if ( conv !== true ) {
8838
8839 // Unless errors are allowed to bubble, catch and return them
8840 if ( conv && s[ "throws" ] ) {
8841 response = conv( response );
8842 } else {
8843 try {
8844 response = conv( response );
8845 } catch ( e ) {
8846 return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
8847 }
8848 }
8849 }
8850 }
8851 }
8852 }
8853
8854 return { state: "success", data: response };
8855 }
8856
8857 jQuery.extend({
8858
8859 // Counter for holding the number of active queries
8860 active: 0,
8861
8862 // Last-Modified header cache for next request
8863 lastModified: {},
8864 etag: {},
8865
8866 ajaxSettings: {
8867 url: ajaxLocation,
8868 type: "GET",
8869 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
8870 global: true,
8871 processData: true,
8872 async: true,
8873 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8874 /*
8875 timeout: 0,
8876 data: null,
8877 dataType: null,
8878 username: null,
8879 password: null,
8880 cache: null,
8881 throws: false,
8882 traditional: false,
8883 headers: {},
8884 */
8885
8886 accepts: {
8887 "*": allTypes,
8888 text: "text/plain",
8889 html: "text/html",
8890 xml: "application/xml, text/xml",
8891 json: "application/json, text/javascript"
8892 },
8893
8894 contents: {
8895 xml: /xml/,
8896 html: /html/,
8897 json: /json/
8898 },
8899
8900 responseFields: {
8901 xml: "responseXML",
8902 text: "responseText",
8903 json: "responseJSON"
8904 },
8905
8906 // Data converters
8907 // Keys separate source (or catchall "*") and destination types with a single space
8908 converters: {
8909
8910 // Convert anything to text
8911 "* text": String,
8912
8913 // Text to html (true = no transformation)
8914 "text html": true,
8915
8916 // Evaluate text as a json expression
8917 "text json": jQuery.parseJSON,
8918
8919 // Parse text as xml
8920 "text xml": jQuery.parseXML
8921 },
8922
8923 // For options that shouldn't be deep extended:
8924 // you can add your own custom options here if
8925 // and when you create one that shouldn't be
8926 // deep extended (see ajaxExtend)
8927 flatOptions: {
8928 url: true,
8929 context: true
8930 }
8931 },
8932
8933 // Creates a full fledged settings object into target
8934 // with both ajaxSettings and settings fields.
8935 // If target is omitted, writes into ajaxSettings.
8936 ajaxSetup: function( target, settings ) {
8937 return settings ?
8938
8939 // Building a settings object
8940 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8941
8942 // Extending ajaxSettings
8943 ajaxExtend( jQuery.ajaxSettings, target );
8944 },
8945
8946 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8947 ajaxTransport: addToPrefiltersOrTransports( transports ),
8948
8949 // Main method
8950 ajax: function( url, options ) {
8951
8952 // If url is an object, simulate pre-1.5 signature
8953 if ( typeof url === "object" ) {
8954 options = url;
8955 url = undefined;
8956 }
8957
8958 // Force options to be an object
8959 options = options || {};
8960
8961 var // Cross-domain detection vars
8962 parts,
8963 // Loop variable
8964 i,
8965 // URL without anti-cache param
8966 cacheURL,
8967 // Response headers as string
8968 responseHeadersString,
8969 // timeout handle
8970 timeoutTimer,
8971
8972 // To know if global events are to be dispatched
8973 fireGlobals,
8974
8975 transport,
8976 // Response headers
8977 responseHeaders,
8978 // Create the final options object
8979 s = jQuery.ajaxSetup( {}, options ),
8980 // Callbacks context
8981 callbackContext = s.context || s,
8982 // Context for global events is callbackContext if it is a DOM node or jQuery collection
8983 globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
8984 jQuery( callbackContext ) :
8985 jQuery.event,
8986 // Deferreds
8987 deferred = jQuery.Deferred(),
8988 completeDeferred = jQuery.Callbacks("once memory"),
8989 // Status-dependent callbacks
8990 statusCode = s.statusCode || {},
8991 // Headers (they are sent all at once)
8992 requestHeaders = {},
8993 requestHeadersNames = {},
8994 // The jqXHR state
8995 state = 0,
8996 // Default abort message
8997 strAbort = "canceled",
8998 // Fake xhr
8999 jqXHR = {
9000 readyState: 0,
9001
9002 // Builds headers hashtable if needed
9003 getResponseHeader: function( key ) {
9004 var match;
9005 if ( state === 2 ) {
9006 if ( !responseHeaders ) {
9007 responseHeaders = {};
9008 while ( (match = rheaders.exec( responseHeadersString )) ) {
9009 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
9010 }
9011 }
9012 match = responseHeaders[ key.toLowerCase() ];
9013 }
9014 return match == null ? null : match;
9015 },
9016
9017 // Raw string
9018 getAllResponseHeaders: function() {
9019 return state === 2 ? responseHeadersString : null;
9020 },
9021
9022 // Caches the header
9023 setRequestHeader: function( name, value ) {
9024 var lname = name.toLowerCase();
9025 if ( !state ) {
9026 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
9027 requestHeaders[ name ] = value;
9028 }
9029 return this;
9030 },
9031
9032 // Overrides response content-type header
9033 overrideMimeType: function( type ) {
9034 if ( !state ) {
9035 s.mimeType = type;
9036 }
9037 return this;
9038 },
9039
9040 // Status-dependent callbacks
9041 statusCode: function( map ) {
9042 var code;
9043 if ( map ) {
9044 if ( state < 2 ) {
9045 for ( code in map ) {
9046 // Lazy-add the new callback in a way that preserves old ones
9047 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9048 }
9049 } else {
9050 // Execute the appropriate callbacks
9051 jqXHR.always( map[ jqXHR.status ] );
9052 }
9053 }
9054 return this;
9055 },
9056
9057 // Cancel the request
9058 abort: function( statusText ) {
9059 var finalText = statusText || strAbort;
9060 if ( transport ) {
9061 transport.abort( finalText );
9062 }
9063 done( 0, finalText );
9064 return this;
9065 }
9066 };
9067
9068 // Attach deferreds
9069 deferred.promise( jqXHR ).complete = completeDeferred.add;
9070 jqXHR.success = jqXHR.done;
9071 jqXHR.error = jqXHR.fail;
9072
9073 // Remove hash character (#7531: and string promotion)
9074 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
9075 // Handle falsy url in the settings object (#10093: consistency with old signature)
9076 // We also use the url parameter if available
9077 s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
9078
9079 // Alias method option to type as per ticket #12004
9080 s.type = options.method || options.type || s.method || s.type;
9081
9082 // Extract dataTypes list
9083 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
9084
9085 // A cross-domain request is in order when we have a protocol:host:port mismatch
9086 if ( s.crossDomain == null ) {
9087 parts = rurl.exec( s.url.toLowerCase() );
9088 s.crossDomain = !!( parts &&
9089 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
9090 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
9091 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
9092 );
9093 }
9094
9095 // Convert data if not already a string
9096 if ( s.data && s.processData && typeof s.data !== "string" ) {
9097 s.data = jQuery.param( s.data, s.traditional );
9098 }
9099
9100 // Apply prefilters
9101 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9102
9103 // If request was aborted inside a prefilter, stop there
9104 if ( state === 2 ) {
9105 return jqXHR;
9106 }
9107
9108 // We can fire global events as of now if asked to
9109 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9110 fireGlobals = jQuery.event && s.global;
9111
9112 // Watch for a new set of requests
9113 if ( fireGlobals && jQuery.active++ === 0 ) {
9114 jQuery.event.trigger("ajaxStart");
9115 }
9116
9117 // Uppercase the type
9118 s.type = s.type.toUpperCase();
9119
9120 // Determine if request has content
9121 s.hasContent = !rnoContent.test( s.type );
9122
9123 // Save the URL in case we're toying with the If-Modified-Since
9124 // and/or If-None-Match header later on
9125 cacheURL = s.url;
9126
9127 // More options handling for requests with no content
9128 if ( !s.hasContent ) {
9129
9130 // If data is available, append data to url
9131 if ( s.data ) {
9132 cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
9133 // #9682: remove data so that it's not used in an eventual retry
9134 delete s.data;
9135 }
9136
9137 // Add anti-cache in url if needed
9138 if ( s.cache === false ) {
9139 s.url = rts.test( cacheURL ) ?
9140
9141 // If there is already a '_' parameter, set its value
9142 cacheURL.replace( rts, "$1_=" + nonce++ ) :
9143
9144 // Otherwise add one to the end
9145 cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
9146 }
9147 }
9148
9149 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9150 if ( s.ifModified ) {
9151 if ( jQuery.lastModified[ cacheURL ] ) {
9152 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9153 }
9154 if ( jQuery.etag[ cacheURL ] ) {
9155 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9156 }
9157 }
9158
9159 // Set the correct header, if data is being sent
9160 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9161 jqXHR.setRequestHeader( "Content-Type", s.contentType );
9162 }
9163
9164 // Set the Accepts header for the server, depending on the dataType
9165 jqXHR.setRequestHeader(
9166 "Accept",
9167 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
9168 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9169 s.accepts[ "*" ]
9170 );
9171
9172 // Check for headers option
9173 for ( i in s.headers ) {
9174 jqXHR.setRequestHeader( i, s.headers[ i ] );
9175 }
9176
9177 // Allow custom headers/mimetypes and early abort
9178 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
9179 // Abort if not done already and return
9180 return jqXHR.abort();
9181 }
9182
9183 // aborting is no longer a cancellation
9184 strAbort = "abort";
9185
9186 // Install callbacks on deferreds
9187 for ( i in { success: 1, error: 1, complete: 1 } ) {
9188 jqXHR[ i ]( s[ i ] );
9189 }
9190
9191 // Get transport
9192 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9193
9194 // If no transport, we auto-abort
9195 if ( !transport ) {
9196 done( -1, "No Transport" );
9197 } else {
9198 jqXHR.readyState = 1;
9199
9200 // Send global event
9201 if ( fireGlobals ) {
9202 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9203 }
9204 // Timeout
9205 if ( s.async && s.timeout > 0 ) {
9206 timeoutTimer = setTimeout(function() {
9207 jqXHR.abort("timeout");
9208 }, s.timeout );
9209 }
9210
9211 try {
9212 state = 1;
9213 transport.send( requestHeaders, done );
9214 } catch ( e ) {
9215 // Propagate exception as error if not done
9216 if ( state < 2 ) {
9217 done( -1, e );
9218 // Simply rethrow otherwise
9219 } else {
9220 throw e;
9221 }
9222 }
9223 }
9224
9225 // Callback for when everything is done
9226 function done( status, nativeStatusText, responses, headers ) {
9227 var isSuccess, success, error, response, modified,
9228 statusText = nativeStatusText;
9229
9230 // Called once
9231 if ( state === 2 ) {
9232 return;
9233 }
9234
9235 // State is "done" now
9236 state = 2;
9237
9238 // Clear timeout if it exists
9239 if ( timeoutTimer ) {
9240 clearTimeout( timeoutTimer );
9241 }
9242
9243 // Dereference transport for early garbage collection
9244 // (no matter how long the jqXHR object will be used)
9245 transport = undefined;
9246
9247 // Cache response headers
9248 responseHeadersString = headers || "";
9249
9250 // Set readyState
9251 jqXHR.readyState = status > 0 ? 4 : 0;
9252
9253 // Determine if successful
9254 isSuccess = status >= 200 && status < 300 || status === 304;
9255
9256 // Get response data
9257 if ( responses ) {
9258 response = ajaxHandleResponses( s, jqXHR, responses );
9259 }
9260
9261 // Convert no matter what (that way responseXXX fields are always set)
9262 response = ajaxConvert( s, response, jqXHR, isSuccess );
9263
9264 // If successful, handle type chaining
9265 if ( isSuccess ) {
9266
9267 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9268 if ( s.ifModified ) {
9269 modified = jqXHR.getResponseHeader("Last-Modified");
9270 if ( modified ) {
9271 jQuery.lastModified[ cacheURL ] = modified;
9272 }
9273 modified = jqXHR.getResponseHeader("etag");
9274 if ( modified ) {
9275 jQuery.etag[ cacheURL ] = modified;
9276 }
9277 }
9278
9279 // if no content
9280 if ( status === 204 || s.type === "HEAD" ) {
9281 statusText = "nocontent";
9282
9283 // if not modified
9284 } else if ( status === 304 ) {
9285 statusText = "notmodified";
9286
9287 // If we have data, let's convert it
9288 } else {
9289 statusText = response.state;
9290 success = response.data;
9291 error = response.error;
9292 isSuccess = !error;
9293 }
9294 } else {
9295 // We extract error from statusText
9296 // then normalize statusText and status for non-aborts
9297 error = statusText;
9298 if ( status || !statusText ) {
9299 statusText = "error";
9300 if ( status < 0 ) {
9301 status = 0;
9302 }
9303 }
9304 }
9305
9306 // Set data for the fake xhr object
9307 jqXHR.status = status;
9308 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9309
9310 // Success/Error
9311 if ( isSuccess ) {
9312 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9313 } else {
9314 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9315 }
9316
9317 // Status-dependent callbacks
9318 jqXHR.statusCode( statusCode );
9319 statusCode = undefined;
9320
9321 if ( fireGlobals ) {
9322 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9323 [ jqXHR, s, isSuccess ? success : error ] );
9324 }
9325
9326 // Complete
9327 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9328
9329 if ( fireGlobals ) {
9330 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9331 // Handle the global AJAX counter
9332 if ( !( --jQuery.active ) ) {
9333 jQuery.event.trigger("ajaxStop");
9334 }
9335 }
9336 }
9337
9338 return jqXHR;
9339 },
9340
9341 getJSON: function( url, data, callback ) {
9342 return jQuery.get( url, data, callback, "json" );
9343 },
9344
9345 getScript: function( url, callback ) {
9346 return jQuery.get( url, undefined, callback, "script" );
9347 }
9348 });
9349
9350 jQuery.each( [ "get", "post" ], function( i, method ) {
9351 jQuery[ method ] = function( url, data, callback, type ) {
9352 // shift arguments if data argument was omitted
9353 if ( jQuery.isFunction( data ) ) {
9354 type = type || callback;
9355 callback = data;
9356 data = undefined;
9357 }
9358
9359 return jQuery.ajax({
9360 url: url,
9361 type: method,
9362 dataType: type,
9363 data: data,
9364 success: callback
9365 });
9366 };
9367 });
9368
9369
9370 jQuery._evalUrl = function( url ) {
9371 return jQuery.ajax({
9372 url: url,
9373 type: "GET",
9374 dataType: "script",
9375 async: false,
9376 global: false,
9377 "throws": true
9378 });
9379 };
9380
9381
9382 jQuery.fn.extend({
9383 wrapAll: function( html ) {
9384 if ( jQuery.isFunction( html ) ) {
9385 return this.each(function(i) {
9386 jQuery(this).wrapAll( html.call(this, i) );
9387 });
9388 }
9389
9390 if ( this[0] ) {
9391 // The elements to wrap the target around
9392 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
9393
9394 if ( this[0].parentNode ) {
9395 wrap.insertBefore( this[0] );
9396 }
9397
9398 wrap.map(function() {
9399 var elem = this;
9400
9401 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
9402 elem = elem.firstChild;
9403 }
9404
9405 return elem;
9406 }).append( this );
9407 }
9408
9409 return this;
9410 },
9411
9412 wrapInner: function( html ) {
9413 if ( jQuery.isFunction( html ) ) {
9414 return this.each(function(i) {
9415 jQuery(this).wrapInner( html.call(this, i) );
9416 });
9417 }
9418
9419 return this.each(function() {
9420 var self = jQuery( this ),
9421 contents = self.contents();
9422
9423 if ( contents.length ) {
9424 contents.wrapAll( html );
9425
9426 } else {
9427 self.append( html );
9428 }
9429 });
9430 },
9431
9432 wrap: function( html ) {
9433 var isFunction = jQuery.isFunction( html );
9434
9435 return this.each(function(i) {
9436 jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
9437 });
9438 },
9439
9440 unwrap: function() {
9441 return this.parent().each(function() {
9442 if ( !jQuery.nodeName( this, "body" ) ) {
9443 jQuery( this ).replaceWith( this.childNodes );
9444 }
9445 }).end();
9446 }
9447 });
9448
9449
9450 jQuery.expr.filters.hidden = function( elem ) {
9451 // Support: Opera <= 12.12
9452 // Opera reports offsetWidths and offsetHeights less than zero on some elements
9453 return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
9454 (!support.reliableHiddenOffsets() &&
9455 ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
9456 };
9457
9458 jQuery.expr.filters.visible = function( elem ) {
9459 return !jQuery.expr.filters.hidden( elem );
9460 };
9461
9462
9463
9464
9465 var r20 = /%20/g,
9466 rbracket = /\[\]$/,
9467 rCRLF = /\r?\n/g,
9468 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
9469 rsubmittable = /^(?:input|select|textarea|keygen)/i;
9470
9471 function buildParams( prefix, obj, traditional, add ) {
9472 var name;
9473
9474 if ( jQuery.isArray( obj ) ) {
9475 // Serialize array item.
9476 jQuery.each( obj, function( i, v ) {
9477 if ( traditional || rbracket.test( prefix ) ) {
9478 // Treat each array item as a scalar.
9479 add( prefix, v );
9480
9481 } else {
9482 // Item is non-scalar (array or object), encode its numeric index.
9483 buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
9484 }
9485 });
9486
9487 } else if ( !traditional && jQuery.type( obj ) === "object" ) {
9488 // Serialize object item.
9489 for ( name in obj ) {
9490 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
9491 }
9492
9493 } else {
9494 // Serialize scalar item.
9495 add( prefix, obj );
9496 }
9497 }
9498
9499 // Serialize an array of form elements or a set of
9500 // key/values into a query string
9501 jQuery.param = function( a, traditional ) {
9502 var prefix,
9503 s = [],
9504 add = function( key, value ) {
9505 // If value is a function, invoke it and return its value
9506 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
9507 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
9508 };
9509
9510 // Set traditional to true for jQuery <= 1.3.2 behavior.
9511 if ( traditional === undefined ) {
9512 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
9513 }
9514
9515 // If an array was passed in, assume that it is an array of form elements.
9516 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
9517 // Serialize the form elements
9518 jQuery.each( a, function() {
9519 add( this.name, this.value );
9520 });
9521
9522 } else {
9523 // If traditional, encode the "old" way (the way 1.3.2 or older
9524 // did it), otherwise encode params recursively.
9525 for ( prefix in a ) {
9526 buildParams( prefix, a[ prefix ], traditional, add );
9527 }
9528 }
9529
9530 // Return the resulting serialization
9531 return s.join( "&" ).replace( r20, "+" );
9532 };
9533
9534 jQuery.fn.extend({
9535 serialize: function() {
9536 return jQuery.param( this.serializeArray() );
9537 },
9538 serializeArray: function() {
9539 return this.map(function() {
9540 // Can add propHook for "elements" to filter or add form elements
9541 var elements = jQuery.prop( this, "elements" );
9542 return elements ? jQuery.makeArray( elements ) : this;
9543 })
9544 .filter(function() {
9545 var type = this.type;
9546 // Use .is(":disabled") so that fieldset[disabled] works
9547 return this.name && !jQuery( this ).is( ":disabled" ) &&
9548 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9549 ( this.checked || !rcheckableType.test( type ) );
9550 })
9551 .map(function( i, elem ) {
9552 var val = jQuery( this ).val();
9553
9554 return val == null ?
9555 null :
9556 jQuery.isArray( val ) ?
9557 jQuery.map( val, function( val ) {
9558 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9559 }) :
9560 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9561 }).get();
9562 }
9563 });
9564
9565
9566 // Create the request object
9567 // (This is still attached to ajaxSettings for backward compatibility)
9568 jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
9569 // Support: IE6+
9570 function() {
9571
9572 // XHR cannot access local files, always use ActiveX for that case
9573 return !this.isLocal &&
9574
9575 // Support: IE7-8
9576 // oldIE XHR does not support non-RFC2616 methods (#13240)
9577 // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
9578 // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
9579 // Although this check for six methods instead of eight
9580 // since IE also does not support "trace" and "connect"
9581 /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
9582
9583 createStandardXHR() || createActiveXHR();
9584 } :
9585 // For all other browsers, use the standard XMLHttpRequest object
9586 createStandardXHR;
9587
9588 var xhrId = 0,
9589 xhrCallbacks = {},
9590 xhrSupported = jQuery.ajaxSettings.xhr();
9591
9592 // Support: IE<10
9593 // Open requests must be manually aborted on unload (#5280)
9594 // See https://support.microsoft.com/kb/2856746 for more info
9595 if ( window.attachEvent ) {
9596 window.attachEvent( "onunload", function() {
9597 for ( var key in xhrCallbacks ) {
9598 xhrCallbacks[ key ]( undefined, true );
9599 }
9600 });
9601 }
9602
9603 // Determine support properties
9604 support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9605 xhrSupported = support.ajax = !!xhrSupported;
9606
9607 // Create transport if the browser can provide an xhr
9608 if ( xhrSupported ) {
9609
9610 jQuery.ajaxTransport(function( options ) {
9611 // Cross domain only allowed if supported through XMLHttpRequest
9612 if ( !options.crossDomain || support.cors ) {
9613
9614 var callback;
9615
9616 return {
9617 send: function( headers, complete ) {
9618 var i,
9619 xhr = options.xhr(),
9620 id = ++xhrId;
9621
9622 // Open the socket
9623 xhr.open( options.type, options.url, options.async, options.username, options.password );
9624
9625 // Apply custom fields if provided
9626 if ( options.xhrFields ) {
9627 for ( i in options.xhrFields ) {
9628 xhr[ i ] = options.xhrFields[ i ];
9629 }
9630 }
9631
9632 // Override mime type if needed
9633 if ( options.mimeType && xhr.overrideMimeType ) {
9634 xhr.overrideMimeType( options.mimeType );
9635 }
9636
9637 // X-Requested-With header
9638 // For cross-domain requests, seeing as conditions for a preflight are
9639 // akin to a jigsaw puzzle, we simply never set it to be sure.
9640 // (it can always be set on a per-request basis or even using ajaxSetup)
9641 // For same-domain requests, won't change header if already provided.
9642 if ( !options.crossDomain && !headers["X-Requested-With"] ) {
9643 headers["X-Requested-With"] = "XMLHttpRequest";
9644 }
9645
9646 // Set headers
9647 for ( i in headers ) {
9648 // Support: IE<9
9649 // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
9650 // request header to a null-value.
9651 //
9652 // To keep consistent with other XHR implementations, cast the value
9653 // to string and ignore `undefined`.
9654 if ( headers[ i ] !== undefined ) {
9655 xhr.setRequestHeader( i, headers[ i ] + "" );
9656 }
9657 }
9658
9659 // Do send the request
9660 // This may raise an exception which is actually
9661 // handled in jQuery.ajax (so no try/catch here)
9662 xhr.send( ( options.hasContent && options.data ) || null );
9663
9664 // Listener
9665 callback = function( _, isAbort ) {
9666 var status, statusText, responses;
9667
9668 // Was never called and is aborted or complete
9669 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
9670 // Clean up
9671 delete xhrCallbacks[ id ];
9672 callback = undefined;
9673 xhr.onreadystatechange = jQuery.noop;
9674
9675 // Abort manually if needed
9676 if ( isAbort ) {
9677 if ( xhr.readyState !== 4 ) {
9678 xhr.abort();
9679 }
9680 } else {
9681 responses = {};
9682 status = xhr.status;
9683
9684 // Support: IE<10
9685 // Accessing binary-data responseText throws an exception
9686 // (#11426)
9687 if ( typeof xhr.responseText === "string" ) {
9688 responses.text = xhr.responseText;
9689 }
9690
9691 // Firefox throws an exception when accessing
9692 // statusText for faulty cross-domain requests
9693 try {
9694 statusText = xhr.statusText;
9695 } catch( e ) {
9696 // We normalize with Webkit giving an empty statusText
9697 statusText = "";
9698 }
9699
9700 // Filter status for non standard behaviors
9701
9702 // If the request is local and we have data: assume a success
9703 // (success with no data won't get notified, that's the best we
9704 // can do given current implementations)
9705 if ( !status && options.isLocal && !options.crossDomain ) {
9706 status = responses.text ? 200 : 404;
9707 // IE - #1450: sometimes returns 1223 when it should be 204
9708 } else if ( status === 1223 ) {
9709 status = 204;
9710 }
9711 }
9712 }
9713
9714 // Call complete if needed
9715 if ( responses ) {
9716 complete( status, statusText, responses, xhr.getAllResponseHeaders() );
9717 }
9718 };
9719
9720 if ( !options.async ) {
9721 // if we're in sync mode we fire the callback
9722 callback();
9723 } else if ( xhr.readyState === 4 ) {
9724 // (IE6 & IE7) if it's in cache and has been
9725 // retrieved directly we need to fire the callback
9726 setTimeout( callback );
9727 } else {
9728 // Add to the list of active xhr callbacks
9729 xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
9730 }
9731 },
9732
9733 abort: function() {
9734 if ( callback ) {
9735 callback( undefined, true );
9736 }
9737 }
9738 };
9739 }
9740 });
9741 }
9742
9743 // Functions to create xhrs
9744 function createStandardXHR() {
9745 try {
9746 return new window.XMLHttpRequest();
9747 } catch( e ) {}
9748 }
9749
9750 function createActiveXHR() {
9751 try {
9752 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
9753 } catch( e ) {}
9754 }
9755
9756
9757
9758
9759 // Install script dataType
9760 jQuery.ajaxSetup({
9761 accepts: {
9762 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
9763 },
9764 contents: {
9765 script: /(?:java|ecma)script/
9766 },
9767 converters: {
9768 "text script": function( text ) {
9769 jQuery.globalEval( text );
9770 return text;
9771 }
9772 }
9773 });
9774
9775 // Handle cache's special case and global
9776 jQuery.ajaxPrefilter( "script", function( s ) {
9777 if ( s.cache === undefined ) {
9778 s.cache = false;
9779 }
9780 if ( s.crossDomain ) {
9781 s.type = "GET";
9782 s.global = false;
9783 }
9784 });
9785
9786 // Bind script tag hack transport
9787 jQuery.ajaxTransport( "script", function(s) {
9788
9789 // This transport only deals with cross domain requests
9790 if ( s.crossDomain ) {
9791
9792 var script,
9793 head = document.head || jQuery("head")[0] || document.documentElement;
9794
9795 return {
9796
9797 send: function( _, callback ) {
9798
9799 script = document.createElement("script");
9800
9801 script.async = true;
9802
9803 if ( s.scriptCharset ) {
9804 script.charset = s.scriptCharset;
9805 }
9806
9807 script.src = s.url;
9808
9809 // Attach handlers for all browsers
9810 script.onload = script.onreadystatechange = function( _, isAbort ) {
9811
9812 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
9813
9814 // Handle memory leak in IE
9815 script.onload = script.onreadystatechange = null;
9816
9817 // Remove the script
9818 if ( script.parentNode ) {
9819 script.parentNode.removeChild( script );
9820 }
9821
9822 // Dereference the script
9823 script = null;
9824
9825 // Callback if not abort
9826 if ( !isAbort ) {
9827 callback( 200, "success" );
9828 }
9829 }
9830 };
9831
9832 // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
9833 // Use native DOM manipulation to avoid our domManip AJAX trickery
9834 head.insertBefore( script, head.firstChild );
9835 },
9836
9837 abort: function() {
9838 if ( script ) {
9839 script.onload( undefined, true );
9840 }
9841 }
9842 };
9843 }
9844 });
9845
9846
9847
9848
9849 var oldCallbacks = [],
9850 rjsonp = /(=)\?(?=&|$)|\?\?/;
9851
9852 // Default jsonp settings
9853 jQuery.ajaxSetup({
9854 jsonp: "callback",
9855 jsonpCallback: function() {
9856 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9857 this[ callback ] = true;
9858 return callback;
9859 }
9860 });
9861
9862 // Detect, normalize options and install callbacks for jsonp requests
9863 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9864
9865 var callbackName, overwritten, responseContainer,
9866 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9867 "url" :
9868 typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
9869 );
9870
9871 // Handle iff the expected data type is "jsonp" or we have a parameter to set
9872 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9873
9874 // Get callback name, remembering preexisting value associated with it
9875 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9876 s.jsonpCallback() :
9877 s.jsonpCallback;
9878
9879 // Insert callback into url or form data
9880 if ( jsonProp ) {
9881 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9882 } else if ( s.jsonp !== false ) {
9883 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9884 }
9885
9886 // Use data converter to retrieve json after script execution
9887 s.converters["script json"] = function() {
9888 if ( !responseContainer ) {
9889 jQuery.error( callbackName + " was not called" );
9890 }
9891 return responseContainer[ 0 ];
9892 };
9893
9894 // force json dataType
9895 s.dataTypes[ 0 ] = "json";
9896
9897 // Install callback
9898 overwritten = window[ callbackName ];
9899 window[ callbackName ] = function() {
9900 responseContainer = arguments;
9901 };
9902
9903 // Clean-up function (fires after converters)
9904 jqXHR.always(function() {
9905 // Restore preexisting value
9906 window[ callbackName ] = overwritten;
9907
9908 // Save back as free
9909 if ( s[ callbackName ] ) {
9910 // make sure that re-using the options doesn't screw things around
9911 s.jsonpCallback = originalSettings.jsonpCallback;
9912
9913 // save the callback name for future use
9914 oldCallbacks.push( callbackName );
9915 }
9916
9917 // Call if it was a function and we have a response
9918 if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9919 overwritten( responseContainer[ 0 ] );
9920 }
9921
9922 responseContainer = overwritten = undefined;
9923 });
9924
9925 // Delegate to script
9926 return "script";
9927 }
9928 });
9929
9930
9931
9932
9933 // data: string of html
9934 // context (optional): If specified, the fragment will be created in this context, defaults to document
9935 // keepScripts (optional): If true, will include scripts passed in the html string
9936 jQuery.parseHTML = function( data, context, keepScripts ) {
9937 if ( !data || typeof data !== "string" ) {
9938 return null;
9939 }
9940 if ( typeof context === "boolean" ) {
9941 keepScripts = context;
9942 context = false;
9943 }
9944 context = context || document;
9945
9946 var parsed = rsingleTag.exec( data ),
9947 scripts = !keepScripts && [];
9948
9949 // Single tag
9950 if ( parsed ) {
9951 return [ context.createElement( parsed[1] ) ];
9952 }
9953
9954 parsed = jQuery.buildFragment( [ data ], context, scripts );
9955
9956 if ( scripts && scripts.length ) {
9957 jQuery( scripts ).remove();
9958 }
9959
9960 return jQuery.merge( [], parsed.childNodes );
9961 };
9962
9963
9964 // Keep a copy of the old load method
9965 var _load = jQuery.fn.load;
9966
9967 /**
9968 * Load a url into a page
9969 */
9970 jQuery.fn.load = function( url, params, callback ) {
9971 if ( typeof url !== "string" && _load ) {
9972 return _load.apply( this, arguments );
9973 }
9974
9975 var selector, response, type,
9976 self = this,
9977 off = url.indexOf(" ");
9978
9979 if ( off >= 0 ) {
9980 selector = jQuery.trim( url.slice( off, url.length ) );
9981 url = url.slice( 0, off );
9982 }
9983
9984 // If it's a function
9985 if ( jQuery.isFunction( params ) ) {
9986
9987 // We assume that it's the callback
9988 callback = params;
9989 params = undefined;
9990
9991 // Otherwise, build a param string
9992 } else if ( params && typeof params === "object" ) {
9993 type = "POST";
9994 }
9995
9996 // If we have elements to modify, make the request
9997 if ( self.length > 0 ) {
9998 jQuery.ajax({
9999 url: url,
10000
10001 // if "type" variable is undefined, then "GET" method will be used
10002 type: type,
10003 dataType: "html",
10004 data: params
10005 }).done(function( responseText ) {
10006
10007 // Save response for use in complete callback
10008 response = arguments;
10009
10010 self.html( selector ?
10011
10012 // If a selector was specified, locate the right elements in a dummy div
10013 // Exclude scripts to avoid IE 'Permission Denied' errors
10014 jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
10015
10016 // Otherwise use the full result
10017 responseText );
10018
10019 }).complete( callback && function( jqXHR, status ) {
10020 self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
10021 });
10022 }
10023
10024 return this;
10025 };
10026
10027
10028
10029
10030 // Attach a bunch of functions for handling common AJAX events
10031 jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
10032 jQuery.fn[ type ] = function( fn ) {
10033 return this.on( type, fn );
10034 };
10035 });
10036
10037
10038
10039
10040 jQuery.expr.filters.animated = function( elem ) {
10041 return jQuery.grep(jQuery.timers, function( fn ) {
10042 return elem === fn.elem;
10043 }).length;
10044 };
10045
10046
10047
10048
10049
10050 var docElem = window.document.documentElement;
10051
10052 /**
10053 * Gets a window from an element
10054 */
10055 function getWindow( elem ) {
10056 return jQuery.isWindow( elem ) ?
10057 elem :
10058 elem.nodeType === 9 ?
10059 elem.defaultView || elem.parentWindow :
10060 false;
10061 }
10062
10063 jQuery.offset = {
10064 setOffset: function( elem, options, i ) {
10065 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10066 position = jQuery.css( elem, "position" ),
10067 curElem = jQuery( elem ),
10068 props = {};
10069
10070 // set position first, in-case top/left are set even on static elem
10071 if ( position === "static" ) {
10072 elem.style.position = "relative";
10073 }
10074
10075 curOffset = curElem.offset();
10076 curCSSTop = jQuery.css( elem, "top" );
10077 curCSSLeft = jQuery.css( elem, "left" );
10078 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10079 jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
10080
10081 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
10082 if ( calculatePosition ) {
10083 curPosition = curElem.position();
10084 curTop = curPosition.top;
10085 curLeft = curPosition.left;
10086 } else {
10087 curTop = parseFloat( curCSSTop ) || 0;
10088 curLeft = parseFloat( curCSSLeft ) || 0;
10089 }
10090
10091 if ( jQuery.isFunction( options ) ) {
10092 options = options.call( elem, i, curOffset );
10093 }
10094
10095 if ( options.top != null ) {
10096 props.top = ( options.top - curOffset.top ) + curTop;
10097 }
10098 if ( options.left != null ) {
10099 props.left = ( options.left - curOffset.left ) + curLeft;
10100 }
10101
10102 if ( "using" in options ) {
10103 options.using.call( elem, props );
10104 } else {
10105 curElem.css( props );
10106 }
10107 }
10108 };
10109
10110 jQuery.fn.extend({
10111 offset: function( options ) {
10112 if ( arguments.length ) {
10113 return options === undefined ?
10114 this :
10115 this.each(function( i ) {
10116 jQuery.offset.setOffset( this, options, i );
10117 });
10118 }
10119
10120 var docElem, win,
10121 box = { top: 0, left: 0 },
10122 elem = this[ 0 ],
10123 doc = elem && elem.ownerDocument;
10124
10125 if ( !doc ) {
10126 return;
10127 }
10128
10129 docElem = doc.documentElement;
10130
10131 // Make sure it's not a disconnected DOM node
10132 if ( !jQuery.contains( docElem, elem ) ) {
10133 return box;
10134 }
10135
10136 // If we don't have gBCR, just use 0,0 rather than error
10137 // BlackBerry 5, iOS 3 (original iPhone)
10138 if ( typeof elem.getBoundingClientRect !== strundefined ) {
10139 box = elem.getBoundingClientRect();
10140 }
10141 win = getWindow( doc );
10142 return {
10143 top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
10144 left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
10145 };
10146 },
10147
10148 position: function() {
10149 if ( !this[ 0 ] ) {
10150 return;
10151 }
10152
10153 var offsetParent, offset,
10154 parentOffset = { top: 0, left: 0 },
10155 elem = this[ 0 ];
10156
10157 // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
10158 if ( jQuery.css( elem, "position" ) === "fixed" ) {
10159 // we assume that getBoundingClientRect is available when computed position is fixed
10160 offset = elem.getBoundingClientRect();
10161 } else {
10162 // Get *real* offsetParent
10163 offsetParent = this.offsetParent();
10164
10165 // Get correct offsets
10166 offset = this.offset();
10167 if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
10168 parentOffset = offsetParent.offset();
10169 }
10170
10171 // Add offsetParent borders
10172 parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
10173 parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
10174 }
10175
10176 // Subtract parent offsets and element margins
10177 // note: when an element has margin: auto the offsetLeft and marginLeft
10178 // are the same in Safari causing offset.left to incorrectly be 0
10179 return {
10180 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10181 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
10182 };
10183 },
10184
10185 offsetParent: function() {
10186 return this.map(function() {
10187 var offsetParent = this.offsetParent || docElem;
10188
10189 while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
10190 offsetParent = offsetParent.offsetParent;
10191 }
10192 return offsetParent || docElem;
10193 });
10194 }
10195 });
10196
10197 // Create scrollLeft and scrollTop methods
10198 jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10199 var top = /Y/.test( prop );
10200
10201 jQuery.fn[ method ] = function( val ) {
10202 return access( this, function( elem, method, val ) {
10203 var win = getWindow( elem );
10204
10205 if ( val === undefined ) {
10206 return win ? (prop in win) ? win[ prop ] :
10207 win.document.documentElement[ method ] :
10208 elem[ method ];
10209 }
10210
10211 if ( win ) {
10212 win.scrollTo(
10213 !top ? val : jQuery( win ).scrollLeft(),
10214 top ? val : jQuery( win ).scrollTop()
10215 );
10216
10217 } else {
10218 elem[ method ] = val;
10219 }
10220 }, method, val, arguments.length, null );
10221 };
10222 });
10223
10224 // Add the top/left cssHooks using jQuery.fn.position
10225 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10226 // getComputedStyle returns percent when specified for top/left/bottom/right
10227 // rather than make the css module depend on the offset module, we just check for it here
10228 jQuery.each( [ "top", "left" ], function( i, prop ) {
10229 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10230 function( elem, computed ) {
10231 if ( computed ) {
10232 computed = curCSS( elem, prop );
10233 // if curCSS returns percentage, fallback to offset
10234 return rnumnonpx.test( computed ) ?
10235 jQuery( elem ).position()[ prop ] + "px" :
10236 computed;
10237 }
10238 }
10239 );
10240 });
10241
10242
10243 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10244 jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10245 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
10246 // margin is only for outerHeight, outerWidth
10247 jQuery.fn[ funcName ] = function( margin, value ) {
10248 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10249 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10250
10251 return access( this, function( elem, type, value ) {
10252 var doc;
10253
10254 if ( jQuery.isWindow( elem ) ) {
10255 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10256 // isn't a whole lot we can do. See pull request at this URL for discussion:
10257 // https://github.com/jquery/jquery/pull/764
10258 return elem.document.documentElement[ "client" + name ];
10259 }
10260
10261 // Get document width or height
10262 if ( elem.nodeType === 9 ) {
10263 doc = elem.documentElement;
10264
10265 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
10266 // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
10267 return Math.max(
10268 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10269 elem.body[ "offset" + name ], doc[ "offset" + name ],
10270 doc[ "client" + name ]
10271 );
10272 }
10273
10274 return value === undefined ?
10275 // Get width or height on the element, requesting but not forcing parseFloat
10276 jQuery.css( elem, type, extra ) :
10277
10278 // Set width or height on the element
10279 jQuery.style( elem, type, value, extra );
10280 }, type, chainable ? margin : undefined, chainable, null );
10281 };
10282 });
10283 });
10284
10285
10286 // The number of elements contained in the matched element set
10287 jQuery.fn.size = function() {
10288 return this.length;
10289 };
10290
10291 jQuery.fn.andSelf = jQuery.fn.addBack;
10292
10293
10294
10295
10296 // Register as a named AMD module, since jQuery can be concatenated with other
10297 // files that may use define, but not via a proper concatenation script that
10298 // understands anonymous AMD modules. A named AMD is safest and most robust
10299 // way to register. Lowercase jquery is used because AMD module names are
10300 // derived from file names, and jQuery is normally delivered in a lowercase
10301 // file name. Do this after creating the global so that if an AMD module wants
10302 // to call noConflict to hide this version of jQuery, it will work.
10303
10304 // Note that for maximum portability, libraries that are not jQuery should
10305 // declare themselves as anonymous modules, and avoid setting a global if an
10306 // AMD loader is present. jQuery is a special case. For more information, see
10307 // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10308
10309 if ( typeof define === "function" && define.amd ) {
10310 define( "jquery", [], function() {
10311 return jQuery;
10312 });
10313 }
10314
10315
10316
10317
10318 var
10319 // Map over jQuery in case of overwrite
10320 _jQuery = window.jQuery,
10321
10322 // Map over the $ in case of overwrite
10323 _$ = window.$;
10324
10325 jQuery.noConflict = function( deep ) {
10326 if ( window.$ === jQuery ) {
10327 window.$ = _$;
10328 }
10329
10330 if ( deep && window.jQuery === jQuery ) {
10331 window.jQuery = _jQuery;
10332 }
10333
10334 return jQuery;
10335 };
10336
10337 // Expose jQuery and $ identifiers, even in
10338 // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10339 // and CommonJS for browser emulators (#13566)
10340 if ( typeof noGlobal === strundefined ) {
10341 window.jQuery = window.$ = jQuery;
10342 }
10343
10344
10345
10346
10347 return jQuery;
10348
10349
10350 }));
0 /*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
1 !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&D.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(B," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split("").sort(j).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var D,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",y.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^([^.]*)(?:\.(.+)|)/;function we(){return!0}function Te(){return!1}function Ce(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ee(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Se(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,we)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=be.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=be.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click",we),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?we:Te,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Te,isPropagationStopped:Te,isImmediatePropagationStopped:Te,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=we,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=we,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=we,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(e,t){S.event.special[e]={setup:function(){return Se(this,e,Ce),!1},trigger:function(){return Se(this,e),!0},_default:function(){return!0},delegateType:t}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return Ee(this,e,t,n,r)},one:function(e,t,n,r){return Ee(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Te),this.each(function(){S.event.remove(this,e,n,t)})}});var ke=/<script|<style|<link/i,Ae=/checked\s*(?:[^=]|=\s*.checked.)/i,Ne=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function He(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),He(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,"script"),De)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,qe),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(Ne,""),u,l))}return n}function Oe(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Le(o[r],a[r]);else Le(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Oe(this,e,!0)},remove:function(e){return Oe(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return He(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||je(this,e).appendChild(e)})},prepend:function(){return He(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=je(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!ke.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return He(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Pe=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Re=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Me=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Ie=new RegExp(ne.join("|"),"i");function We(e,t,n){var r,i,o,a,s=e.style;return(n=n||Re(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Pe.test(a)&&Ie.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function Fe(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,re.removeChild(e)),a}}))}();var Be=["Webkit","Moz","ms"],$e=E.createElement("div").style,_e={};function ze(e){var t=S.cssProps[e]||_e[e];return t||(e in $e?e:_e[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Be.length;while(n--)if((e=Be[n]+t)in $e)return e}(e)||e)}var Ue=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ve={position:"absolute",visibility:"hidden",display:"block"},Ge={letterSpacing:"0",fontWeight:"400"};function Ye(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Qe(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Je(e,t,n){var r=Re(e),i=(!y.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=We(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Qe(e,t,n||(i?"border":"content"),o,r,a)+"px"}function Ke(e,t,n,r,i){return new Ke.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=We(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Xe.test(t),l=e.style;if(u||(t=ze(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Xe.test(t)||(t=ze(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=We(e,t,r)),"normal"===i&&t in Ge&&(i=Ge[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ue.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Je(e,u,n):Me(e,Ve,function(){return Je(e,u,n)})},set:function(e,t,n){var r,i=Re(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Qe(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Qe(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Ye(0,t,s)}}}),S.cssHooks.marginLeft=Fe(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(We(e,"marginLeft"))||e.getBoundingClientRect().left-Me(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Ye)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Re(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=Ke).prototype={constructor:Ke,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=Ke.propHooks[this.prop];return e&&e.get?e.get(this):Ke.propHooks._default.get(this)},run:function(e){var t,n=Ke.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ke.propHooks._default.set(this),this}}).init.prototype=Ke.prototype,(Ke.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[ze(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=Ke.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=Ke.prototype.init,S.fx.step={};var Ze,et,tt,nt,rt=/^(?:toggle|show|hide)$/,it=/queueHooks$/;function ot(){et&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(ot):C.setTimeout(ot,S.fx.interval),S.fx.tick())}function at(){return C.setTimeout(function(){Ze=void 0}),Ze=Date.now()}function st(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ut(e,t,n){for(var r,i=(lt.tweeners[t]||[]).concat(lt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function lt(o,e,t){var n,a,r=0,i=lt.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=Ze||at(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:Ze||at(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=lt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ut,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(lt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],lt.tweeners[n]=lt.tweeners[n]||[],lt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],rt.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Y.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ut(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?lt.prefilters.unshift(e):lt.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=lt(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&it.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(st(r,!0),e,t,n)}}),S.each({slideDown:st("show"),slideUp:st("hide"),slideToggle:st("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(Ze=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),Ze=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){et||(et=!0,ot())},S.fx.stop=function(){et=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},tt=E.createElement("input"),nt=E.createElement("select").appendChild(E.createElement("option")),tt.type="checkbox",y.checkOn=""!==tt.value,y.optSelected=nt.selected,(tt=E.createElement("input")).value="t",tt.type="radio",y.radioValue="t"===tt.value;var ct,ft=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?ct:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ct={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=ft[t]||S.find.attr;ft[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=ft[o],ft[o]=r,r=null!=a(e,t,n)?o:null,ft[o]=i),r}});var pt=/^(?:input|select|textarea|button)$/i,dt=/^(?:a|area)$/i;function ht(e){return(e.match(P)||[]).join(" ")}function gt(e){return e.getAttribute&&e.getAttribute("class")||""}function vt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):pt.test(e.nodeName)||dt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,gt(this)))});if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&" "+ht(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=ht(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,gt(this)))});if(!arguments.length)return this.attr("class","");if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&" "+ht(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=ht(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,gt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=vt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=gt(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+ht(gt(n))+" ").indexOf(t))return!0;return!1}});var yt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(yt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:ht(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var mt=/^(?:focusinfocus|focusoutblur)$/,xt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!mt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,mt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,xt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,xt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var bt=C.location,wt={guid:Date.now()},Tt=/\?/;S.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||S.error("Invalid XML: "+(n?S.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var Ct=/\[\]$/,Et=/\r?\n/g,St=/^(?:submit|button|image|reset|file)$/i,kt=/^(?:input|select|textarea|keygen)/i;function At(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||Ct.test(n)?i(n,t):At(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)At(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)At(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&kt.test(this.nodeName)&&!St.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(Et,"\r\n")}}):{name:t.name,value:n.replace(Et,"\r\n")}}).get()}});var Nt=/%20/g,jt=/#.*$/,Dt=/([?&])_=[^&]*/,qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Lt=/^(?:GET|HEAD)$/,Ht=/^\/\//,Ot={},Pt={},Rt="*/".concat("*"),Mt=E.createElement("a");function It(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Wt(t,i,o,a){var s={},u=t===Pt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Ft(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Mt.href=bt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:bt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(bt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Rt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Ft(Ft(e,S.ajaxSettings),t):Ft(S.ajaxSettings,e)},ajaxPrefilter:It(Ot),ajaxTransport:It(Pt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=qt.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||bt.href)+"").replace(Ht,bt.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(P)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Mt.protocol+"//"+Mt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Wt(Ot,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Lt.test(v.type),f=v.url.replace(jt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Nt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(Tt.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Dt,"$1"),o=(Tt.test(f)?"&":"?")+"_="+wt.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+Rt+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Wt(Pt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray("script",v.dataTypes)&&S.inArray("json",v.dataTypes)<0&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Bt={0:200,1223:204},$t=S.ajaxSettings.xhr();y.cors=!!$t&&"withCredentials"in $t,y.ajax=$t=!!$t,S.ajaxTransport(function(i){var o,a;if(y.cors||$t&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Bt[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=ht(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Xt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Xt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Vt=C.jQuery,Gt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Gt),e&&C.jQuery===S&&(C.jQuery=Vt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S});
0 /*
1 * language_data.js
2 * ~~~~~~~~~~~~~~~~
3 *
4 * This script contains the language-specific data used by searchtools.js,
5 * namely the list of stopwords, stemmer, scorer and splitter.
6 *
7 * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
8 * :license: BSD, see LICENSE for details.
9 *
10 */
11
12 var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
13
14
15 /* Non-minified version is copied as a separate JS file, is available */
16
17 /**
18 * Porter Stemmer
19 */
20 var Stemmer = function() {
21
22 var step2list = {
23 ational: 'ate',
24 tional: 'tion',
25 enci: 'ence',
26 anci: 'ance',
27 izer: 'ize',
28 bli: 'ble',
29 alli: 'al',
30 entli: 'ent',
31 eli: 'e',
32 ousli: 'ous',
33 ization: 'ize',
34 ation: 'ate',
35 ator: 'ate',
36 alism: 'al',
37 iveness: 'ive',
38 fulness: 'ful',
39 ousness: 'ous',
40 aliti: 'al',
41 iviti: 'ive',
42 biliti: 'ble',
43 logi: 'log'
44 };
45
46 var step3list = {
47 icate: 'ic',
48 ative: '',
49 alize: 'al',
50 iciti: 'ic',
51 ical: 'ic',
52 ful: '',
53 ness: ''
54 };
55
56 var c = "[^aeiou]"; // consonant
57 var v = "[aeiouy]"; // vowel
58 var C = c + "[^aeiouy]*"; // consonant sequence
59 var V = v + "[aeiou]*"; // vowel sequence
60
61 var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
62 var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
63 var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
64 var s_v = "^(" + C + ")?" + v; // vowel in stem
65
66 this.stemWord = function (w) {
67 var stem;
68 var suffix;
69 var firstch;
70 var origword = w;
71
72 if (w.length < 3)
73 return w;
74
75 var re;
76 var re2;
77 var re3;
78 var re4;
79
80 firstch = w.substr(0,1);
81 if (firstch == "y")
82 w = firstch.toUpperCase() + w.substr(1);
83
84 // Step 1a
85 re = /^(.+?)(ss|i)es$/;
86 re2 = /^(.+?)([^s])s$/;
87
88 if (re.test(w))
89 w = w.replace(re,"$1$2");
90 else if (re2.test(w))
91 w = w.replace(re2,"$1$2");
92
93 // Step 1b
94 re = /^(.+?)eed$/;
95 re2 = /^(.+?)(ed|ing)$/;
96 if (re.test(w)) {
97 var fp = re.exec(w);
98 re = new RegExp(mgr0);
99 if (re.test(fp[1])) {
100 re = /.$/;
101 w = w.replace(re,"");
102 }
103 }
104 else if (re2.test(w)) {
105 var fp = re2.exec(w);
106 stem = fp[1];
107 re2 = new RegExp(s_v);
108 if (re2.test(stem)) {
109 w = stem;
110 re2 = /(at|bl|iz)$/;
111 re3 = new RegExp("([^aeiouylsz])\\1$");
112 re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
113 if (re2.test(w))
114 w = w + "e";
115 else if (re3.test(w)) {
116 re = /.$/;
117 w = w.replace(re,"");
118 }
119 else if (re4.test(w))
120 w = w + "e";
121 }
122 }
123
124 // Step 1c
125 re = /^(.+?)y$/;
126 if (re.test(w)) {
127 var fp = re.exec(w);
128 stem = fp[1];
129 re = new RegExp(s_v);
130 if (re.test(stem))
131 w = stem + "i";
132 }
133
134 // Step 2
135 re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
136 if (re.test(w)) {
137 var fp = re.exec(w);
138 stem = fp[1];
139 suffix = fp[2];
140 re = new RegExp(mgr0);
141 if (re.test(stem))
142 w = stem + step2list[suffix];
143 }
144
145 // Step 3
146 re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
147 if (re.test(w)) {
148 var fp = re.exec(w);
149 stem = fp[1];
150 suffix = fp[2];
151 re = new RegExp(mgr0);
152 if (re.test(stem))
153 w = stem + step3list[suffix];
154 }
155
156 // Step 4
157 re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
158 re2 = /^(.+?)(s|t)(ion)$/;
159 if (re.test(w)) {
160 var fp = re.exec(w);
161 stem = fp[1];
162 re = new RegExp(mgr1);
163 if (re.test(stem))
164 w = stem;
165 }
166 else if (re2.test(w)) {
167 var fp = re2.exec(w);
168 stem = fp[1] + fp[2];
169 re2 = new RegExp(mgr1);
170 if (re2.test(stem))
171 w = stem;
172 }
173
174 // Step 5
175 re = /^(.+?)e$/;
176 if (re.test(w)) {
177 var fp = re.exec(w);
178 stem = fp[1];
179 re = new RegExp(mgr1);
180 re2 = new RegExp(meq1);
181 re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
182 if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
183 w = stem;
184 }
185 re = /ll$/;
186 re2 = new RegExp(mgr1);
187 if (re.test(w) && re2.test(w)) {
188 re = /.$/;
189 w = w.replace(re,"");
190 }
191
192 // and turn initial Y back to y
193 if (firstch == "y")
194 w = firstch.toLowerCase() + w.substr(1);
195 return w;
196 }
197 }
198
Binary diff not shown
0 pre { line-height: 125%; }
1 td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
2 span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
3 td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
4 span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
05 .highlight .hll { background-color: #ffffcc }
1 .highlight { background: #eeffcc; }
6 .highlight { background: #eeffcc; }
27 .highlight .c { color: #408090; font-style: italic } /* Comment */
38 .highlight .err { border: 1px solid #FF0000 } /* Error */
49 .highlight .k { color: #007020; font-weight: bold } /* Keyword */
4651 .highlight .mh { color: #208050 } /* Literal.Number.Hex */
4752 .highlight .mi { color: #208050 } /* Literal.Number.Integer */
4853 .highlight .mo { color: #208050 } /* Literal.Number.Oct */
54 .highlight .sa { color: #4070a0 } /* Literal.String.Affix */
4955 .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
5056 .highlight .sc { color: #4070a0 } /* Literal.String.Char */
57 .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
5158 .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
5259 .highlight .s2 { color: #4070a0 } /* Literal.String.Double */
5360 .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
5865 .highlight .s1 { color: #4070a0 } /* Literal.String.Single */
5966 .highlight .ss { color: #517918 } /* Literal.String.Symbol */
6067 .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
68 .highlight .fm { color: #06287e } /* Name.Function.Magic */
6169 .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
6270 .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
6371 .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
72 .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
6473 .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
00 /*
1 * searchtools.js_t
1 * searchtools.js
22 * ~~~~~~~~~~~~~~~~
33 *
4 * Sphinx JavaScript utilties for the full-text search.
4 * Sphinx JavaScript utilities for the full-text search.
55 *
6 * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
6 * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
77 * :license: BSD, see LICENSE for details.
88 *
99 */
10
11
12 /* Non-minified version JS is _stemmer.js if file is provided */
13 /**
14 * Porter Stemmer
15 */
16 var Stemmer = function() {
17
18 var step2list = {
19 ational: 'ate',
20 tional: 'tion',
21 enci: 'ence',
22 anci: 'ance',
23 izer: 'ize',
24 bli: 'ble',
25 alli: 'al',
26 entli: 'ent',
27 eli: 'e',
28 ousli: 'ous',
29 ization: 'ize',
30 ation: 'ate',
31 ator: 'ate',
32 alism: 'al',
33 iveness: 'ive',
34 fulness: 'ful',
35 ousness: 'ous',
36 aliti: 'al',
37 iviti: 'ive',
38 biliti: 'ble',
39 logi: 'log'
40 };
41
42 var step3list = {
43 icate: 'ic',
44 ative: '',
45 alize: 'al',
46 iciti: 'ic',
47 ical: 'ic',
48 ful: '',
49 ness: ''
50 };
51
52 var c = "[^aeiou]"; // consonant
53 var v = "[aeiouy]"; // vowel
54 var C = c + "[^aeiouy]*"; // consonant sequence
55 var V = v + "[aeiou]*"; // vowel sequence
56
57 var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
58 var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
59 var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
60 var s_v = "^(" + C + ")?" + v; // vowel in stem
61
62 this.stemWord = function (w) {
63 var stem;
64 var suffix;
65 var firstch;
66 var origword = w;
67
68 if (w.length < 3)
69 return w;
70
71 var re;
72 var re2;
73 var re3;
74 var re4;
75
76 firstch = w.substr(0,1);
77 if (firstch == "y")
78 w = firstch.toUpperCase() + w.substr(1);
79
80 // Step 1a
81 re = /^(.+?)(ss|i)es$/;
82 re2 = /^(.+?)([^s])s$/;
83
84 if (re.test(w))
85 w = w.replace(re,"$1$2");
86 else if (re2.test(w))
87 w = w.replace(re2,"$1$2");
88
89 // Step 1b
90 re = /^(.+?)eed$/;
91 re2 = /^(.+?)(ed|ing)$/;
92 if (re.test(w)) {
93 var fp = re.exec(w);
94 re = new RegExp(mgr0);
95 if (re.test(fp[1])) {
96 re = /.$/;
97 w = w.replace(re,"");
98 }
99 }
100 else if (re2.test(w)) {
101 var fp = re2.exec(w);
102 stem = fp[1];
103 re2 = new RegExp(s_v);
104 if (re2.test(stem)) {
105 w = stem;
106 re2 = /(at|bl|iz)$/;
107 re3 = new RegExp("([^aeiouylsz])\\1$");
108 re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
109 if (re2.test(w))
110 w = w + "e";
111 else if (re3.test(w)) {
112 re = /.$/;
113 w = w.replace(re,"");
114 }
115 else if (re4.test(w))
116 w = w + "e";
117 }
118 }
119
120 // Step 1c
121 re = /^(.+?)y$/;
122 if (re.test(w)) {
123 var fp = re.exec(w);
124 stem = fp[1];
125 re = new RegExp(s_v);
126 if (re.test(stem))
127 w = stem + "i";
128 }
129
130 // Step 2
131 re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
132 if (re.test(w)) {
133 var fp = re.exec(w);
134 stem = fp[1];
135 suffix = fp[2];
136 re = new RegExp(mgr0);
137 if (re.test(stem))
138 w = stem + step2list[suffix];
139 }
140
141 // Step 3
142 re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
143 if (re.test(w)) {
144 var fp = re.exec(w);
145 stem = fp[1];
146 suffix = fp[2];
147 re = new RegExp(mgr0);
148 if (re.test(stem))
149 w = stem + step3list[suffix];
150 }
151
152 // Step 4
153 re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
154 re2 = /^(.+?)(s|t)(ion)$/;
155 if (re.test(w)) {
156 var fp = re.exec(w);
157 stem = fp[1];
158 re = new RegExp(mgr1);
159 if (re.test(stem))
160 w = stem;
161 }
162 else if (re2.test(w)) {
163 var fp = re2.exec(w);
164 stem = fp[1] + fp[2];
165 re2 = new RegExp(mgr1);
166 if (re2.test(stem))
167 w = stem;
168 }
169
170 // Step 5
171 re = /^(.+?)e$/;
172 if (re.test(w)) {
173 var fp = re.exec(w);
174 stem = fp[1];
175 re = new RegExp(mgr1);
176 re2 = new RegExp(meq1);
177 re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
178 if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
179 w = stem;
180 }
181 re = /ll$/;
182 re2 = new RegExp(mgr1);
183 if (re.test(w) && re2.test(w)) {
184 re = /.$/;
185 w = w.replace(re,"");
186 }
187
188 // and turn initial Y back to y
189 if (firstch == "y")
190 w = firstch.toLowerCase() + w.substr(1);
191 return w;
192 }
193 }
194
195
10 "use strict";
19611
19712 /**
19813 * Simple result scoring code.
19914 */
200 var Scorer = {
201 // Implement the following function to further tweak the score for each result
202 // The function takes a result array [filename, title, anchor, descr, score]
203 // and returns the new score.
204 /*
205 score: function(result) {
206 return result[4];
207 },
208 */
209
210 // query matches the full name of an object
211 objNameMatch: 11,
212 // or matches in the last dotted part of the object name
213 objPartialMatch: 6,
214 // Additive scores depending on the priority of the object
215 objPrio: {0: 15, // used to be importantResults
216 1: 5, // used to be objectResults
217 2: -5}, // used to be unimportantResults
218 // Used when the priority is not in the mapping.
219 objPrioDefault: 0,
220
221 // query found in title
222 title: 15,
223 // query found in terms
224 term: 5
15 if (typeof Scorer === "undefined") {
16 var Scorer = {
17 // Implement the following function to further tweak the score for each result
18 // The function takes a result array [docname, title, anchor, descr, score, filename]
19 // and returns the new score.
20 /*
21 score: result => {
22 const [docname, title, anchor, descr, score, filename] = result
23 return score
24 },
25 */
26
27 // query matches the full name of an object
28 objNameMatch: 11,
29 // or matches in the last dotted part of the object name
30 objPartialMatch: 6,
31 // Additive scores depending on the priority of the object
32 objPrio: {
33 0: 15, // used to be importantResults
34 1: 5, // used to be objectResults
35 2: -5, // used to be unimportantResults
36 },
37 // Used when the priority is not in the mapping.
38 objPrioDefault: 0,
39
40 // query found in title
41 title: 15,
42 partialTitle: 7,
43 // query found in terms
44 term: 5,
45 partialTerm: 2,
46 };
47 }
48
49 const _removeChildren = (element) => {
50 while (element && element.lastChild) element.removeChild(element.lastChild);
22551 };
22652
53 /**
54 * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
55 */
56 const _escapeRegExp = (string) =>
57 string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
58
59 const _displayItem = (item, highlightTerms, searchTerms) => {
60 const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
61 const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
62 const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
63 const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
64 const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
65
66 const [docName, title, anchor, descr] = item;
67
68 let listItem = document.createElement("li");
69 let requestUrl;
70 let linkUrl;
71 if (docBuilder === "dirhtml") {
72 // dirhtml builder
73 let dirname = docName + "/";
74 if (dirname.match(/\/index\/$/))
75 dirname = dirname.substring(0, dirname.length - 6);
76 else if (dirname === "index/") dirname = "";
77 requestUrl = docUrlRoot + dirname;
78 linkUrl = requestUrl;
79 } else {
80 // normal html builders
81 requestUrl = docUrlRoot + docName + docFileSuffix;
82 linkUrl = docName + docLinkSuffix;
83 }
84 const params = new URLSearchParams();
85 params.set("highlight", [...highlightTerms].join(" "));
86 let linkEl = listItem.appendChild(document.createElement("a"));
87 linkEl.href = linkUrl + "?" + params.toString() + anchor;
88 linkEl.innerHTML = title;
89 if (descr)
90 listItem.appendChild(document.createElement("span")).innerText =
91 " (" + descr + ")";
92 else if (showSearchSummary)
93 fetch(requestUrl)
94 .then((responseData) => responseData.text())
95 .then((data) => {
96 if (data)
97 listItem.appendChild(
98 Search.makeSearchSummary(data, searchTerms, highlightTerms)
99 );
100 });
101 Search.output.appendChild(listItem);
102 };
103 const _finishSearch = (resultCount) => {
104 Search.stopPulse();
105 Search.title.innerText = _("Search Results");
106 if (!resultCount)
107 Search.status.innerText = Documentation.gettext(
108 "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
109 );
110 else
111 Search.status.innerText = _(
112 `Search finished, found ${resultCount} page(s) matching the search query.`
113 );
114 };
115 const _displayNextItem = (
116 results,
117 resultCount,
118 highlightTerms,
119 searchTerms
120 ) => {
121 // results left, load the summary and display it
122 // this is intended to be dynamic (don't sub resultsCount)
123 if (results.length) {
124 _displayItem(results.pop(), highlightTerms, searchTerms);
125 setTimeout(
126 () => _displayNextItem(results, resultCount, highlightTerms, searchTerms),
127 5
128 );
129 }
130 // search finished, update title and status message
131 else _finishSearch(resultCount);
132 };
133
134 /**
135 * Default splitQuery function. Can be overridden in ``sphinx.search`` with a
136 * custom function per language.
137 *
138 * The regular expression works by splitting the string on consecutive characters
139 * that are not Unicode letters, numbers, underscores, or emoji characters.
140 * This is the same as ``\W+`` in Python, preserving the surrogate pair area.
141 */
142 if (typeof splitQuery === "undefined") {
143 var splitQuery = (query) => query
144 .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
145 .filter(term => term) // remove remaining empty strings
146 }
227147
228148 /**
229149 * Search Module
230150 */
231 var Search = {
232
233 _index : null,
234 _queued_query : null,
235 _pulse_status : -1,
236
237 init : function() {
238 var params = $.getQueryParameters();
239 if (params.q) {
240 var query = params.q[0];
241 $('input[name="q"]')[0].value = query;
242 this.performSearch(query);
243 }
244 },
245
246 loadIndex : function(url) {
247 $.ajax({type: "GET", url: url, data: null,
248 dataType: "script", cache: true,
249 complete: function(jqxhr, textstatus) {
250 if (textstatus != "success") {
251 document.getElementById("searchindexloader").src = url;
252 }
253 }});
254 },
255
256 setIndex : function(index) {
257 var q;
258 this._index = index;
259 if ((q = this._queued_query) !== null) {
260 this._queued_query = null;
261 Search.query(q);
151 const Search = {
152 _index: null,
153 _queued_query: null,
154 _pulse_status: -1,
155
156 htmlToText: (htmlString) => {
157 const htmlElement = document
158 .createRange()
159 .createContextualFragment(htmlString);
160 _removeChildren(htmlElement.querySelectorAll(".headerlink"));
161 const docContent = htmlElement.querySelector('[role="main"]');
162 if (docContent !== undefined) return docContent.textContent;
163 console.warn(
164 "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
165 );
166 return "";
167 },
168
169 init: () => {
170 const query = new URLSearchParams(window.location.search).get("q");
171 document
172 .querySelectorAll('input[name="q"]')
173 .forEach((el) => (el.value = query));
174 if (query) Search.performSearch(query);
175 },
176
177 loadIndex: (url) =>
178 (document.body.appendChild(document.createElement("script")).src = url),
179
180 setIndex: (index) => {
181 Search._index = index;
182 if (Search._queued_query !== null) {
183 const query = Search._queued_query;
184 Search._queued_query = null;
185 Search.query(query);
262186 }
263187 },
264188
265 hasIndex : function() {
266 return this._index !== null;
267 },
268
269 deferQuery : function(query) {
270 this._queued_query = query;
271 },
272
273 stopPulse : function() {
274 this._pulse_status = 0;
275 },
276
277 startPulse : function() {
278 if (this._pulse_status >= 0)
279 return;
280 function pulse() {
281 var i;
189 hasIndex: () => Search._index !== null,
190
191 deferQuery: (query) => (Search._queued_query = query),
192
193 stopPulse: () => (Search._pulse_status = -1),
194
195 startPulse: () => {
196 if (Search._pulse_status >= 0) return;
197
198 const pulse = () => {
282199 Search._pulse_status = (Search._pulse_status + 1) % 4;
283 var dotString = '';
284 for (i = 0; i < Search._pulse_status; i++)
285 dotString += '.';
286 Search.dots.text(dotString);
287 if (Search._pulse_status > -1)
288 window.setTimeout(pulse, 500);
289 }
200 Search.dots.innerText = ".".repeat(Search._pulse_status);
201 if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
202 };
290203 pulse();
291204 },
292205
293206 /**
294207 * perform a search for something (or wait until index is loaded)
295208 */
296 performSearch : function(query) {
209 performSearch: (query) => {
297210 // create the required interface elements
298 this.out = $('#search-results');
299 this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
300 this.dots = $('<span></span>').appendTo(this.title);
301 this.status = $('<p style="display: none"></p>').appendTo(this.out);
302 this.output = $('<ul class="search"/>').appendTo(this.out);
303
304 $('#search-progress').text(_('Preparing search...'));
305 this.startPulse();
211 const searchText = document.createElement("h2");
212 searchText.textContent = _("Searching");
213 const searchSummary = document.createElement("p");
214 searchSummary.classList.add("search-summary");
215 searchSummary.innerText = "";
216 const searchList = document.createElement("ul");
217 searchList.classList.add("search");
218
219 const out = document.getElementById("search-results");
220 Search.title = out.appendChild(searchText);
221 Search.dots = Search.title.appendChild(document.createElement("span"));
222 Search.status = out.appendChild(searchSummary);
223 Search.output = out.appendChild(searchList);
224
225 const searchProgress = document.getElementById("search-progress");
226 // Some themes don't use the search progress node
227 if (searchProgress) {
228 searchProgress.innerText = _("Preparing search...");
229 }
230 Search.startPulse();
306231
307232 // index already loaded, the browser was quick!
308 if (this.hasIndex())
309 this.query(query);
310 else
311 this.deferQuery(query);
233 if (Search.hasIndex()) Search.query(query);
234 else Search.deferQuery(query);
312235 },
313236
314237 /**
315238 * execute search (requires search index to be loaded)
316239 */
317 query : function(query) {
318 var i;
319 var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
320
321 // stem the searchterms and add them to the correct list
322 var stemmer = new Stemmer();
323 var searchterms = [];
324 var excluded = [];
325 var hlterms = [];
326 var tmp = query.split(/\s+/);
327 var objectterms = [];
328 for (i = 0; i < tmp.length; i++) {
329 if (tmp[i] !== "") {
330 objectterms.push(tmp[i].toLowerCase());
240 query: (query) => {
241 // stem the search terms and add them to the correct list
242 const stemmer = new Stemmer();
243 const searchTerms = new Set();
244 const excludedTerms = new Set();
245 const highlightTerms = new Set();
246 const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
247 splitQuery(query.trim()).forEach((queryTerm) => {
248 const queryTermLower = queryTerm.toLowerCase();
249
250 // maybe skip this "word"
251 // stopwords array is from language_data.js
252 if (
253 stopwords.indexOf(queryTermLower) !== -1 ||
254 queryTerm.match(/^\d+$/)
255 )
256 return;
257
258 // stem the word
259 let word = stemmer.stemWord(queryTermLower);
260 // select the correct list
261 if (word[0] === "-") excludedTerms.add(word.substr(1));
262 else {
263 searchTerms.add(word);
264 highlightTerms.add(queryTermLower);
331265 }
332
333 if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
334 tmp[i] === "") {
335 // skip this "word"
336 continue;
337 }
338 // stem the word
339 var word = stemmer.stemWord(tmp[i].toLowerCase());
340 var toAppend;
341 // select the correct list
342 if (word[0] == '-') {
343 toAppend = excluded;
344 word = word.substr(1);
345 }
346 else {
347 toAppend = searchterms;
348 hlterms.push(tmp[i].toLowerCase());
349 }
350 // only add if not already in the list
351 if (!$u.contains(toAppend, word))
352 toAppend.push(word);
353 }
354 var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
355
356 // console.debug('SEARCH: searching for:');
357 // console.info('required: ', searchterms);
358 // console.info('excluded: ', excluded);
359
360 // prepare search
361 var terms = this._index.terms;
362 var titleterms = this._index.titleterms;
363
364 // array of [filename, title, anchor, descr, score]
365 var results = [];
366 $('#search-progress').empty();
266 });
267
268 // console.debug("SEARCH: searching for:");
269 // console.info("required: ", [...searchTerms]);
270 // console.info("excluded: ", [...excludedTerms]);
271
272 // array of [docname, title, anchor, descr, score, filename]
273 let results = [];
274 _removeChildren(document.getElementById("search-progress"));
367275
368276 // lookup as object
369 for (i = 0; i < objectterms.length; i++) {
370 var others = [].concat(objectterms.slice(0, i),
371 objectterms.slice(i+1, objectterms.length));
372 results = results.concat(this.performObjectSearch(objectterms[i], others));
373 }
277 objectTerms.forEach((term) =>
278 results.push(...Search.performObjectSearch(term, objectTerms))
279 );
374280
375281 // lookup as search terms in fulltext
376 results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
282 results.push(...Search.performTermsSearch(searchTerms, excludedTerms));
377283
378284 // let the scorer override scores with a custom scoring function
379 if (Scorer.score) {
380 for (i = 0; i < results.length; i++)
381 results[i][4] = Scorer.score(results[i]);
382 }
285 if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item)));
383286
384287 // now sort the results by score (in opposite order of appearance, since the
385288 // display function below uses pop() to retrieve items) and then
386289 // alphabetically
387 results.sort(function(a, b) {
388 var left = a[4];
389 var right = b[4];
390 if (left > right) {
391 return 1;
392 } else if (left < right) {
393 return -1;
394 } else {
290 results.sort((a, b) => {
291 const leftScore = a[4];
292 const rightScore = b[4];
293 if (leftScore === rightScore) {
395294 // same score: sort alphabetically
396 left = a[1].toLowerCase();
397 right = b[1].toLowerCase();
398 return (left > right) ? -1 : ((left < right) ? 1 : 0);
295 const leftTitle = a[1].toLowerCase();
296 const rightTitle = b[1].toLowerCase();
297 if (leftTitle === rightTitle) return 0;
298 return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
399299 }
300 return leftScore > rightScore ? 1 : -1;
400301 });
302
303 // remove duplicate search results
304 // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
305 let seen = new Set();
306 results = results.reverse().reduce((acc, result) => {
307 let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
308 if (!seen.has(resultStr)) {
309 acc.push(result);
310 seen.add(resultStr);
311 }
312 return acc;
313 }, []);
314
315 results = results.reverse();
401316
402317 // for debugging
403318 //Search.lastresults = results.slice(); // a copy
404 //console.info('search results:', Search.lastresults);
319 // console.info("search results:", Search.lastresults);
405320
406321 // print the results
407 var resultCount = results.length;
408 function displayNextItem() {
409 // results left, load the summary and display it
410 if (results.length) {
411 var item = results.pop();
412 var listItem = $('<li style="display:none"></li>');
413 if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
414 // dirhtml builder
415 var dirname = item[0] + '/';
416 if (dirname.match(/\/index\/$/)) {
417 dirname = dirname.substring(0, dirname.length-6);
418 } else if (dirname == 'index/') {
419 dirname = '';
420 }
421 listItem.append($('<a/>').attr('href',
422 DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
423 highlightstring + item[2]).html(item[1]));
424 } else {
425 // normal html builders
426 listItem.append($('<a/>').attr('href',
427 item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
428 highlightstring + item[2]).html(item[1]));
429 }
430 if (item[3]) {
431 listItem.append($('<span> (' + item[3] + ')</span>'));
432 Search.output.append(listItem);
433 listItem.slideDown(5, function() {
434 displayNextItem();
435 });
436 } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
437 $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt',
438 dataType: "text",
439 complete: function(jqxhr, textstatus) {
440 var data = jqxhr.responseText;
441 if (data !== '' && data !== undefined) {
442 listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
443 }
444 Search.output.append(listItem);
445 listItem.slideDown(5, function() {
446 displayNextItem();
447 });
448 }});
449 } else {
450 // no source available, just display title
451 Search.output.append(listItem);
452 listItem.slideDown(5, function() {
453 displayNextItem();
454 });
455 }
456 }
457 // search finished, update title and status message
458 else {
459 Search.stopPulse();
460 Search.title.text(_('Search Results'));
461 if (!resultCount)
462 Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
463 else
464 Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
465 Search.status.fadeIn(500);
466 }
467 }
468 displayNextItem();
322 _displayNextItem(results, results.length, highlightTerms, searchTerms);
469323 },
470324
471325 /**
472326 * search for object names
473327 */
474 performObjectSearch : function(object, otherterms) {
475 var filenames = this._index.filenames;
476 var objects = this._index.objects;
477 var objnames = this._index.objnames;
478 var titles = this._index.titles;
479
480 var i;
481 var results = [];
482
483 for (var prefix in objects) {
484 for (var name in objects[prefix]) {
485 var fullname = (prefix ? prefix + '.' : '') + name;
486 if (fullname.toLowerCase().indexOf(object) > -1) {
487 var score = 0;
488 var parts = fullname.split('.');
489 // check for different match types: exact matches of full name or
490 // "last name" (i.e. last dotted part)
491 if (fullname == object || parts[parts.length - 1] == object) {
492 score += Scorer.objNameMatch;
493 // matches in last name
494 } else if (parts[parts.length - 1].indexOf(object) > -1) {
495 score += Scorer.objPartialMatch;
496 }
497 var match = objects[prefix][name];
498 var objname = objnames[match[1]][2];
499 var title = titles[match[0]];
500 // If more than one term searched for, we require other words to be
501 // found in the name/title/description
502 if (otherterms.length > 0) {
503 var haystack = (prefix + ' ' + name + ' ' +
504 objname + ' ' + title).toLowerCase();
505 var allfound = true;
506 for (i = 0; i < otherterms.length; i++) {
507 if (haystack.indexOf(otherterms[i]) == -1) {
508 allfound = false;
509 break;
510 }
511 }
512 if (!allfound) {
513 continue;
514 }
515 }
516 var descr = objname + _(', in ') + title;
517
518 var anchor = match[3];
519 if (anchor === '')
520 anchor = fullname;
521 else if (anchor == '-')
522 anchor = objnames[match[1]][1] + '-' + fullname;
523 // add custom score for some objects according to scorer
524 if (Scorer.objPrio.hasOwnProperty(match[2])) {
525 score += Scorer.objPrio[match[2]];
526 } else {
527 score += Scorer.objPrioDefault;
528 }
529 results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]);
530 }
328 performObjectSearch: (object, objectTerms) => {
329 const filenames = Search._index.filenames;
330 const docNames = Search._index.docnames;
331 const objects = Search._index.objects;
332 const objNames = Search._index.objnames;
333 const titles = Search._index.titles;
334
335 const results = [];
336
337 const objectSearchCallback = (prefix, match) => {
338 const name = match[4]
339 const fullname = (prefix ? prefix + "." : "") + name;
340 const fullnameLower = fullname.toLowerCase();
341 if (fullnameLower.indexOf(object) < 0) return;
342
343 let score = 0;
344 const parts = fullnameLower.split(".");
345
346 // check for different match types: exact matches of full name or
347 // "last name" (i.e. last dotted part)
348 if (fullnameLower === object || parts.slice(-1)[0] === object)
349 score += Scorer.objNameMatch;
350 else if (parts.slice(-1)[0].indexOf(object) > -1)
351 score += Scorer.objPartialMatch; // matches in last name
352
353 const objName = objNames[match[1]][2];
354 const title = titles[match[0]];
355
356 // If more than one term searched for, we require other words to be
357 // found in the name/title/description
358 const otherTerms = new Set(objectTerms);
359 otherTerms.delete(object);
360 if (otherTerms.size > 0) {
361 const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
362 if (
363 [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
364 )
365 return;
531366 }
532 }
533
367
368 let anchor = match[3];
369 if (anchor === "") anchor = fullname;
370 else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
371
372 const descr = objName + _(", in ") + title;
373
374 // add custom score for some objects according to scorer
375 if (Scorer.objPrio.hasOwnProperty(match[2]))
376 score += Scorer.objPrio[match[2]];
377 else score += Scorer.objPrioDefault;
378
379 results.push([
380 docNames[match[0]],
381 fullname,
382 "#" + anchor,
383 descr,
384 score,
385 filenames[match[0]],
386 ]);
387 };
388 Object.keys(objects).forEach((prefix) =>
389 objects[prefix].forEach((array) =>
390 objectSearchCallback(prefix, array)
391 )
392 );
534393 return results;
535394 },
536395
537396 /**
538397 * search for full-text terms in the index
539398 */
540 performTermsSearch : function(searchterms, excluded, terms, titleterms) {
541 var filenames = this._index.filenames;
542 var titles = this._index.titles;
543
544 var i, j, file;
545 var fileMap = {};
546 var scoreMap = {};
547 var results = [];
399 performTermsSearch: (searchTerms, excludedTerms) => {
400 // prepare search
401 const terms = Search._index.terms;
402 const titleTerms = Search._index.titleterms;
403 const docNames = Search._index.docnames;
404 const filenames = Search._index.filenames;
405 const titles = Search._index.titles;
406
407 const scoreMap = new Map();
408 const fileMap = new Map();
548409
549410 // perform the search on the required terms
550 for (i = 0; i < searchterms.length; i++) {
551 var word = searchterms[i];
552 var files = [];
553 var _o = [
554 {files: terms[word], score: Scorer.term},
555 {files: titleterms[word], score: Scorer.title}
411 searchTerms.forEach((word) => {
412 const files = [];
413 const arr = [
414 { files: terms[word], score: Scorer.term },
415 { files: titleTerms[word], score: Scorer.title },
556416 ];
417 // add support for partial matches
418 if (word.length > 2) {
419 const escapedWord = _escapeRegExp(word);
420 Object.keys(terms).forEach((term) => {
421 if (term.match(escapedWord) && !terms[word])
422 arr.push({ files: terms[term], score: Scorer.partialTerm });
423 });
424 Object.keys(titleTerms).forEach((term) => {
425 if (term.match(escapedWord) && !titleTerms[word])
426 arr.push({ files: titleTerms[word], score: Scorer.partialTitle });
427 });
428 }
557429
558430 // no match but word was a required one
559 if ($u.every(_o, function(o){return o.files === undefined;})) {
431 if (arr.every((record) => record.files === undefined)) return;
432
433 // found search word in contents
434 arr.forEach((record) => {
435 if (record.files === undefined) return;
436
437 let recordFiles = record.files;
438 if (recordFiles.length === undefined) recordFiles = [recordFiles];
439 files.push(...recordFiles);
440
441 // set score for the word in each file
442 recordFiles.forEach((file) => {
443 if (!scoreMap.has(file)) scoreMap.set(file, {});
444 scoreMap.get(file)[word] = record.score;
445 });
446 });
447
448 // create the mapping
449 files.forEach((file) => {
450 if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1)
451 fileMap.get(file).push(word);
452 else fileMap.set(file, [word]);
453 });
454 });
455
456 // now check if the files don't contain excluded terms
457 const results = [];
458 for (const [file, wordList] of fileMap) {
459 // check if all requirements are matched
460
461 // as search terms with length < 3 are discarded
462 const filteredTermCount = [...searchTerms].filter(
463 (term) => term.length > 2
464 ).length;
465 if (
466 wordList.length !== searchTerms.size &&
467 wordList.length !== filteredTermCount
468 )
469 continue;
470
471 // ensure that none of the excluded terms is in the search result
472 if (
473 [...excludedTerms].some(
474 (term) =>
475 terms[term] === file ||
476 titleTerms[term] === file ||
477 (terms[term] || []).includes(file) ||
478 (titleTerms[term] || []).includes(file)
479 )
480 )
560481 break;
561 }
562 // found search word in contents
563 $u.each(_o, function(o) {
564 var _files = o.files;
565 if (_files === undefined)
566 return
567
568 if (_files.length === undefined)
569 _files = [_files];
570 files = files.concat(_files);
571
572 // set score for the word in each file to Scorer.term
573 for (j = 0; j < _files.length; j++) {
574 file = _files[j];
575 if (!(file in scoreMap))
576 scoreMap[file] = {}
577 scoreMap[file][word] = o.score;
578 }
579 });
580
581 // create the mapping
582 for (j = 0; j < files.length; j++) {
583 file = files[j];
584 if (file in fileMap)
585 fileMap[file].push(word);
586 else
587 fileMap[file] = [word];
588 }
589 }
590
591 // now check if the files don't contain excluded terms
592 for (file in fileMap) {
593 var valid = true;
594
595 // check if all requirements are matched
596 if (fileMap[file].length != searchterms.length)
597 continue;
598
599 // ensure that none of the excluded terms is in the search result
600 for (i = 0; i < excluded.length; i++) {
601 if (terms[excluded[i]] == file ||
602 titleterms[excluded[i]] == file ||
603 $u.contains(terms[excluded[i]] || [], file) ||
604 $u.contains(titleterms[excluded[i]] || [], file)) {
605 valid = false;
606 break;
607 }
608 }
609
610 // if we have still a valid result we can add it to the result list
611 if (valid) {
612 // select one (max) score for the file.
613 // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
614 var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
615 results.push([filenames[file], titles[file], '', null, score]);
616 }
482
483 // select one (max) score for the file.
484 const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
485 // add result to the result list
486 results.push([
487 docNames[file],
488 titles[file],
489 "",
490 null,
491 score,
492 filenames[file],
493 ]);
617494 }
618495 return results;
619496 },
621498 /**
622499 * helper function to return a node containing the
623500 * search summary for a given text. keywords is a list
624 * of stemmed words, hlwords is the list of normal, unstemmed
625 * words. the first one is used to find the occurance, the
501 * of stemmed words, highlightWords is the list of normal, unstemmed
502 * words. the first one is used to find the occurrence, the
626503 * latter for highlighting it.
627504 */
628 makeSearchSummary : function(text, keywords, hlwords) {
629 var textLower = text.toLowerCase();
630 var start = 0;
631 $.each(keywords, function() {
632 var i = textLower.indexOf(this.toLowerCase());
633 if (i > -1)
634 start = i;
635 });
636 start = Math.max(start - 120, 0);
637 var excerpt = ((start > 0) ? '...' : '') +
638 $.trim(text.substr(start, 240)) +
639 ((start + 240 - text.length) ? '...' : '');
640 var rv = $('<div class="context"></div>').text(excerpt);
641 $.each(hlwords, function() {
642 rv = rv.highlightText(this, 'highlighted');
643 });
644 return rv;
645 }
505 makeSearchSummary: (htmlText, keywords, highlightWords) => {
506 const text = Search.htmlToText(htmlText).toLowerCase();
507 if (text === "") return null;
508
509 const actualStartPosition = [...keywords]
510 .map((k) => text.indexOf(k.toLowerCase()))
511 .filter((i) => i > -1)
512 .slice(-1)[0];
513 const startWithContext = Math.max(actualStartPosition - 120, 0);
514
515 const top = startWithContext === 0 ? "" : "...";
516 const tail = startWithContext + 240 < text.length ? "..." : "";
517
518 let summary = document.createElement("div");
519 summary.classList.add("context");
520 summary.innerText = top + text.substr(startWithContext, 240).trim() + tail;
521
522 highlightWords.forEach((highlightWord) =>
523 _highlightText(summary, highlightWord, "highlighted")
524 );
525
526 return summary;
527 },
646528 };
647529
648 $(document).ready(function() {
649 Search.init();
650 });
530 _ready(Search.init);
44 * Sphinx stylesheet -- sphinxdoc theme. Originally created by
55 * Armin Ronacher for Werkzeug.
66 *
7 * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
7 * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
88 * :license: BSD, see LICENSE for details.
99 *
1010 */
3636 background-repeat: repeat-x;
3737 }
3838
39 div.documentwrapper {
40 float: left;
41 width: 100%;
42 }
43
3944 div.bodywrapper {
40 margin: 0 240px 0 0;
45 margin: 0 calc(230px + 10px) 0 0;
4146 border-right: 1px solid #ccc;
4247 }
4348
8590 }
8691
8792 div.sphinxsidebar {
88 margin: 0;
8993 padding: 0.5em 15px 15px 0;
90 width: 210px;
94 width: calc(230px - 20px);
9195 float: right;
9296 font-size: 1em;
9397 text-align: left;
133137
134138 /* -- body styles ----------------------------------------------------------- */
135139
136 p {
140 p {
137141 margin: 0.8em 0 0.5em 0;
138142 }
139143
242246 line-height: 120%;
243247 padding: 0.5em;
244248 border: 1px solid #ccc;
245 background-color: #f8f8f8;
246249 }
247250
248251 pre a {
262265 border: 1px solid #ccc;
263266 }
264267
265 div.topic {
268 div.topic, aside.topic {
266269 background-color: #f8f8f8;
267270 }
268271
0 (function (global, factory) {
1 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
2 typeof define === 'function' && define.amd ? define('underscore', factory) :
3 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () {
4 var current = global._;
5 var exports = global._ = factory();
6 exports.noConflict = function () { global._ = current; return exports; };
7 }()));
8 }(this, (function () {
9 // Underscore.js 1.13.1
10 // https://underscorejs.org
11 // (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
12 // Underscore may be freely distributed under the MIT license.
13
14 // Current version.
15 var VERSION = '1.13.1';
16
17 // Establish the root object, `window` (`self`) in the browser, `global`
18 // on the server, or `this` in some virtual machines. We use `self`
19 // instead of `window` for `WebWorker` support.
20 var root = typeof self == 'object' && self.self === self && self ||
21 typeof global == 'object' && global.global === global && global ||
22 Function('return this')() ||
23 {};
24
25 // Save bytes in the minified (but not gzipped) version:
26 var ArrayProto = Array.prototype, ObjProto = Object.prototype;
27 var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
28
29 // Create quick reference variables for speed access to core prototypes.
30 var push = ArrayProto.push,
31 slice = ArrayProto.slice,
32 toString = ObjProto.toString,
33 hasOwnProperty = ObjProto.hasOwnProperty;
34
35 // Modern feature detection.
36 var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',
37 supportsDataView = typeof DataView !== 'undefined';
38
39 // All **ECMAScript 5+** native function implementations that we hope to use
40 // are declared here.
41 var nativeIsArray = Array.isArray,
42 nativeKeys = Object.keys,
43 nativeCreate = Object.create,
44 nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;
45
46 // Create references to these builtin functions because we override them.
47 var _isNaN = isNaN,
48 _isFinite = isFinite;
49
50 // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
51 var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
52 var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
53 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
54
55 // The largest integer that can be represented exactly.
56 var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
57
58 // Some functions take a variable number of arguments, or a few expected
59 // arguments at the beginning and then a variable number of values to operate
60 // on. This helper accumulates all remaining arguments past the function’s
61 // argument length (or an explicit `startIndex`), into an array that becomes
62 // the last argument. Similar to ES6’s "rest parameter".
63 function restArguments(func, startIndex) {
64 startIndex = startIndex == null ? func.length - 1 : +startIndex;
65 return function() {
66 var length = Math.max(arguments.length - startIndex, 0),
67 rest = Array(length),
68 index = 0;
69 for (; index < length; index++) {
70 rest[index] = arguments[index + startIndex];
71 }
72 switch (startIndex) {
73 case 0: return func.call(this, rest);
74 case 1: return func.call(this, arguments[0], rest);
75 case 2: return func.call(this, arguments[0], arguments[1], rest);
76 }
77 var args = Array(startIndex + 1);
78 for (index = 0; index < startIndex; index++) {
79 args[index] = arguments[index];
80 }
81 args[startIndex] = rest;
82 return func.apply(this, args);
83 };
84 }
85
86 // Is a given variable an object?
87 function isObject(obj) {
88 var type = typeof obj;
89 return type === 'function' || type === 'object' && !!obj;
90 }
91
92 // Is a given value equal to null?
93 function isNull(obj) {
94 return obj === null;
95 }
96
97 // Is a given variable undefined?
98 function isUndefined(obj) {
99 return obj === void 0;
100 }
101
102 // Is a given value a boolean?
103 function isBoolean(obj) {
104 return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
105 }
106
107 // Is a given value a DOM element?
108 function isElement(obj) {
109 return !!(obj && obj.nodeType === 1);
110 }
111
112 // Internal function for creating a `toString`-based type tester.
113 function tagTester(name) {
114 var tag = '[object ' + name + ']';
115 return function(obj) {
116 return toString.call(obj) === tag;
117 };
118 }
119
120 var isString = tagTester('String');
121
122 var isNumber = tagTester('Number');
123
124 var isDate = tagTester('Date');
125
126 var isRegExp = tagTester('RegExp');
127
128 var isError = tagTester('Error');
129
130 var isSymbol = tagTester('Symbol');
131
132 var isArrayBuffer = tagTester('ArrayBuffer');
133
134 var isFunction = tagTester('Function');
135
136 // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old
137 // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
138 var nodelist = root.document && root.document.childNodes;
139 if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
140 isFunction = function(obj) {
141 return typeof obj == 'function' || false;
142 };
143 }
144
145 var isFunction$1 = isFunction;
146
147 var hasObjectTag = tagTester('Object');
148
149 // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.
150 // In IE 11, the most common among them, this problem also applies to
151 // `Map`, `WeakMap` and `Set`.
152 var hasStringTagBug = (
153 supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))
154 ),
155 isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));
156
157 var isDataView = tagTester('DataView');
158
159 // In IE 10 - Edge 13, we need a different heuristic
160 // to determine whether an object is a `DataView`.
161 function ie10IsDataView(obj) {
162 return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);
163 }
164
165 var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);
166
167 // Is a given value an array?
168 // Delegates to ECMA5's native `Array.isArray`.
169 var isArray = nativeIsArray || tagTester('Array');
170
171 // Internal function to check whether `key` is an own property name of `obj`.
172 function has$1(obj, key) {
173 return obj != null && hasOwnProperty.call(obj, key);
174 }
175
176 var isArguments = tagTester('Arguments');
177
178 // Define a fallback version of the method in browsers (ahem, IE < 9), where
179 // there isn't any inspectable "Arguments" type.
180 (function() {
181 if (!isArguments(arguments)) {
182 isArguments = function(obj) {
183 return has$1(obj, 'callee');
184 };
185 }
186 }());
187
188 var isArguments$1 = isArguments;
189
190 // Is a given object a finite number?
191 function isFinite$1(obj) {
192 return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));
193 }
194
195 // Is the given value `NaN`?
196 function isNaN$1(obj) {
197 return isNumber(obj) && _isNaN(obj);
198 }
199
200 // Predicate-generating function. Often useful outside of Underscore.
201 function constant(value) {
202 return function() {
203 return value;
204 };
205 }
206
207 // Common internal logic for `isArrayLike` and `isBufferLike`.
208 function createSizePropertyCheck(getSizeProperty) {
209 return function(collection) {
210 var sizeProperty = getSizeProperty(collection);
211 return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;
212 }
213 }
214
215 // Internal helper to generate a function to obtain property `key` from `obj`.
216 function shallowProperty(key) {
217 return function(obj) {
218 return obj == null ? void 0 : obj[key];
219 };
220 }
221
222 // Internal helper to obtain the `byteLength` property of an object.
223 var getByteLength = shallowProperty('byteLength');
224
225 // Internal helper to determine whether we should spend extensive checks against
226 // `ArrayBuffer` et al.
227 var isBufferLike = createSizePropertyCheck(getByteLength);
228
229 // Is a given value a typed array?
230 var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;
231 function isTypedArray(obj) {
232 // `ArrayBuffer.isView` is the most future-proof, so use it when available.
233 // Otherwise, fall back on the above regular expression.
234 return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) :
235 isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));
236 }
237
238 var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);
239
240 // Internal helper to obtain the `length` property of an object.
241 var getLength = shallowProperty('length');
242
243 // Internal helper to create a simple lookup structure.
244 // `collectNonEnumProps` used to depend on `_.contains`, but this led to
245 // circular imports. `emulatedSet` is a one-off solution that only works for
246 // arrays of strings.
247 function emulatedSet(keys) {
248 var hash = {};
249 for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;
250 return {
251 contains: function(key) { return hash[key]; },
252 push: function(key) {
253 hash[key] = true;
254 return keys.push(key);
255 }
256 };
257 }
258
259 // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't
260 // be iterated by `for key in ...` and thus missed. Extends `keys` in place if
261 // needed.
262 function collectNonEnumProps(obj, keys) {
263 keys = emulatedSet(keys);
264 var nonEnumIdx = nonEnumerableProps.length;
265 var constructor = obj.constructor;
266 var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;
267
268 // Constructor is a special case.
269 var prop = 'constructor';
270 if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);
271
272 while (nonEnumIdx--) {
273 prop = nonEnumerableProps[nonEnumIdx];
274 if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {
275 keys.push(prop);
276 }
277 }
278 }
279
280 // Retrieve the names of an object's own properties.
281 // Delegates to **ECMAScript 5**'s native `Object.keys`.
282 function keys(obj) {
283 if (!isObject(obj)) return [];
284 if (nativeKeys) return nativeKeys(obj);
285 var keys = [];
286 for (var key in obj) if (has$1(obj, key)) keys.push(key);
287 // Ahem, IE < 9.
288 if (hasEnumBug) collectNonEnumProps(obj, keys);
289 return keys;
290 }
291
292 // Is a given array, string, or object empty?
293 // An "empty" object has no enumerable own-properties.
294 function isEmpty(obj) {
295 if (obj == null) return true;
296 // Skip the more expensive `toString`-based type checks if `obj` has no
297 // `.length`.
298 var length = getLength(obj);
299 if (typeof length == 'number' && (
300 isArray(obj) || isString(obj) || isArguments$1(obj)
301 )) return length === 0;
302 return getLength(keys(obj)) === 0;
303 }
304
305 // Returns whether an object has a given set of `key:value` pairs.
306 function isMatch(object, attrs) {
307 var _keys = keys(attrs), length = _keys.length;
308 if (object == null) return !length;
309 var obj = Object(object);
310 for (var i = 0; i < length; i++) {
311 var key = _keys[i];
312 if (attrs[key] !== obj[key] || !(key in obj)) return false;
313 }
314 return true;
315 }
316
317 // If Underscore is called as a function, it returns a wrapped object that can
318 // be used OO-style. This wrapper holds altered versions of all functions added
319 // through `_.mixin`. Wrapped objects may be chained.
320 function _$1(obj) {
321 if (obj instanceof _$1) return obj;
322 if (!(this instanceof _$1)) return new _$1(obj);
323 this._wrapped = obj;
324 }
325
326 _$1.VERSION = VERSION;
327
328 // Extracts the result from a wrapped and chained object.
329 _$1.prototype.value = function() {
330 return this._wrapped;
331 };
332
333 // Provide unwrapping proxies for some methods used in engine operations
334 // such as arithmetic and JSON stringification.
335 _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;
336
337 _$1.prototype.toString = function() {
338 return String(this._wrapped);
339 };
340
341 // Internal function to wrap or shallow-copy an ArrayBuffer,
342 // typed array or DataView to a new view, reusing the buffer.
343 function toBufferView(bufferSource) {
344 return new Uint8Array(
345 bufferSource.buffer || bufferSource,
346 bufferSource.byteOffset || 0,
347 getByteLength(bufferSource)
348 );
349 }
350
351 // We use this string twice, so give it a name for minification.
352 var tagDataView = '[object DataView]';
353
354 // Internal recursive comparison function for `_.isEqual`.
355 function eq(a, b, aStack, bStack) {
356 // Identical objects are equal. `0 === -0`, but they aren't identical.
357 // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).
358 if (a === b) return a !== 0 || 1 / a === 1 / b;
359 // `null` or `undefined` only equal to itself (strict comparison).
360 if (a == null || b == null) return false;
361 // `NaN`s are equivalent, but non-reflexive.
362 if (a !== a) return b !== b;
363 // Exhaust primitive checks
364 var type = typeof a;
365 if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
366 return deepEq(a, b, aStack, bStack);
367 }
368
369 // Internal recursive comparison function for `_.isEqual`.
370 function deepEq(a, b, aStack, bStack) {
371 // Unwrap any wrapped objects.
372 if (a instanceof _$1) a = a._wrapped;
373 if (b instanceof _$1) b = b._wrapped;
374 // Compare `[[Class]]` names.
375 var className = toString.call(a);
376 if (className !== toString.call(b)) return false;
377 // Work around a bug in IE 10 - Edge 13.
378 if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {
379 if (!isDataView$1(b)) return false;
380 className = tagDataView;
381 }
382 switch (className) {
383 // These types are compared by value.
384 case '[object RegExp]':
385 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
386 case '[object String]':
387 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
388 // equivalent to `new String("5")`.
389 return '' + a === '' + b;
390 case '[object Number]':
391 // `NaN`s are equivalent, but non-reflexive.
392 // Object(NaN) is equivalent to NaN.
393 if (+a !== +a) return +b !== +b;
394 // An `egal` comparison is performed for other numeric values.
395 return +a === 0 ? 1 / +a === 1 / b : +a === +b;
396 case '[object Date]':
397 case '[object Boolean]':
398 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
399 // millisecond representations. Note that invalid dates with millisecond representations
400 // of `NaN` are not equivalent.
401 return +a === +b;
402 case '[object Symbol]':
403 return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
404 case '[object ArrayBuffer]':
405 case tagDataView:
406 // Coerce to typed array so we can fall through.
407 return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);
408 }
409
410 var areArrays = className === '[object Array]';
411 if (!areArrays && isTypedArray$1(a)) {
412 var byteLength = getByteLength(a);
413 if (byteLength !== getByteLength(b)) return false;
414 if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;
415 areArrays = true;
416 }
417 if (!areArrays) {
418 if (typeof a != 'object' || typeof b != 'object') return false;
419
420 // Objects with different constructors are not equivalent, but `Object`s or `Array`s
421 // from different frames are.
422 var aCtor = a.constructor, bCtor = b.constructor;
423 if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor &&
424 isFunction$1(bCtor) && bCtor instanceof bCtor)
425 && ('constructor' in a && 'constructor' in b)) {
426 return false;
427 }
428 }
429 // Assume equality for cyclic structures. The algorithm for detecting cyclic
430 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
431
432 // Initializing stack of traversed objects.
433 // It's done here since we only need them for objects and arrays comparison.
434 aStack = aStack || [];
435 bStack = bStack || [];
436 var length = aStack.length;
437 while (length--) {
438 // Linear search. Performance is inversely proportional to the number of
439 // unique nested structures.
440 if (aStack[length] === a) return bStack[length] === b;
441 }
442
443 // Add the first object to the stack of traversed objects.
444 aStack.push(a);
445 bStack.push(b);
446
447 // Recursively compare objects and arrays.
448 if (areArrays) {
449 // Compare array lengths to determine if a deep comparison is necessary.
450 length = a.length;
451 if (length !== b.length) return false;
452 // Deep compare the contents, ignoring non-numeric properties.
453 while (length--) {
454 if (!eq(a[length], b[length], aStack, bStack)) return false;
455 }
456 } else {
457 // Deep compare objects.
458 var _keys = keys(a), key;
459 length = _keys.length;
460 // Ensure that both objects contain the same number of properties before comparing deep equality.
461 if (keys(b).length !== length) return false;
462 while (length--) {
463 // Deep compare each member
464 key = _keys[length];
465 if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
466 }
467 }
468 // Remove the first object from the stack of traversed objects.
469 aStack.pop();
470 bStack.pop();
471 return true;
472 }
473
474 // Perform a deep comparison to check if two objects are equal.
475 function isEqual(a, b) {
476 return eq(a, b);
477 }
478
479 // Retrieve all the enumerable property names of an object.
480 function allKeys(obj) {
481 if (!isObject(obj)) return [];
482 var keys = [];
483 for (var key in obj) keys.push(key);
484 // Ahem, IE < 9.
485 if (hasEnumBug) collectNonEnumProps(obj, keys);
486 return keys;
487 }
488
489 // Since the regular `Object.prototype.toString` type tests don't work for
490 // some types in IE 11, we use a fingerprinting heuristic instead, based
491 // on the methods. It's not great, but it's the best we got.
492 // The fingerprint method lists are defined below.
493 function ie11fingerprint(methods) {
494 var length = getLength(methods);
495 return function(obj) {
496 if (obj == null) return false;
497 // `Map`, `WeakMap` and `Set` have no enumerable keys.
498 var keys = allKeys(obj);
499 if (getLength(keys)) return false;
500 for (var i = 0; i < length; i++) {
501 if (!isFunction$1(obj[methods[i]])) return false;
502 }
503 // If we are testing against `WeakMap`, we need to ensure that
504 // `obj` doesn't have a `forEach` method in order to distinguish
505 // it from a regular `Map`.
506 return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);
507 };
508 }
509
510 // In the interest of compact minification, we write
511 // each string in the fingerprints only once.
512 var forEachName = 'forEach',
513 hasName = 'has',
514 commonInit = ['clear', 'delete'],
515 mapTail = ['get', hasName, 'set'];
516
517 // `Map`, `WeakMap` and `Set` each have slightly different
518 // combinations of the above sublists.
519 var mapMethods = commonInit.concat(forEachName, mapTail),
520 weakMapMethods = commonInit.concat(mapTail),
521 setMethods = ['add'].concat(commonInit, forEachName, hasName);
522
523 var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');
524
525 var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');
526
527 var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');
528
529 var isWeakSet = tagTester('WeakSet');
530
531 // Retrieve the values of an object's properties.
532 function values(obj) {
533 var _keys = keys(obj);
534 var length = _keys.length;
535 var values = Array(length);
536 for (var i = 0; i < length; i++) {
537 values[i] = obj[_keys[i]];
538 }
539 return values;
540 }
541
542 // Convert an object into a list of `[key, value]` pairs.
543 // The opposite of `_.object` with one argument.
544 function pairs(obj) {
545 var _keys = keys(obj);
546 var length = _keys.length;
547 var pairs = Array(length);
548 for (var i = 0; i < length; i++) {
549 pairs[i] = [_keys[i], obj[_keys[i]]];
550 }
551 return pairs;
552 }
553
554 // Invert the keys and values of an object. The values must be serializable.
555 function invert(obj) {
556 var result = {};
557 var _keys = keys(obj);
558 for (var i = 0, length = _keys.length; i < length; i++) {
559 result[obj[_keys[i]]] = _keys[i];
560 }
561 return result;
562 }
563
564 // Return a sorted list of the function names available on the object.
565 function functions(obj) {
566 var names = [];
567 for (var key in obj) {
568 if (isFunction$1(obj[key])) names.push(key);
569 }
570 return names.sort();
571 }
572
573 // An internal function for creating assigner functions.
574 function createAssigner(keysFunc, defaults) {
575 return function(obj) {
576 var length = arguments.length;
577 if (defaults) obj = Object(obj);
578 if (length < 2 || obj == null) return obj;
579 for (var index = 1; index < length; index++) {
580 var source = arguments[index],
581 keys = keysFunc(source),
582 l = keys.length;
583 for (var i = 0; i < l; i++) {
584 var key = keys[i];
585 if (!defaults || obj[key] === void 0) obj[key] = source[key];
586 }
587 }
588 return obj;
589 };
590 }
591
592 // Extend a given object with all the properties in passed-in object(s).
593 var extend = createAssigner(allKeys);
594
595 // Assigns a given object with all the own properties in the passed-in
596 // object(s).
597 // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
598 var extendOwn = createAssigner(keys);
599
600 // Fill in a given object with default properties.
601 var defaults = createAssigner(allKeys, true);
602
603 // Create a naked function reference for surrogate-prototype-swapping.
604 function ctor() {
605 return function(){};
606 }
607
608 // An internal function for creating a new object that inherits from another.
609 function baseCreate(prototype) {
610 if (!isObject(prototype)) return {};
611 if (nativeCreate) return nativeCreate(prototype);
612 var Ctor = ctor();
613 Ctor.prototype = prototype;
614 var result = new Ctor;
615 Ctor.prototype = null;
616 return result;
617 }
618
619 // Creates an object that inherits from the given prototype object.
620 // If additional properties are provided then they will be added to the
621 // created object.
622 function create(prototype, props) {
623 var result = baseCreate(prototype);
624 if (props) extendOwn(result, props);
625 return result;
626 }
627
628 // Create a (shallow-cloned) duplicate of an object.
629 function clone(obj) {
630 if (!isObject(obj)) return obj;
631 return isArray(obj) ? obj.slice() : extend({}, obj);
632 }
633
634 // Invokes `interceptor` with the `obj` and then returns `obj`.
635 // The primary purpose of this method is to "tap into" a method chain, in
636 // order to perform operations on intermediate results within the chain.
637 function tap(obj, interceptor) {
638 interceptor(obj);
639 return obj;
640 }
641
642 // Normalize a (deep) property `path` to array.
643 // Like `_.iteratee`, this function can be customized.
644 function toPath$1(path) {
645 return isArray(path) ? path : [path];
646 }
647 _$1.toPath = toPath$1;
648
649 // Internal wrapper for `_.toPath` to enable minification.
650 // Similar to `cb` for `_.iteratee`.
651 function toPath(path) {
652 return _$1.toPath(path);
653 }
654
655 // Internal function to obtain a nested property in `obj` along `path`.
656 function deepGet(obj, path) {
657 var length = path.length;
658 for (var i = 0; i < length; i++) {
659 if (obj == null) return void 0;
660 obj = obj[path[i]];
661 }
662 return length ? obj : void 0;
663 }
664
665 // Get the value of the (deep) property on `path` from `object`.
666 // If any property in `path` does not exist or if the value is
667 // `undefined`, return `defaultValue` instead.
668 // The `path` is normalized through `_.toPath`.
669 function get(object, path, defaultValue) {
670 var value = deepGet(object, toPath(path));
671 return isUndefined(value) ? defaultValue : value;
672 }
673
674 // Shortcut function for checking if an object has a given property directly on
675 // itself (in other words, not on a prototype). Unlike the internal `has`
676 // function, this public version can also traverse nested properties.
677 function has(obj, path) {
678 path = toPath(path);
679 var length = path.length;
680 for (var i = 0; i < length; i++) {
681 var key = path[i];
682 if (!has$1(obj, key)) return false;
683 obj = obj[key];
684 }
685 return !!length;
686 }
687
688 // Keep the identity function around for default iteratees.
689 function identity(value) {
690 return value;
691 }
692
693 // Returns a predicate for checking whether an object has a given set of
694 // `key:value` pairs.
695 function matcher(attrs) {
696 attrs = extendOwn({}, attrs);
697 return function(obj) {
698 return isMatch(obj, attrs);
699 };
700 }
701
702 // Creates a function that, when passed an object, will traverse that object’s
703 // properties down the given `path`, specified as an array of keys or indices.
704 function property(path) {
705 path = toPath(path);
706 return function(obj) {
707 return deepGet(obj, path);
708 };
709 }
710
711 // Internal function that returns an efficient (for current engines) version
712 // of the passed-in callback, to be repeatedly applied in other Underscore
713 // functions.
714 function optimizeCb(func, context, argCount) {
715 if (context === void 0) return func;
716 switch (argCount == null ? 3 : argCount) {
717 case 1: return function(value) {
718 return func.call(context, value);
719 };
720 // The 2-argument case is omitted because we’re not using it.
721 case 3: return function(value, index, collection) {
722 return func.call(context, value, index, collection);
723 };
724 case 4: return function(accumulator, value, index, collection) {
725 return func.call(context, accumulator, value, index, collection);
726 };
727 }
728 return function() {
729 return func.apply(context, arguments);
730 };
731 }
732
733 // An internal function to generate callbacks that can be applied to each
734 // element in a collection, returning the desired result — either `_.identity`,
735 // an arbitrary callback, a property matcher, or a property accessor.
736 function baseIteratee(value, context, argCount) {
737 if (value == null) return identity;
738 if (isFunction$1(value)) return optimizeCb(value, context, argCount);
739 if (isObject(value) && !isArray(value)) return matcher(value);
740 return property(value);
741 }
742
743 // External wrapper for our callback generator. Users may customize
744 // `_.iteratee` if they want additional predicate/iteratee shorthand styles.
745 // This abstraction hides the internal-only `argCount` argument.
746 function iteratee(value, context) {
747 return baseIteratee(value, context, Infinity);
748 }
749 _$1.iteratee = iteratee;
750
751 // The function we call internally to generate a callback. It invokes
752 // `_.iteratee` if overridden, otherwise `baseIteratee`.
753 function cb(value, context, argCount) {
754 if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);
755 return baseIteratee(value, context, argCount);
756 }
757
758 // Returns the results of applying the `iteratee` to each element of `obj`.
759 // In contrast to `_.map` it returns an object.
760 function mapObject(obj, iteratee, context) {
761 iteratee = cb(iteratee, context);
762 var _keys = keys(obj),
763 length = _keys.length,
764 results = {};
765 for (var index = 0; index < length; index++) {
766 var currentKey = _keys[index];
767 results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
768 }
769 return results;
770 }
771
772 // Predicate-generating function. Often useful outside of Underscore.
773 function noop(){}
774
775 // Generates a function for a given object that returns a given property.
776 function propertyOf(obj) {
777 if (obj == null) return noop;
778 return function(path) {
779 return get(obj, path);
780 };
781 }
782
783 // Run a function **n** times.
784 function times(n, iteratee, context) {
785 var accum = Array(Math.max(0, n));
786 iteratee = optimizeCb(iteratee, context, 1);
787 for (var i = 0; i < n; i++) accum[i] = iteratee(i);
788 return accum;
789 }
790
791 // Return a random integer between `min` and `max` (inclusive).
792 function random(min, max) {
793 if (max == null) {
794 max = min;
795 min = 0;
796 }
797 return min + Math.floor(Math.random() * (max - min + 1));
798 }
799
800 // A (possibly faster) way to get the current timestamp as an integer.
801 var now = Date.now || function() {
802 return new Date().getTime();
803 };
804
805 // Internal helper to generate functions for escaping and unescaping strings
806 // to/from HTML interpolation.
807 function createEscaper(map) {
808 var escaper = function(match) {
809 return map[match];
810 };
811 // Regexes for identifying a key that needs to be escaped.
812 var source = '(?:' + keys(map).join('|') + ')';
813 var testRegexp = RegExp(source);
814 var replaceRegexp = RegExp(source, 'g');
815 return function(string) {
816 string = string == null ? '' : '' + string;
817 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
818 };
819 }
820
821 // Internal list of HTML entities for escaping.
822 var escapeMap = {
823 '&': '&amp;',
824 '<': '&lt;',
825 '>': '&gt;',
826 '"': '&quot;',
827 "'": '&#x27;',
828 '`': '&#x60;'
829 };
830
831 // Function for escaping strings to HTML interpolation.
832 var _escape = createEscaper(escapeMap);
833
834 // Internal list of HTML entities for unescaping.
835 var unescapeMap = invert(escapeMap);
836
837 // Function for unescaping strings from HTML interpolation.
838 var _unescape = createEscaper(unescapeMap);
839
840 // By default, Underscore uses ERB-style template delimiters. Change the
841 // following template settings to use alternative delimiters.
842 var templateSettings = _$1.templateSettings = {
843 evaluate: /<%([\s\S]+?)%>/g,
844 interpolate: /<%=([\s\S]+?)%>/g,
845 escape: /<%-([\s\S]+?)%>/g
846 };
847
848 // When customizing `_.templateSettings`, if you don't want to define an
849 // interpolation, evaluation or escaping regex, we need one that is
850 // guaranteed not to match.
851 var noMatch = /(.)^/;
852
853 // Certain characters need to be escaped so that they can be put into a
854 // string literal.
855 var escapes = {
856 "'": "'",
857 '\\': '\\',
858 '\r': 'r',
859 '\n': 'n',
860 '\u2028': 'u2028',
861 '\u2029': 'u2029'
862 };
863
864 var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
865
866 function escapeChar(match) {
867 return '\\' + escapes[match];
868 }
869
870 // In order to prevent third-party code injection through
871 // `_.templateSettings.variable`, we test it against the following regular
872 // expression. It is intentionally a bit more liberal than just matching valid
873 // identifiers, but still prevents possible loopholes through defaults or
874 // destructuring assignment.
875 var bareIdentifier = /^\s*(\w|\$)+\s*$/;
876
877 // JavaScript micro-templating, similar to John Resig's implementation.
878 // Underscore templating handles arbitrary delimiters, preserves whitespace,
879 // and correctly escapes quotes within interpolated code.
880 // NB: `oldSettings` only exists for backwards compatibility.
881 function template(text, settings, oldSettings) {
882 if (!settings && oldSettings) settings = oldSettings;
883 settings = defaults({}, settings, _$1.templateSettings);
884
885 // Combine delimiters into one regular expression via alternation.
886 var matcher = RegExp([
887 (settings.escape || noMatch).source,
888 (settings.interpolate || noMatch).source,
889 (settings.evaluate || noMatch).source
890 ].join('|') + '|$', 'g');
891
892 // Compile the template source, escaping string literals appropriately.
893 var index = 0;
894 var source = "__p+='";
895 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
896 source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
897 index = offset + match.length;
898
899 if (escape) {
900 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
901 } else if (interpolate) {
902 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
903 } else if (evaluate) {
904 source += "';\n" + evaluate + "\n__p+='";
905 }
906
907 // Adobe VMs need the match returned to produce the correct offset.
908 return match;
909 });
910 source += "';\n";
911
912 var argument = settings.variable;
913 if (argument) {
914 // Insure against third-party code injection. (CVE-2021-23358)
915 if (!bareIdentifier.test(argument)) throw new Error(
916 'variable is not a bare identifier: ' + argument
917 );
918 } else {
919 // If a variable is not specified, place data values in local scope.
920 source = 'with(obj||{}){\n' + source + '}\n';
921 argument = 'obj';
922 }
923
924 source = "var __t,__p='',__j=Array.prototype.join," +
925 "print=function(){__p+=__j.call(arguments,'');};\n" +
926 source + 'return __p;\n';
927
928 var render;
929 try {
930 render = new Function(argument, '_', source);
931 } catch (e) {
932 e.source = source;
933 throw e;
934 }
935
936 var template = function(data) {
937 return render.call(this, data, _$1);
938 };
939
940 // Provide the compiled source as a convenience for precompilation.
941 template.source = 'function(' + argument + '){\n' + source + '}';
942
943 return template;
944 }
945
946 // Traverses the children of `obj` along `path`. If a child is a function, it
947 // is invoked with its parent as context. Returns the value of the final
948 // child, or `fallback` if any child is undefined.
949 function result(obj, path, fallback) {
950 path = toPath(path);
951 var length = path.length;
952 if (!length) {
953 return isFunction$1(fallback) ? fallback.call(obj) : fallback;
954 }
955 for (var i = 0; i < length; i++) {
956 var prop = obj == null ? void 0 : obj[path[i]];
957 if (prop === void 0) {
958 prop = fallback;
959 i = length; // Ensure we don't continue iterating.
960 }
961 obj = isFunction$1(prop) ? prop.call(obj) : prop;
962 }
963 return obj;
964 }
965
966 // Generate a unique integer id (unique within the entire client session).
967 // Useful for temporary DOM ids.
968 var idCounter = 0;
969 function uniqueId(prefix) {
970 var id = ++idCounter + '';
971 return prefix ? prefix + id : id;
972 }
973
974 // Start chaining a wrapped Underscore object.
975 function chain(obj) {
976 var instance = _$1(obj);
977 instance._chain = true;
978 return instance;
979 }
980
981 // Internal function to execute `sourceFunc` bound to `context` with optional
982 // `args`. Determines whether to execute a function as a constructor or as a
983 // normal function.
984 function executeBound(sourceFunc, boundFunc, context, callingContext, args) {
985 if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
986 var self = baseCreate(sourceFunc.prototype);
987 var result = sourceFunc.apply(self, args);
988 if (isObject(result)) return result;
989 return self;
990 }
991
992 // Partially apply a function by creating a version that has had some of its
993 // arguments pre-filled, without changing its dynamic `this` context. `_` acts
994 // as a placeholder by default, allowing any combination of arguments to be
995 // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
996 var partial = restArguments(function(func, boundArgs) {
997 var placeholder = partial.placeholder;
998 var bound = function() {
999 var position = 0, length = boundArgs.length;
1000 var args = Array(length);
1001 for (var i = 0; i < length; i++) {
1002 args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
1003 }
1004 while (position < arguments.length) args.push(arguments[position++]);
1005 return executeBound(func, bound, this, this, args);
1006 };
1007 return bound;
1008 });
1009
1010 partial.placeholder = _$1;
1011
1012 // Create a function bound to a given object (assigning `this`, and arguments,
1013 // optionally).
1014 var bind = restArguments(function(func, context, args) {
1015 if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');
1016 var bound = restArguments(function(callArgs) {
1017 return executeBound(func, bound, context, this, args.concat(callArgs));
1018 });
1019 return bound;
1020 });
1021
1022 // Internal helper for collection methods to determine whether a collection
1023 // should be iterated as an array or as an object.
1024 // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
1025 // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
1026 var isArrayLike = createSizePropertyCheck(getLength);
1027
1028 // Internal implementation of a recursive `flatten` function.
1029 function flatten$1(input, depth, strict, output) {
1030 output = output || [];
1031 if (!depth && depth !== 0) {
1032 depth = Infinity;
1033 } else if (depth <= 0) {
1034 return output.concat(input);
1035 }
1036 var idx = output.length;
1037 for (var i = 0, length = getLength(input); i < length; i++) {
1038 var value = input[i];
1039 if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {
1040 // Flatten current level of array or arguments object.
1041 if (depth > 1) {
1042 flatten$1(value, depth - 1, strict, output);
1043 idx = output.length;
1044 } else {
1045 var j = 0, len = value.length;
1046 while (j < len) output[idx++] = value[j++];
1047 }
1048 } else if (!strict) {
1049 output[idx++] = value;
1050 }
1051 }
1052 return output;
1053 }
1054
1055 // Bind a number of an object's methods to that object. Remaining arguments
1056 // are the method names to be bound. Useful for ensuring that all callbacks
1057 // defined on an object belong to it.
1058 var bindAll = restArguments(function(obj, keys) {
1059 keys = flatten$1(keys, false, false);
1060 var index = keys.length;
1061 if (index < 1) throw new Error('bindAll must be passed function names');
1062 while (index--) {
1063 var key = keys[index];
1064 obj[key] = bind(obj[key], obj);
1065 }
1066 return obj;
1067 });
1068
1069 // Memoize an expensive function by storing its results.
1070 function memoize(func, hasher) {
1071 var memoize = function(key) {
1072 var cache = memoize.cache;
1073 var address = '' + (hasher ? hasher.apply(this, arguments) : key);
1074 if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);
1075 return cache[address];
1076 };
1077 memoize.cache = {};
1078 return memoize;
1079 }
1080
1081 // Delays a function for the given number of milliseconds, and then calls
1082 // it with the arguments supplied.
1083 var delay = restArguments(function(func, wait, args) {
1084 return setTimeout(function() {
1085 return func.apply(null, args);
1086 }, wait);
1087 });
1088
1089 // Defers a function, scheduling it to run after the current call stack has
1090 // cleared.
1091 var defer = partial(delay, _$1, 1);
1092
1093 // Returns a function, that, when invoked, will only be triggered at most once
1094 // during a given window of time. Normally, the throttled function will run
1095 // as much as it can, without ever going more than once per `wait` duration;
1096 // but if you'd like to disable the execution on the leading edge, pass
1097 // `{leading: false}`. To disable execution on the trailing edge, ditto.
1098 function throttle(func, wait, options) {
1099 var timeout, context, args, result;
1100 var previous = 0;
1101 if (!options) options = {};
1102
1103 var later = function() {
1104 previous = options.leading === false ? 0 : now();
1105 timeout = null;
1106 result = func.apply(context, args);
1107 if (!timeout) context = args = null;
1108 };
1109
1110 var throttled = function() {
1111 var _now = now();
1112 if (!previous && options.leading === false) previous = _now;
1113 var remaining = wait - (_now - previous);
1114 context = this;
1115 args = arguments;
1116 if (remaining <= 0 || remaining > wait) {
1117 if (timeout) {
1118 clearTimeout(timeout);
1119 timeout = null;
1120 }
1121 previous = _now;
1122 result = func.apply(context, args);
1123 if (!timeout) context = args = null;
1124 } else if (!timeout && options.trailing !== false) {
1125 timeout = setTimeout(later, remaining);
1126 }
1127 return result;
1128 };
1129
1130 throttled.cancel = function() {
1131 clearTimeout(timeout);
1132 previous = 0;
1133 timeout = context = args = null;
1134 };
1135
1136 return throttled;
1137 }
1138
1139 // When a sequence of calls of the returned function ends, the argument
1140 // function is triggered. The end of a sequence is defined by the `wait`
1141 // parameter. If `immediate` is passed, the argument function will be
1142 // triggered at the beginning of the sequence instead of at the end.
1143 function debounce(func, wait, immediate) {
1144 var timeout, previous, args, result, context;
1145
1146 var later = function() {
1147 var passed = now() - previous;
1148 if (wait > passed) {
1149 timeout = setTimeout(later, wait - passed);
1150 } else {
1151 timeout = null;
1152 if (!immediate) result = func.apply(context, args);
1153 // This check is needed because `func` can recursively invoke `debounced`.
1154 if (!timeout) args = context = null;
1155 }
1156 };
1157
1158 var debounced = restArguments(function(_args) {
1159 context = this;
1160 args = _args;
1161 previous = now();
1162 if (!timeout) {
1163 timeout = setTimeout(later, wait);
1164 if (immediate) result = func.apply(context, args);
1165 }
1166 return result;
1167 });
1168
1169 debounced.cancel = function() {
1170 clearTimeout(timeout);
1171 timeout = args = context = null;
1172 };
1173
1174 return debounced;
1175 }
1176
1177 // Returns the first function passed as an argument to the second,
1178 // allowing you to adjust arguments, run code before and after, and
1179 // conditionally execute the original function.
1180 function wrap(func, wrapper) {
1181 return partial(wrapper, func);
1182 }
1183
1184 // Returns a negated version of the passed-in predicate.
1185 function negate(predicate) {
1186 return function() {
1187 return !predicate.apply(this, arguments);
1188 };
1189 }
1190
1191 // Returns a function that is the composition of a list of functions, each
1192 // consuming the return value of the function that follows.
1193 function compose() {
1194 var args = arguments;
1195 var start = args.length - 1;
1196 return function() {
1197 var i = start;
1198 var result = args[start].apply(this, arguments);
1199 while (i--) result = args[i].call(this, result);
1200 return result;
1201 };
1202 }
1203
1204 // Returns a function that will only be executed on and after the Nth call.
1205 function after(times, func) {
1206 return function() {
1207 if (--times < 1) {
1208 return func.apply(this, arguments);
1209 }
1210 };
1211 }
1212
1213 // Returns a function that will only be executed up to (but not including) the
1214 // Nth call.
1215 function before(times, func) {
1216 var memo;
1217 return function() {
1218 if (--times > 0) {
1219 memo = func.apply(this, arguments);
1220 }
1221 if (times <= 1) func = null;
1222 return memo;
1223 };
1224 }
1225
1226 // Returns a function that will be executed at most one time, no matter how
1227 // often you call it. Useful for lazy initialization.
1228 var once = partial(before, 2);
1229
1230 // Returns the first key on an object that passes a truth test.
1231 function findKey(obj, predicate, context) {
1232 predicate = cb(predicate, context);
1233 var _keys = keys(obj), key;
1234 for (var i = 0, length = _keys.length; i < length; i++) {
1235 key = _keys[i];
1236 if (predicate(obj[key], key, obj)) return key;
1237 }
1238 }
1239
1240 // Internal function to generate `_.findIndex` and `_.findLastIndex`.
1241 function createPredicateIndexFinder(dir) {
1242 return function(array, predicate, context) {
1243 predicate = cb(predicate, context);
1244 var length = getLength(array);
1245 var index = dir > 0 ? 0 : length - 1;
1246 for (; index >= 0 && index < length; index += dir) {
1247 if (predicate(array[index], index, array)) return index;
1248 }
1249 return -1;
1250 };
1251 }
1252
1253 // Returns the first index on an array-like that passes a truth test.
1254 var findIndex = createPredicateIndexFinder(1);
1255
1256 // Returns the last index on an array-like that passes a truth test.
1257 var findLastIndex = createPredicateIndexFinder(-1);
1258
1259 // Use a comparator function to figure out the smallest index at which
1260 // an object should be inserted so as to maintain order. Uses binary search.
1261 function sortedIndex(array, obj, iteratee, context) {
1262 iteratee = cb(iteratee, context, 1);
1263 var value = iteratee(obj);
1264 var low = 0, high = getLength(array);
1265 while (low < high) {
1266 var mid = Math.floor((low + high) / 2);
1267 if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
1268 }
1269 return low;
1270 }
1271
1272 // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.
1273 function createIndexFinder(dir, predicateFind, sortedIndex) {
1274 return function(array, item, idx) {
1275 var i = 0, length = getLength(array);
1276 if (typeof idx == 'number') {
1277 if (dir > 0) {
1278 i = idx >= 0 ? idx : Math.max(idx + length, i);
1279 } else {
1280 length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
1281 }
1282 } else if (sortedIndex && idx && length) {
1283 idx = sortedIndex(array, item);
1284 return array[idx] === item ? idx : -1;
1285 }
1286 if (item !== item) {
1287 idx = predicateFind(slice.call(array, i, length), isNaN$1);
1288 return idx >= 0 ? idx + i : -1;
1289 }
1290 for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
1291 if (array[idx] === item) return idx;
1292 }
1293 return -1;
1294 };
1295 }
1296
1297 // Return the position of the first occurrence of an item in an array,
1298 // or -1 if the item is not included in the array.
1299 // If the array is large and already in sort order, pass `true`
1300 // for **isSorted** to use binary search.
1301 var indexOf = createIndexFinder(1, findIndex, sortedIndex);
1302
1303 // Return the position of the last occurrence of an item in an array,
1304 // or -1 if the item is not included in the array.
1305 var lastIndexOf = createIndexFinder(-1, findLastIndex);
1306
1307 // Return the first value which passes a truth test.
1308 function find(obj, predicate, context) {
1309 var keyFinder = isArrayLike(obj) ? findIndex : findKey;
1310 var key = keyFinder(obj, predicate, context);
1311 if (key !== void 0 && key !== -1) return obj[key];
1312 }
1313
1314 // Convenience version of a common use case of `_.find`: getting the first
1315 // object containing specific `key:value` pairs.
1316 function findWhere(obj, attrs) {
1317 return find(obj, matcher(attrs));
1318 }
1319
1320 // The cornerstone for collection functions, an `each`
1321 // implementation, aka `forEach`.
1322 // Handles raw objects in addition to array-likes. Treats all
1323 // sparse array-likes as if they were dense.
1324 function each(obj, iteratee, context) {
1325 iteratee = optimizeCb(iteratee, context);
1326 var i, length;
1327 if (isArrayLike(obj)) {
1328 for (i = 0, length = obj.length; i < length; i++) {
1329 iteratee(obj[i], i, obj);
1330 }
1331 } else {
1332 var _keys = keys(obj);
1333 for (i = 0, length = _keys.length; i < length; i++) {
1334 iteratee(obj[_keys[i]], _keys[i], obj);
1335 }
1336 }
1337 return obj;
1338 }
1339
1340 // Return the results of applying the iteratee to each element.
1341 function map(obj, iteratee, context) {
1342 iteratee = cb(iteratee, context);
1343 var _keys = !isArrayLike(obj) && keys(obj),
1344 length = (_keys || obj).length,
1345 results = Array(length);
1346 for (var index = 0; index < length; index++) {
1347 var currentKey = _keys ? _keys[index] : index;
1348 results[index] = iteratee(obj[currentKey], currentKey, obj);
1349 }
1350 return results;
1351 }
1352
1353 // Internal helper to create a reducing function, iterating left or right.
1354 function createReduce(dir) {
1355 // Wrap code that reassigns argument variables in a separate function than
1356 // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
1357 var reducer = function(obj, iteratee, memo, initial) {
1358 var _keys = !isArrayLike(obj) && keys(obj),
1359 length = (_keys || obj).length,
1360 index = dir > 0 ? 0 : length - 1;
1361 if (!initial) {
1362 memo = obj[_keys ? _keys[index] : index];
1363 index += dir;
1364 }
1365 for (; index >= 0 && index < length; index += dir) {
1366 var currentKey = _keys ? _keys[index] : index;
1367 memo = iteratee(memo, obj[currentKey], currentKey, obj);
1368 }
1369 return memo;
1370 };
1371
1372 return function(obj, iteratee, memo, context) {
1373 var initial = arguments.length >= 3;
1374 return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
1375 };
1376 }
1377
1378 // **Reduce** builds up a single result from a list of values, aka `inject`,
1379 // or `foldl`.
1380 var reduce = createReduce(1);
1381
1382 // The right-associative version of reduce, also known as `foldr`.
1383 var reduceRight = createReduce(-1);
1384
1385 // Return all the elements that pass a truth test.
1386 function filter(obj, predicate, context) {
1387 var results = [];
1388 predicate = cb(predicate, context);
1389 each(obj, function(value, index, list) {
1390 if (predicate(value, index, list)) results.push(value);
1391 });
1392 return results;
1393 }
1394
1395 // Return all the elements for which a truth test fails.
1396 function reject(obj, predicate, context) {
1397 return filter(obj, negate(cb(predicate)), context);
1398 }
1399
1400 // Determine whether all of the elements pass a truth test.
1401 function every(obj, predicate, context) {
1402 predicate = cb(predicate, context);
1403 var _keys = !isArrayLike(obj) && keys(obj),
1404 length = (_keys || obj).length;
1405 for (var index = 0; index < length; index++) {
1406 var currentKey = _keys ? _keys[index] : index;
1407 if (!predicate(obj[currentKey], currentKey, obj)) return false;
1408 }
1409 return true;
1410 }
1411
1412 // Determine if at least one element in the object passes a truth test.
1413 function some(obj, predicate, context) {
1414 predicate = cb(predicate, context);
1415 var _keys = !isArrayLike(obj) && keys(obj),
1416 length = (_keys || obj).length;
1417 for (var index = 0; index < length; index++) {
1418 var currentKey = _keys ? _keys[index] : index;
1419 if (predicate(obj[currentKey], currentKey, obj)) return true;
1420 }
1421 return false;
1422 }
1423
1424 // Determine if the array or object contains a given item (using `===`).
1425 function contains(obj, item, fromIndex, guard) {
1426 if (!isArrayLike(obj)) obj = values(obj);
1427 if (typeof fromIndex != 'number' || guard) fromIndex = 0;
1428 return indexOf(obj, item, fromIndex) >= 0;
1429 }
1430
1431 // Invoke a method (with arguments) on every item in a collection.
1432 var invoke = restArguments(function(obj, path, args) {
1433 var contextPath, func;
1434 if (isFunction$1(path)) {
1435 func = path;
1436 } else {
1437 path = toPath(path);
1438 contextPath = path.slice(0, -1);
1439 path = path[path.length - 1];
1440 }
1441 return map(obj, function(context) {
1442 var method = func;
1443 if (!method) {
1444 if (contextPath && contextPath.length) {
1445 context = deepGet(context, contextPath);
1446 }
1447 if (context == null) return void 0;
1448 method = context[path];
1449 }
1450 return method == null ? method : method.apply(context, args);
1451 });
1452 });
1453
1454 // Convenience version of a common use case of `_.map`: fetching a property.
1455 function pluck(obj, key) {
1456 return map(obj, property(key));
1457 }
1458
1459 // Convenience version of a common use case of `_.filter`: selecting only
1460 // objects containing specific `key:value` pairs.
1461 function where(obj, attrs) {
1462 return filter(obj, matcher(attrs));
1463 }
1464
1465 // Return the maximum element (or element-based computation).
1466 function max(obj, iteratee, context) {
1467 var result = -Infinity, lastComputed = -Infinity,
1468 value, computed;
1469 if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
1470 obj = isArrayLike(obj) ? obj : values(obj);
1471 for (var i = 0, length = obj.length; i < length; i++) {
1472 value = obj[i];
1473 if (value != null && value > result) {
1474 result = value;
1475 }
1476 }
1477 } else {
1478 iteratee = cb(iteratee, context);
1479 each(obj, function(v, index, list) {
1480 computed = iteratee(v, index, list);
1481 if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
1482 result = v;
1483 lastComputed = computed;
1484 }
1485 });
1486 }
1487 return result;
1488 }
1489
1490 // Return the minimum element (or element-based computation).
1491 function min(obj, iteratee, context) {
1492 var result = Infinity, lastComputed = Infinity,
1493 value, computed;
1494 if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
1495 obj = isArrayLike(obj) ? obj : values(obj);
1496 for (var i = 0, length = obj.length; i < length; i++) {
1497 value = obj[i];
1498 if (value != null && value < result) {
1499 result = value;
1500 }
1501 }
1502 } else {
1503 iteratee = cb(iteratee, context);
1504 each(obj, function(v, index, list) {
1505 computed = iteratee(v, index, list);
1506 if (computed < lastComputed || computed === Infinity && result === Infinity) {
1507 result = v;
1508 lastComputed = computed;
1509 }
1510 });
1511 }
1512 return result;
1513 }
1514
1515 // Sample **n** random values from a collection using the modern version of the
1516 // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
1517 // If **n** is not specified, returns a single random element.
1518 // The internal `guard` argument allows it to work with `_.map`.
1519 function sample(obj, n, guard) {
1520 if (n == null || guard) {
1521 if (!isArrayLike(obj)) obj = values(obj);
1522 return obj[random(obj.length - 1)];
1523 }
1524 var sample = isArrayLike(obj) ? clone(obj) : values(obj);
1525 var length = getLength(sample);
1526 n = Math.max(Math.min(n, length), 0);
1527 var last = length - 1;
1528 for (var index = 0; index < n; index++) {
1529 var rand = random(index, last);
1530 var temp = sample[index];
1531 sample[index] = sample[rand];
1532 sample[rand] = temp;
1533 }
1534 return sample.slice(0, n);
1535 }
1536
1537 // Shuffle a collection.
1538 function shuffle(obj) {
1539 return sample(obj, Infinity);
1540 }
1541
1542 // Sort the object's values by a criterion produced by an iteratee.
1543 function sortBy(obj, iteratee, context) {
1544 var index = 0;
1545 iteratee = cb(iteratee, context);
1546 return pluck(map(obj, function(value, key, list) {
1547 return {
1548 value: value,
1549 index: index++,
1550 criteria: iteratee(value, key, list)
1551 };
1552 }).sort(function(left, right) {
1553 var a = left.criteria;
1554 var b = right.criteria;
1555 if (a !== b) {
1556 if (a > b || a === void 0) return 1;
1557 if (a < b || b === void 0) return -1;
1558 }
1559 return left.index - right.index;
1560 }), 'value');
1561 }
1562
1563 // An internal function used for aggregate "group by" operations.
1564 function group(behavior, partition) {
1565 return function(obj, iteratee, context) {
1566 var result = partition ? [[], []] : {};
1567 iteratee = cb(iteratee, context);
1568 each(obj, function(value, index) {
1569 var key = iteratee(value, index, obj);
1570 behavior(result, value, key);
1571 });
1572 return result;
1573 };
1574 }
1575
1576 // Groups the object's values by a criterion. Pass either a string attribute
1577 // to group by, or a function that returns the criterion.
1578 var groupBy = group(function(result, value, key) {
1579 if (has$1(result, key)) result[key].push(value); else result[key] = [value];
1580 });
1581
1582 // Indexes the object's values by a criterion, similar to `_.groupBy`, but for
1583 // when you know that your index values will be unique.
1584 var indexBy = group(function(result, value, key) {
1585 result[key] = value;
1586 });
1587
1588 // Counts instances of an object that group by a certain criterion. Pass
1589 // either a string attribute to count by, or a function that returns the
1590 // criterion.
1591 var countBy = group(function(result, value, key) {
1592 if (has$1(result, key)) result[key]++; else result[key] = 1;
1593 });
1594
1595 // Split a collection into two arrays: one whose elements all pass the given
1596 // truth test, and one whose elements all do not pass the truth test.
1597 var partition = group(function(result, value, pass) {
1598 result[pass ? 0 : 1].push(value);
1599 }, true);
1600
1601 // Safely create a real, live array from anything iterable.
1602 var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
1603 function toArray(obj) {
1604 if (!obj) return [];
1605 if (isArray(obj)) return slice.call(obj);
1606 if (isString(obj)) {
1607 // Keep surrogate pair characters together.
1608 return obj.match(reStrSymbol);
1609 }
1610 if (isArrayLike(obj)) return map(obj, identity);
1611 return values(obj);
1612 }
1613
1614 // Return the number of elements in a collection.
1615 function size(obj) {
1616 if (obj == null) return 0;
1617 return isArrayLike(obj) ? obj.length : keys(obj).length;
1618 }
1619
1620 // Internal `_.pick` helper function to determine whether `key` is an enumerable
1621 // property name of `obj`.
1622 function keyInObj(value, key, obj) {
1623 return key in obj;
1624 }
1625
1626 // Return a copy of the object only containing the allowed properties.
1627 var pick = restArguments(function(obj, keys) {
1628 var result = {}, iteratee = keys[0];
1629 if (obj == null) return result;
1630 if (isFunction$1(iteratee)) {
1631 if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
1632 keys = allKeys(obj);
1633 } else {
1634 iteratee = keyInObj;
1635 keys = flatten$1(keys, false, false);
1636 obj = Object(obj);
1637 }
1638 for (var i = 0, length = keys.length; i < length; i++) {
1639 var key = keys[i];
1640 var value = obj[key];
1641 if (iteratee(value, key, obj)) result[key] = value;
1642 }
1643 return result;
1644 });
1645
1646 // Return a copy of the object without the disallowed properties.
1647 var omit = restArguments(function(obj, keys) {
1648 var iteratee = keys[0], context;
1649 if (isFunction$1(iteratee)) {
1650 iteratee = negate(iteratee);
1651 if (keys.length > 1) context = keys[1];
1652 } else {
1653 keys = map(flatten$1(keys, false, false), String);
1654 iteratee = function(value, key) {
1655 return !contains(keys, key);
1656 };
1657 }
1658 return pick(obj, iteratee, context);
1659 });
1660
1661 // Returns everything but the last entry of the array. Especially useful on
1662 // the arguments object. Passing **n** will return all the values in
1663 // the array, excluding the last N.
1664 function initial(array, n, guard) {
1665 return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
1666 }
1667
1668 // Get the first element of an array. Passing **n** will return the first N
1669 // values in the array. The **guard** check allows it to work with `_.map`.
1670 function first(array, n, guard) {
1671 if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
1672 if (n == null || guard) return array[0];
1673 return initial(array, array.length - n);
1674 }
1675
1676 // Returns everything but the first entry of the `array`. Especially useful on
1677 // the `arguments` object. Passing an **n** will return the rest N values in the
1678 // `array`.
1679 function rest(array, n, guard) {
1680 return slice.call(array, n == null || guard ? 1 : n);
1681 }
1682
1683 // Get the last element of an array. Passing **n** will return the last N
1684 // values in the array.
1685 function last(array, n, guard) {
1686 if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
1687 if (n == null || guard) return array[array.length - 1];
1688 return rest(array, Math.max(0, array.length - n));
1689 }
1690
1691 // Trim out all falsy values from an array.
1692 function compact(array) {
1693 return filter(array, Boolean);
1694 }
1695
1696 // Flatten out an array, either recursively (by default), or up to `depth`.
1697 // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.
1698 function flatten(array, depth) {
1699 return flatten$1(array, depth, false);
1700 }
1701
1702 // Take the difference between one array and a number of other arrays.
1703 // Only the elements present in just the first array will remain.
1704 var difference = restArguments(function(array, rest) {
1705 rest = flatten$1(rest, true, true);
1706 return filter(array, function(value){
1707 return !contains(rest, value);
1708 });
1709 });
1710
1711 // Return a version of the array that does not contain the specified value(s).
1712 var without = restArguments(function(array, otherArrays) {
1713 return difference(array, otherArrays);
1714 });
1715
1716 // Produce a duplicate-free version of the array. If the array has already
1717 // been sorted, you have the option of using a faster algorithm.
1718 // The faster algorithm will not work with an iteratee if the iteratee
1719 // is not a one-to-one function, so providing an iteratee will disable
1720 // the faster algorithm.
1721 function uniq(array, isSorted, iteratee, context) {
1722 if (!isBoolean(isSorted)) {
1723 context = iteratee;
1724 iteratee = isSorted;
1725 isSorted = false;
1726 }
1727 if (iteratee != null) iteratee = cb(iteratee, context);
1728 var result = [];
1729 var seen = [];
1730 for (var i = 0, length = getLength(array); i < length; i++) {
1731 var value = array[i],
1732 computed = iteratee ? iteratee(value, i, array) : value;
1733 if (isSorted && !iteratee) {
1734 if (!i || seen !== computed) result.push(value);
1735 seen = computed;
1736 } else if (iteratee) {
1737 if (!contains(seen, computed)) {
1738 seen.push(computed);
1739 result.push(value);
1740 }
1741 } else if (!contains(result, value)) {
1742 result.push(value);
1743 }
1744 }
1745 return result;
1746 }
1747
1748 // Produce an array that contains the union: each distinct element from all of
1749 // the passed-in arrays.
1750 var union = restArguments(function(arrays) {
1751 return uniq(flatten$1(arrays, true, true));
1752 });
1753
1754 // Produce an array that contains every item shared between all the
1755 // passed-in arrays.
1756 function intersection(array) {
1757 var result = [];
1758 var argsLength = arguments.length;
1759 for (var i = 0, length = getLength(array); i < length; i++) {
1760 var item = array[i];
1761 if (contains(result, item)) continue;
1762 var j;
1763 for (j = 1; j < argsLength; j++) {
1764 if (!contains(arguments[j], item)) break;
1765 }
1766 if (j === argsLength) result.push(item);
1767 }
1768 return result;
1769 }
1770
1771 // Complement of zip. Unzip accepts an array of arrays and groups
1772 // each array's elements on shared indices.
1773 function unzip(array) {
1774 var length = array && max(array, getLength).length || 0;
1775 var result = Array(length);
1776
1777 for (var index = 0; index < length; index++) {
1778 result[index] = pluck(array, index);
1779 }
1780 return result;
1781 }
1782
1783 // Zip together multiple lists into a single array -- elements that share
1784 // an index go together.
1785 var zip = restArguments(unzip);
1786
1787 // Converts lists into objects. Pass either a single array of `[key, value]`
1788 // pairs, or two parallel arrays of the same length -- one of keys, and one of
1789 // the corresponding values. Passing by pairs is the reverse of `_.pairs`.
1790 function object(list, values) {
1791 var result = {};
1792 for (var i = 0, length = getLength(list); i < length; i++) {
1793 if (values) {
1794 result[list[i]] = values[i];
1795 } else {
1796 result[list[i][0]] = list[i][1];
1797 }
1798 }
1799 return result;
1800 }
1801
1802 // Generate an integer Array containing an arithmetic progression. A port of
1803 // the native Python `range()` function. See
1804 // [the Python documentation](https://docs.python.org/library/functions.html#range).
1805 function range(start, stop, step) {
1806 if (stop == null) {
1807 stop = start || 0;
1808 start = 0;
1809 }
1810 if (!step) {
1811 step = stop < start ? -1 : 1;
1812 }
1813
1814 var length = Math.max(Math.ceil((stop - start) / step), 0);
1815 var range = Array(length);
1816
1817 for (var idx = 0; idx < length; idx++, start += step) {
1818 range[idx] = start;
1819 }
1820
1821 return range;
1822 }
1823
1824 // Chunk a single array into multiple arrays, each containing `count` or fewer
1825 // items.
1826 function chunk(array, count) {
1827 if (count == null || count < 1) return [];
1828 var result = [];
1829 var i = 0, length = array.length;
1830 while (i < length) {
1831 result.push(slice.call(array, i, i += count));
1832 }
1833 return result;
1834 }
1835
1836 // Helper function to continue chaining intermediate results.
1837 function chainResult(instance, obj) {
1838 return instance._chain ? _$1(obj).chain() : obj;
1839 }
1840
1841 // Add your own custom functions to the Underscore object.
1842 function mixin(obj) {
1843 each(functions(obj), function(name) {
1844 var func = _$1[name] = obj[name];
1845 _$1.prototype[name] = function() {
1846 var args = [this._wrapped];
1847 push.apply(args, arguments);
1848 return chainResult(this, func.apply(_$1, args));
1849 };
1850 });
1851 return _$1;
1852 }
1853
1854 // Add all mutator `Array` functions to the wrapper.
1855 each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1856 var method = ArrayProto[name];
1857 _$1.prototype[name] = function() {
1858 var obj = this._wrapped;
1859 if (obj != null) {
1860 method.apply(obj, arguments);
1861 if ((name === 'shift' || name === 'splice') && obj.length === 0) {
1862 delete obj[0];
1863 }
1864 }
1865 return chainResult(this, obj);
1866 };
1867 });
1868
1869 // Add all accessor `Array` functions to the wrapper.
1870 each(['concat', 'join', 'slice'], function(name) {
1871 var method = ArrayProto[name];
1872 _$1.prototype[name] = function() {
1873 var obj = this._wrapped;
1874 if (obj != null) obj = method.apply(obj, arguments);
1875 return chainResult(this, obj);
1876 };
1877 });
1878
1879 // Named Exports
1880
1881 var allExports = {
1882 __proto__: null,
1883 VERSION: VERSION,
1884 restArguments: restArguments,
1885 isObject: isObject,
1886 isNull: isNull,
1887 isUndefined: isUndefined,
1888 isBoolean: isBoolean,
1889 isElement: isElement,
1890 isString: isString,
1891 isNumber: isNumber,
1892 isDate: isDate,
1893 isRegExp: isRegExp,
1894 isError: isError,
1895 isSymbol: isSymbol,
1896 isArrayBuffer: isArrayBuffer,
1897 isDataView: isDataView$1,
1898 isArray: isArray,
1899 isFunction: isFunction$1,
1900 isArguments: isArguments$1,
1901 isFinite: isFinite$1,
1902 isNaN: isNaN$1,
1903 isTypedArray: isTypedArray$1,
1904 isEmpty: isEmpty,
1905 isMatch: isMatch,
1906 isEqual: isEqual,
1907 isMap: isMap,
1908 isWeakMap: isWeakMap,
1909 isSet: isSet,
1910 isWeakSet: isWeakSet,
1911 keys: keys,
1912 allKeys: allKeys,
1913 values: values,
1914 pairs: pairs,
1915 invert: invert,
1916 functions: functions,
1917 methods: functions,
1918 extend: extend,
1919 extendOwn: extendOwn,
1920 assign: extendOwn,
1921 defaults: defaults,
1922 create: create,
1923 clone: clone,
1924 tap: tap,
1925 get: get,
1926 has: has,
1927 mapObject: mapObject,
1928 identity: identity,
1929 constant: constant,
1930 noop: noop,
1931 toPath: toPath$1,
1932 property: property,
1933 propertyOf: propertyOf,
1934 matcher: matcher,
1935 matches: matcher,
1936 times: times,
1937 random: random,
1938 now: now,
1939 escape: _escape,
1940 unescape: _unescape,
1941 templateSettings: templateSettings,
1942 template: template,
1943 result: result,
1944 uniqueId: uniqueId,
1945 chain: chain,
1946 iteratee: iteratee,
1947 partial: partial,
1948 bind: bind,
1949 bindAll: bindAll,
1950 memoize: memoize,
1951 delay: delay,
1952 defer: defer,
1953 throttle: throttle,
1954 debounce: debounce,
1955 wrap: wrap,
1956 negate: negate,
1957 compose: compose,
1958 after: after,
1959 before: before,
1960 once: once,
1961 findKey: findKey,
1962 findIndex: findIndex,
1963 findLastIndex: findLastIndex,
1964 sortedIndex: sortedIndex,
1965 indexOf: indexOf,
1966 lastIndexOf: lastIndexOf,
1967 find: find,
1968 detect: find,
1969 findWhere: findWhere,
1970 each: each,
1971 forEach: each,
1972 map: map,
1973 collect: map,
1974 reduce: reduce,
1975 foldl: reduce,
1976 inject: reduce,
1977 reduceRight: reduceRight,
1978 foldr: reduceRight,
1979 filter: filter,
1980 select: filter,
1981 reject: reject,
1982 every: every,
1983 all: every,
1984 some: some,
1985 any: some,
1986 contains: contains,
1987 includes: contains,
1988 include: contains,
1989 invoke: invoke,
1990 pluck: pluck,
1991 where: where,
1992 max: max,
1993 min: min,
1994 shuffle: shuffle,
1995 sample: sample,
1996 sortBy: sortBy,
1997 groupBy: groupBy,
1998 indexBy: indexBy,
1999 countBy: countBy,
2000 partition: partition,
2001 toArray: toArray,
2002 size: size,
2003 pick: pick,
2004 omit: omit,
2005 first: first,
2006 head: first,
2007 take: first,
2008 initial: initial,
2009 last: last,
2010 rest: rest,
2011 tail: rest,
2012 drop: rest,
2013 compact: compact,
2014 flatten: flatten,
2015 without: without,
2016 uniq: uniq,
2017 unique: uniq,
2018 union: union,
2019 intersection: intersection,
2020 difference: difference,
2021 unzip: unzip,
2022 transpose: unzip,
2023 zip: zip,
2024 object: object,
2025 range: range,
2026 chunk: chunk,
2027 mixin: mixin,
2028 'default': _$1
2029 };
2030
2031 // Default Export
2032
2033 // Add all of the Underscore functions to the wrapper object.
2034 var _ = mixin(allExports);
2035 // Legacy Node.js API.
2036 _._ = _;
2037
2038 return _;
2039
2040 })));
2041 //# sourceMappingURL=underscore-umd.js.map
0 // Underscore.js 1.3.1
1 // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
2 // Underscore is freely distributable under the MIT license.
3 // Portions of Underscore are inspired or borrowed from Prototype,
4 // Oliver Steele's Functional, and John Resig's Micro-Templating.
5 // For all details and documentation:
6 // http://documentcloud.github.com/underscore
7
8 (function() {
9
10 // Baseline setup
11 // --------------
12
13 // Establish the root object, `window` in the browser, or `global` on the server.
14 var root = this;
15
16 // Save the previous value of the `_` variable.
17 var previousUnderscore = root._;
18
19 // Establish the object that gets returned to break out of a loop iteration.
20 var breaker = {};
21
22 // Save bytes in the minified (but not gzipped) version:
23 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
24
25 // Create quick reference variables for speed access to core prototypes.
26 var slice = ArrayProto.slice,
27 unshift = ArrayProto.unshift,
28 toString = ObjProto.toString,
29 hasOwnProperty = ObjProto.hasOwnProperty;
30
31 // All **ECMAScript 5** native function implementations that we hope to use
32 // are declared here.
33 var
34 nativeForEach = ArrayProto.forEach,
35 nativeMap = ArrayProto.map,
36 nativeReduce = ArrayProto.reduce,
37 nativeReduceRight = ArrayProto.reduceRight,
38 nativeFilter = ArrayProto.filter,
39 nativeEvery = ArrayProto.every,
40 nativeSome = ArrayProto.some,
41 nativeIndexOf = ArrayProto.indexOf,
42 nativeLastIndexOf = ArrayProto.lastIndexOf,
43 nativeIsArray = Array.isArray,
44 nativeKeys = Object.keys,
45 nativeBind = FuncProto.bind;
46
47 // Create a safe reference to the Underscore object for use below.
48 var _ = function(obj) { return new wrapper(obj); };
49
50 // Export the Underscore object for **Node.js**, with
51 // backwards-compatibility for the old `require()` API. If we're in
52 // the browser, add `_` as a global object via a string identifier,
53 // for Closure Compiler "advanced" mode.
54 if (typeof exports !== 'undefined') {
55 if (typeof module !== 'undefined' && module.exports) {
56 exports = module.exports = _;
57 }
58 exports._ = _;
59 } else {
60 root['_'] = _;
61 }
62
63 // Current version.
64 _.VERSION = '1.3.1';
65
66 // Collection Functions
67 // --------------------
68
69 // The cornerstone, an `each` implementation, aka `forEach`.
70 // Handles objects with the built-in `forEach`, arrays, and raw objects.
71 // Delegates to **ECMAScript 5**'s native `forEach` if available.
72 var each = _.each = _.forEach = function(obj, iterator, context) {
73 if (obj == null) return;
74 if (nativeForEach && obj.forEach === nativeForEach) {
75 obj.forEach(iterator, context);
76 } else if (obj.length === +obj.length) {
77 for (var i = 0, l = obj.length; i < l; i++) {
78 if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
79 }
80 } else {
81 for (var key in obj) {
82 if (_.has(obj, key)) {
83 if (iterator.call(context, obj[key], key, obj) === breaker) return;
84 }
85 }
86 }
87 };
88
89 // Return the results of applying the iterator to each element.
90 // Delegates to **ECMAScript 5**'s native `map` if available.
91 _.map = _.collect = function(obj, iterator, context) {
92 var results = [];
93 if (obj == null) return results;
94 if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
95 each(obj, function(value, index, list) {
96 results[results.length] = iterator.call(context, value, index, list);
97 });
98 if (obj.length === +obj.length) results.length = obj.length;
99 return results;
100 };
101
102 // **Reduce** builds up a single result from a list of values, aka `inject`,
103 // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
104 _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
105 var initial = arguments.length > 2;
106 if (obj == null) obj = [];
107 if (nativeReduce && obj.reduce === nativeReduce) {
108 if (context) iterator = _.bind(iterator, context);
109 return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
110 }
111 each(obj, function(value, index, list) {
112 if (!initial) {
113 memo = value;
114 initial = true;
115 } else {
116 memo = iterator.call(context, memo, value, index, list);
117 }
118 });
119 if (!initial) throw new TypeError('Reduce of empty array with no initial value');
120 return memo;
121 };
122
123 // The right-associative version of reduce, also known as `foldr`.
124 // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
125 _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
126 var initial = arguments.length > 2;
127 if (obj == null) obj = [];
128 if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
129 if (context) iterator = _.bind(iterator, context);
130 return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
131 }
132 var reversed = _.toArray(obj).reverse();
133 if (context && !initial) iterator = _.bind(iterator, context);
134 return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
135 };
136
137 // Return the first value which passes a truth test. Aliased as `detect`.
138 _.find = _.detect = function(obj, iterator, context) {
139 var result;
140 any(obj, function(value, index, list) {
141 if (iterator.call(context, value, index, list)) {
142 result = value;
143 return true;
144 }
145 });
146 return result;
147 };
148
149 // Return all the elements that pass a truth test.
150 // Delegates to **ECMAScript 5**'s native `filter` if available.
151 // Aliased as `select`.
152 _.filter = _.select = function(obj, iterator, context) {
153 var results = [];
154 if (obj == null) return results;
155 if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
156 each(obj, function(value, index, list) {
157 if (iterator.call(context, value, index, list)) results[results.length] = value;
158 });
159 return results;
160 };
161
162 // Return all the elements for which a truth test fails.
163 _.reject = function(obj, iterator, context) {
164 var results = [];
165 if (obj == null) return results;
166 each(obj, function(value, index, list) {
167 if (!iterator.call(context, value, index, list)) results[results.length] = value;
168 });
169 return results;
170 };
171
172 // Determine whether all of the elements match a truth test.
173 // Delegates to **ECMAScript 5**'s native `every` if available.
174 // Aliased as `all`.
175 _.every = _.all = function(obj, iterator, context) {
176 var result = true;
177 if (obj == null) return result;
178 if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
179 each(obj, function(value, index, list) {
180 if (!(result = result && iterator.call(context, value, index, list))) return breaker;
181 });
182 return result;
183 };
184
185 // Determine if at least one element in the object matches a truth test.
186 // Delegates to **ECMAScript 5**'s native `some` if available.
187 // Aliased as `any`.
188 var any = _.some = _.any = function(obj, iterator, context) {
189 iterator || (iterator = _.identity);
190 var result = false;
191 if (obj == null) return result;
192 if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
193 each(obj, function(value, index, list) {
194 if (result || (result = iterator.call(context, value, index, list))) return breaker;
195 });
196 return !!result;
197 };
198
199 // Determine if a given value is included in the array or object using `===`.
200 // Aliased as `contains`.
201 _.include = _.contains = function(obj, target) {
202 var found = false;
203 if (obj == null) return found;
204 if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
205 found = any(obj, function(value) {
206 return value === target;
207 });
208 return found;
209 };
210
211 // Invoke a method (with arguments) on every item in a collection.
212 _.invoke = function(obj, method) {
213 var args = slice.call(arguments, 2);
214 return _.map(obj, function(value) {
215 return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
216 });
217 };
218
219 // Convenience version of a common use case of `map`: fetching a property.
220 _.pluck = function(obj, key) {
221 return _.map(obj, function(value){ return value[key]; });
222 };
223
224 // Return the maximum element or (element-based computation).
225 _.max = function(obj, iterator, context) {
226 if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
227 if (!iterator && _.isEmpty(obj)) return -Infinity;
228 var result = {computed : -Infinity};
229 each(obj, function(value, index, list) {
230 var computed = iterator ? iterator.call(context, value, index, list) : value;
231 computed >= result.computed && (result = {value : value, computed : computed});
232 });
233 return result.value;
234 };
235
236 // Return the minimum element (or element-based computation).
237 _.min = function(obj, iterator, context) {
238 if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
239 if (!iterator && _.isEmpty(obj)) return Infinity;
240 var result = {computed : Infinity};
241 each(obj, function(value, index, list) {
242 var computed = iterator ? iterator.call(context, value, index, list) : value;
243 computed < result.computed && (result = {value : value, computed : computed});
244 });
245 return result.value;
246 };
247
248 // Shuffle an array.
249 _.shuffle = function(obj) {
250 var shuffled = [], rand;
251 each(obj, function(value, index, list) {
252 if (index == 0) {
253 shuffled[0] = value;
254 } else {
255 rand = Math.floor(Math.random() * (index + 1));
256 shuffled[index] = shuffled[rand];
257 shuffled[rand] = value;
258 }
259 });
260 return shuffled;
261 };
262
263 // Sort the object's values by a criterion produced by an iterator.
264 _.sortBy = function(obj, iterator, context) {
265 return _.pluck(_.map(obj, function(value, index, list) {
266 return {
267 value : value,
268 criteria : iterator.call(context, value, index, list)
269 };
270 }).sort(function(left, right) {
271 var a = left.criteria, b = right.criteria;
272 return a < b ? -1 : a > b ? 1 : 0;
273 }), 'value');
274 };
275
276 // Groups the object's values by a criterion. Pass either a string attribute
277 // to group by, or a function that returns the criterion.
278 _.groupBy = function(obj, val) {
279 var result = {};
280 var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
281 each(obj, function(value, index) {
282 var key = iterator(value, index);
283 (result[key] || (result[key] = [])).push(value);
284 });
285 return result;
286 };
287
288 // Use a comparator function to figure out at what index an object should
289 // be inserted so as to maintain order. Uses binary search.
290 _.sortedIndex = function(array, obj, iterator) {
291 iterator || (iterator = _.identity);
292 var low = 0, high = array.length;
293 while (low < high) {
294 var mid = (low + high) >> 1;
295 iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
296 }
297 return low;
298 };
299
300 // Safely convert anything iterable into a real, live array.
301 _.toArray = function(iterable) {
302 if (!iterable) return [];
303 if (iterable.toArray) return iterable.toArray();
304 if (_.isArray(iterable)) return slice.call(iterable);
305 if (_.isArguments(iterable)) return slice.call(iterable);
306 return _.values(iterable);
307 };
308
309 // Return the number of elements in an object.
310 _.size = function(obj) {
311 return _.toArray(obj).length;
312 };
313
314 // Array Functions
315 // ---------------
316
317 // Get the first element of an array. Passing **n** will return the first N
318 // values in the array. Aliased as `head`. The **guard** check allows it to work
319 // with `_.map`.
320 _.first = _.head = function(array, n, guard) {
321 return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
322 };
323
324 // Returns everything but the last entry of the array. Especcialy useful on
325 // the arguments object. Passing **n** will return all the values in
326 // the array, excluding the last N. The **guard** check allows it to work with
327 // `_.map`.
328 _.initial = function(array, n, guard) {
329 return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
330 };
331
332 // Get the last element of an array. Passing **n** will return the last N
333 // values in the array. The **guard** check allows it to work with `_.map`.
334 _.last = function(array, n, guard) {
335 if ((n != null) && !guard) {
336 return slice.call(array, Math.max(array.length - n, 0));
337 } else {
338 return array[array.length - 1];
339 }
340 };
341
342 // Returns everything but the first entry of the array. Aliased as `tail`.
343 // Especially useful on the arguments object. Passing an **index** will return
344 // the rest of the values in the array from that index onward. The **guard**
345 // check allows it to work with `_.map`.
346 _.rest = _.tail = function(array, index, guard) {
347 return slice.call(array, (index == null) || guard ? 1 : index);
348 };
349
350 // Trim out all falsy values from an array.
351 _.compact = function(array) {
352 return _.filter(array, function(value){ return !!value; });
353 };
354
355 // Return a completely flattened version of an array.
356 _.flatten = function(array, shallow) {
357 return _.reduce(array, function(memo, value) {
358 if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
359 memo[memo.length] = value;
360 return memo;
361 }, []);
362 };
363
364 // Return a version of the array that does not contain the specified value(s).
365 _.without = function(array) {
366 return _.difference(array, slice.call(arguments, 1));
367 };
368
369 // Produce a duplicate-free version of the array. If the array has already
370 // been sorted, you have the option of using a faster algorithm.
371 // Aliased as `unique`.
372 _.uniq = _.unique = function(array, isSorted, iterator) {
373 var initial = iterator ? _.map(array, iterator) : array;
374 var result = [];
375 _.reduce(initial, function(memo, el, i) {
376 if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
377 memo[memo.length] = el;
378 result[result.length] = array[i];
379 }
380 return memo;
381 }, []);
382 return result;
383 };
384
385 // Produce an array that contains the union: each distinct element from all of
386 // the passed-in arrays.
387 _.union = function() {
388 return _.uniq(_.flatten(arguments, true));
389 };
390
391 // Produce an array that contains every item shared between all the
392 // passed-in arrays. (Aliased as "intersect" for back-compat.)
393 _.intersection = _.intersect = function(array) {
394 var rest = slice.call(arguments, 1);
395 return _.filter(_.uniq(array), function(item) {
396 return _.every(rest, function(other) {
397 return _.indexOf(other, item) >= 0;
398 });
399 });
400 };
401
402 // Take the difference between one array and a number of other arrays.
403 // Only the elements present in just the first array will remain.
404 _.difference = function(array) {
405 var rest = _.flatten(slice.call(arguments, 1));
406 return _.filter(array, function(value){ return !_.include(rest, value); });
407 };
408
409 // Zip together multiple lists into a single array -- elements that share
410 // an index go together.
411 _.zip = function() {
412 var args = slice.call(arguments);
413 var length = _.max(_.pluck(args, 'length'));
414 var results = new Array(length);
415 for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
416 return results;
417 };
418
419 // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
420 // we need this function. Return the position of the first occurrence of an
421 // item in an array, or -1 if the item is not included in the array.
422 // Delegates to **ECMAScript 5**'s native `indexOf` if available.
423 // If the array is large and already in sort order, pass `true`
424 // for **isSorted** to use binary search.
425 _.indexOf = function(array, item, isSorted) {
426 if (array == null) return -1;
427 var i, l;
428 if (isSorted) {
429 i = _.sortedIndex(array, item);
430 return array[i] === item ? i : -1;
431 }
432 if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
433 for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
434 return -1;
435 };
436
437 // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
438 _.lastIndexOf = function(array, item) {
439 if (array == null) return -1;
440 if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
441 var i = array.length;
442 while (i--) if (i in array && array[i] === item) return i;
443 return -1;
444 };
445
446 // Generate an integer Array containing an arithmetic progression. A port of
447 // the native Python `range()` function. See
448 // [the Python documentation](http://docs.python.org/library/functions.html#range).
449 _.range = function(start, stop, step) {
450 if (arguments.length <= 1) {
451 stop = start || 0;
452 start = 0;
453 }
454 step = arguments[2] || 1;
455
456 var len = Math.max(Math.ceil((stop - start) / step), 0);
457 var idx = 0;
458 var range = new Array(len);
459
460 while(idx < len) {
461 range[idx++] = start;
462 start += step;
463 }
464
465 return range;
466 };
467
468 // Function (ahem) Functions
469 // ------------------
470
471 // Reusable constructor function for prototype setting.
472 var ctor = function(){};
473
474 // Create a function bound to a given object (assigning `this`, and arguments,
475 // optionally). Binding with arguments is also known as `curry`.
476 // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
477 // We check for `func.bind` first, to fail fast when `func` is undefined.
478 _.bind = function bind(func, context) {
479 var bound, args;
480 if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
481 if (!_.isFunction(func)) throw new TypeError;
482 args = slice.call(arguments, 2);
483 return bound = function() {
484 if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
485 ctor.prototype = func.prototype;
486 var self = new ctor;
487 var result = func.apply(self, args.concat(slice.call(arguments)));
488 if (Object(result) === result) return result;
489 return self;
490 };
491 };
492
493 // Bind all of an object's methods to that object. Useful for ensuring that
494 // all callbacks defined on an object belong to it.
495 _.bindAll = function(obj) {
496 var funcs = slice.call(arguments, 1);
497 if (funcs.length == 0) funcs = _.functions(obj);
498 each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
499 return obj;
500 };
501
502 // Memoize an expensive function by storing its results.
503 _.memoize = function(func, hasher) {
504 var memo = {};
505 hasher || (hasher = _.identity);
506 return function() {
507 var key = hasher.apply(this, arguments);
508 return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
509 };
510 };
511
512 // Delays a function for the given number of milliseconds, and then calls
513 // it with the arguments supplied.
514 _.delay = function(func, wait) {
515 var args = slice.call(arguments, 2);
516 return setTimeout(function(){ return func.apply(func, args); }, wait);
517 };
518
519 // Defers a function, scheduling it to run after the current call stack has
520 // cleared.
521 _.defer = function(func) {
522 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
523 };
524
525 // Returns a function, that, when invoked, will only be triggered at most once
526 // during a given window of time.
527 _.throttle = function(func, wait) {
528 var context, args, timeout, throttling, more;
529 var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
530 return function() {
531 context = this; args = arguments;
532 var later = function() {
533 timeout = null;
534 if (more) func.apply(context, args);
535 whenDone();
536 };
537 if (!timeout) timeout = setTimeout(later, wait);
538 if (throttling) {
539 more = true;
540 } else {
541 func.apply(context, args);
542 }
543 whenDone();
544 throttling = true;
545 };
546 };
547
548 // Returns a function, that, as long as it continues to be invoked, will not
549 // be triggered. The function will be called after it stops being called for
550 // N milliseconds.
551 _.debounce = function(func, wait) {
552 var timeout;
553 return function() {
554 var context = this, args = arguments;
555 var later = function() {
556 timeout = null;
557 func.apply(context, args);
558 };
559 clearTimeout(timeout);
560 timeout = setTimeout(later, wait);
561 };
562 };
563
564 // Returns a function that will be executed at most one time, no matter how
565 // often you call it. Useful for lazy initialization.
566 _.once = function(func) {
567 var ran = false, memo;
568 return function() {
569 if (ran) return memo;
570 ran = true;
571 return memo = func.apply(this, arguments);
572 };
573 };
574
575 // Returns the first function passed as an argument to the second,
576 // allowing you to adjust arguments, run code before and after, and
577 // conditionally execute the original function.
578 _.wrap = function(func, wrapper) {
579 return function() {
580 var args = [func].concat(slice.call(arguments, 0));
581 return wrapper.apply(this, args);
582 };
583 };
584
585 // Returns a function that is the composition of a list of functions, each
586 // consuming the return value of the function that follows.
587 _.compose = function() {
588 var funcs = arguments;
589 return function() {
590 var args = arguments;
591 for (var i = funcs.length - 1; i >= 0; i--) {
592 args = [funcs[i].apply(this, args)];
593 }
594 return args[0];
595 };
596 };
597
598 // Returns a function that will only be executed after being called N times.
599 _.after = function(times, func) {
600 if (times <= 0) return func();
601 return function() {
602 if (--times < 1) { return func.apply(this, arguments); }
603 };
604 };
605
606 // Object Functions
607 // ----------------
608
609 // Retrieve the names of an object's properties.
610 // Delegates to **ECMAScript 5**'s native `Object.keys`
611 _.keys = nativeKeys || function(obj) {
612 if (obj !== Object(obj)) throw new TypeError('Invalid object');
613 var keys = [];
614 for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
615 return keys;
616 };
617
618 // Retrieve the values of an object's properties.
619 _.values = function(obj) {
620 return _.map(obj, _.identity);
621 };
622
623 // Return a sorted list of the function names available on the object.
624 // Aliased as `methods`
625 _.functions = _.methods = function(obj) {
626 var names = [];
627 for (var key in obj) {
628 if (_.isFunction(obj[key])) names.push(key);
629 }
630 return names.sort();
631 };
632
633 // Extend a given object with all the properties in passed-in object(s).
634 _.extend = function(obj) {
635 each(slice.call(arguments, 1), function(source) {
636 for (var prop in source) {
637 obj[prop] = source[prop];
638 }
639 });
640 return obj;
641 };
642
643 // Fill in a given object with default properties.
644 _.defaults = function(obj) {
645 each(slice.call(arguments, 1), function(source) {
646 for (var prop in source) {
647 if (obj[prop] == null) obj[prop] = source[prop];
648 }
649 });
650 return obj;
651 };
652
653 // Create a (shallow-cloned) duplicate of an object.
654 _.clone = function(obj) {
655 if (!_.isObject(obj)) return obj;
656 return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
657 };
658
659 // Invokes interceptor with the obj, and then returns obj.
660 // The primary purpose of this method is to "tap into" a method chain, in
661 // order to perform operations on intermediate results within the chain.
662 _.tap = function(obj, interceptor) {
663 interceptor(obj);
664 return obj;
665 };
666
667 // Internal recursive comparison function.
668 function eq(a, b, stack) {
669 // Identical objects are equal. `0 === -0`, but they aren't identical.
670 // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
671 if (a === b) return a !== 0 || 1 / a == 1 / b;
672 // A strict comparison is necessary because `null == undefined`.
673 if (a == null || b == null) return a === b;
674 // Unwrap any wrapped objects.
675 if (a._chain) a = a._wrapped;
676 if (b._chain) b = b._wrapped;
677 // Invoke a custom `isEqual` method if one is provided.
678 if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
679 if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
680 // Compare `[[Class]]` names.
681 var className = toString.call(a);
682 if (className != toString.call(b)) return false;
683 switch (className) {
684 // Strings, numbers, dates, and booleans are compared by value.
685 case '[object String]':
686 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
687 // equivalent to `new String("5")`.
688 return a == String(b);
689 case '[object Number]':
690 // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
691 // other numeric values.
692 return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
693 case '[object Date]':
694 case '[object Boolean]':
695 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
696 // millisecond representations. Note that invalid dates with millisecond representations
697 // of `NaN` are not equivalent.
698 return +a == +b;
699 // RegExps are compared by their source patterns and flags.
700 case '[object RegExp]':
701 return a.source == b.source &&
702 a.global == b.global &&
703 a.multiline == b.multiline &&
704 a.ignoreCase == b.ignoreCase;
705 }
706 if (typeof a != 'object' || typeof b != 'object') return false;
707 // Assume equality for cyclic structures. The algorithm for detecting cyclic
708 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
709 var length = stack.length;
710 while (length--) {
711 // Linear search. Performance is inversely proportional to the number of
712 // unique nested structures.
713 if (stack[length] == a) return true;
714 }
715 // Add the first object to the stack of traversed objects.
716 stack.push(a);
717 var size = 0, result = true;
718 // Recursively compare objects and arrays.
719 if (className == '[object Array]') {
720 // Compare array lengths to determine if a deep comparison is necessary.
721 size = a.length;
722 result = size == b.length;
723 if (result) {
724 // Deep compare the contents, ignoring non-numeric properties.
725 while (size--) {
726 // Ensure commutative equality for sparse arrays.
727 if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
728 }
729 }
730 } else {
731 // Objects with different constructors are not equivalent.
732 if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
733 // Deep compare objects.
734 for (var key in a) {
735 if (_.has(a, key)) {
736 // Count the expected number of properties.
737 size++;
738 // Deep compare each member.
739 if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
740 }
741 }
742 // Ensure that both objects contain the same number of properties.
743 if (result) {
744 for (key in b) {
745 if (_.has(b, key) && !(size--)) break;
746 }
747 result = !size;
748 }
749 }
750 // Remove the first object from the stack of traversed objects.
751 stack.pop();
752 return result;
753 }
754
755 // Perform a deep comparison to check if two objects are equal.
756 _.isEqual = function(a, b) {
757 return eq(a, b, []);
758 };
759
760 // Is a given array, string, or object empty?
761 // An "empty" object has no enumerable own-properties.
762 _.isEmpty = function(obj) {
763 if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
764 for (var key in obj) if (_.has(obj, key)) return false;
765 return true;
766 };
767
768 // Is a given value a DOM element?
769 _.isElement = function(obj) {
770 return !!(obj && obj.nodeType == 1);
771 };
772
773 // Is a given value an array?
774 // Delegates to ECMA5's native Array.isArray
775 _.isArray = nativeIsArray || function(obj) {
776 return toString.call(obj) == '[object Array]';
777 };
778
779 // Is a given variable an object?
780 _.isObject = function(obj) {
781 return obj === Object(obj);
782 };
783
784 // Is a given variable an arguments object?
785 _.isArguments = function(obj) {
786 return toString.call(obj) == '[object Arguments]';
787 };
788 if (!_.isArguments(arguments)) {
789 _.isArguments = function(obj) {
790 return !!(obj && _.has(obj, 'callee'));
791 };
792 }
793
794 // Is a given value a function?
795 _.isFunction = function(obj) {
796 return toString.call(obj) == '[object Function]';
797 };
798
799 // Is a given value a string?
800 _.isString = function(obj) {
801 return toString.call(obj) == '[object String]';
802 };
803
804 // Is a given value a number?
805 _.isNumber = function(obj) {
806 return toString.call(obj) == '[object Number]';
807 };
808
809 // Is the given value `NaN`?
810 _.isNaN = function(obj) {
811 // `NaN` is the only value for which `===` is not reflexive.
812 return obj !== obj;
813 };
814
815 // Is a given value a boolean?
816 _.isBoolean = function(obj) {
817 return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
818 };
819
820 // Is a given value a date?
821 _.isDate = function(obj) {
822 return toString.call(obj) == '[object Date]';
823 };
824
825 // Is the given value a regular expression?
826 _.isRegExp = function(obj) {
827 return toString.call(obj) == '[object RegExp]';
828 };
829
830 // Is a given value equal to null?
831 _.isNull = function(obj) {
832 return obj === null;
833 };
834
835 // Is a given variable undefined?
836 _.isUndefined = function(obj) {
837 return obj === void 0;
838 };
839
840 // Has own property?
841 _.has = function(obj, key) {
842 return hasOwnProperty.call(obj, key);
843 };
844
845 // Utility Functions
846 // -----------------
847
848 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
849 // previous owner. Returns a reference to the Underscore object.
850 _.noConflict = function() {
851 root._ = previousUnderscore;
852 return this;
853 };
854
855 // Keep the identity function around for default iterators.
856 _.identity = function(value) {
857 return value;
858 };
859
860 // Run a function **n** times.
861 _.times = function (n, iterator, context) {
862 for (var i = 0; i < n; i++) iterator.call(context, i);
863 };
864
865 // Escape a string for HTML interpolation.
866 _.escape = function(string) {
867 return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
868 };
869
870 // Add your own custom functions to the Underscore object, ensuring that
871 // they're correctly added to the OOP wrapper as well.
872 _.mixin = function(obj) {
873 each(_.functions(obj), function(name){
874 addToWrapper(name, _[name] = obj[name]);
875 });
876 };
877
878 // Generate a unique integer id (unique within the entire client session).
879 // Useful for temporary DOM ids.
880 var idCounter = 0;
881 _.uniqueId = function(prefix) {
882 var id = idCounter++;
883 return prefix ? prefix + id : id;
884 };
885
886 // By default, Underscore uses ERB-style template delimiters, change the
887 // following template settings to use alternative delimiters.
888 _.templateSettings = {
889 evaluate : /<%([\s\S]+?)%>/g,
890 interpolate : /<%=([\s\S]+?)%>/g,
891 escape : /<%-([\s\S]+?)%>/g
892 };
893
894 // When customizing `templateSettings`, if you don't want to define an
895 // interpolation, evaluation or escaping regex, we need one that is
896 // guaranteed not to match.
897 var noMatch = /.^/;
898
899 // Within an interpolation, evaluation, or escaping, remove HTML escaping
900 // that had been previously added.
901 var unescape = function(code) {
902 return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");
903 };
904
905 // JavaScript micro-templating, similar to John Resig's implementation.
906 // Underscore templating handles arbitrary delimiters, preserves whitespace,
907 // and correctly escapes quotes within interpolated code.
908 _.template = function(str, data) {
909 var c = _.templateSettings;
910 var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
911 'with(obj||{}){__p.push(\'' +
912 str.replace(/\\/g, '\\\\')
913 .replace(/'/g, "\\'")
914 .replace(c.escape || noMatch, function(match, code) {
915 return "',_.escape(" + unescape(code) + "),'";
916 })
917 .replace(c.interpolate || noMatch, function(match, code) {
918 return "'," + unescape(code) + ",'";
919 })
920 .replace(c.evaluate || noMatch, function(match, code) {
921 return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
922 })
923 .replace(/\r/g, '\\r')
924 .replace(/\n/g, '\\n')
925 .replace(/\t/g, '\\t')
926 + "');}return __p.join('');";
927 var func = new Function('obj', '_', tmpl);
928 if (data) return func(data, _);
929 return function(data) {
930 return func.call(this, data, _);
931 };
932 };
933
934 // Add a "chain" function, which will delegate to the wrapper.
935 _.chain = function(obj) {
936 return _(obj).chain();
937 };
938
939 // The OOP Wrapper
940 // ---------------
941
942 // If Underscore is called as a function, it returns a wrapped object that
943 // can be used OO-style. This wrapper holds altered versions of all the
944 // underscore functions. Wrapped objects may be chained.
945 var wrapper = function(obj) { this._wrapped = obj; };
946
947 // Expose `wrapper.prototype` as `_.prototype`
948 _.prototype = wrapper.prototype;
949
950 // Helper function to continue chaining intermediate results.
951 var result = function(obj, chain) {
952 return chain ? _(obj).chain() : obj;
953 };
954
955 // A method to easily add functions to the OOP wrapper.
956 var addToWrapper = function(name, func) {
957 wrapper.prototype[name] = function() {
958 var args = slice.call(arguments);
959 unshift.call(args, this._wrapped);
960 return result(func.apply(_, args), this._chain);
961 };
962 };
963
964 // Add all of the Underscore functions to the wrapper object.
965 _.mixin(_);
966
967 // Add all mutator Array functions to the wrapper.
968 each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
969 var method = ArrayProto[name];
970 wrapper.prototype[name] = function() {
971 var wrapped = this._wrapped;
972 method.apply(wrapped, arguments);
973 var length = wrapped.length;
974 if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
975 return result(wrapped, this._chain);
976 };
977 });
978
979 // Add all accessor Array functions to the wrapper.
980 each(['concat', 'join', 'slice'], function(name) {
981 var method = ArrayProto[name];
982 wrapper.prototype[name] = function() {
983 return result(method.apply(this._wrapped, arguments), this._chain);
984 };
985 });
986
987 // Start chaining a wrapped Underscore object.
988 wrapper.prototype.chain = function() {
989 this._chain = true;
990 return this;
991 };
992
993 // Extracts the result from a wrapped and chained object.
994 wrapper.prototype.value = function() {
995 return this._wrapped;
996 };
997
998 }).call(this);
0 // Underscore.js 1.7.0
1 // http://underscorejs.org
2 // (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
0 !function(n,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define("underscore",r):(n="undefined"!=typeof globalThis?globalThis:n||self,function(){var t=n._,e=n._=r();e.noConflict=function(){return n._=t,e}}())}(this,(function(){
1 // Underscore.js 1.13.1
2 // https://underscorejs.org
3 // (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
34 // Underscore may be freely distributed under the MIT license.
4
5 (function() {
6
7 // Baseline setup
8 // --------------
9
10 // Establish the root object, `window` in the browser, or `exports` on the server.
11 var root = this;
12
13 // Save the previous value of the `_` variable.
14 var previousUnderscore = root._;
15
16 // Save bytes in the minified (but not gzipped) version:
17 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
18
19 // Create quick reference variables for speed access to core prototypes.
20 var
21 push = ArrayProto.push,
22 slice = ArrayProto.slice,
23 concat = ArrayProto.concat,
24 toString = ObjProto.toString,
25 hasOwnProperty = ObjProto.hasOwnProperty;
26
27 // All **ECMAScript 5** native function implementations that we hope to use
28 // are declared here.
29 var
30 nativeIsArray = Array.isArray,
31 nativeKeys = Object.keys,
32 nativeBind = FuncProto.bind;
33
34 // Create a safe reference to the Underscore object for use below.
35 var _ = function(obj) {
36 if (obj instanceof _) return obj;
37 if (!(this instanceof _)) return new _(obj);
38 this._wrapped = obj;
39 };
40
41 // Export the Underscore object for **Node.js**, with
42 // backwards-compatibility for the old `require()` API. If we're in
43 // the browser, add `_` as a global object.
44 if (typeof exports !== 'undefined') {
45 if (typeof module !== 'undefined' && module.exports) {
46 exports = module.exports = _;
47 }
48 exports._ = _;
49 } else {
50 root._ = _;
51 }
52
53 // Current version.
54 _.VERSION = '1.7.0';
55
56 // Internal function that returns an efficient (for current engines) version
57 // of the passed-in callback, to be repeatedly applied in other Underscore
58 // functions.
59 var createCallback = function(func, context, argCount) {
60 if (context === void 0) return func;
61 switch (argCount == null ? 3 : argCount) {
62 case 1: return function(value) {
63 return func.call(context, value);
64 };
65 case 2: return function(value, other) {
66 return func.call(context, value, other);
67 };
68 case 3: return function(value, index, collection) {
69 return func.call(context, value, index, collection);
70 };
71 case 4: return function(accumulator, value, index, collection) {
72 return func.call(context, accumulator, value, index, collection);
73 };
74 }
75 return function() {
76 return func.apply(context, arguments);
77 };
78 };
79
80 // A mostly-internal function to generate callbacks that can be applied
81 // to each element in a collection, returning the desired result — either
82 // identity, an arbitrary callback, a property matcher, or a property accessor.
83 _.iteratee = function(value, context, argCount) {
84 if (value == null) return _.identity;
85 if (_.isFunction(value)) return createCallback(value, context, argCount);
86 if (_.isObject(value)) return _.matches(value);
87 return _.property(value);
88 };
89
90 // Collection Functions
91 // --------------------
92
93 // The cornerstone, an `each` implementation, aka `forEach`.
94 // Handles raw objects in addition to array-likes. Treats all
95 // sparse array-likes as if they were dense.
96 _.each = _.forEach = function(obj, iteratee, context) {
97 if (obj == null) return obj;
98 iteratee = createCallback(iteratee, context);
99 var i, length = obj.length;
100 if (length === +length) {
101 for (i = 0; i < length; i++) {
102 iteratee(obj[i], i, obj);
103 }
104 } else {
105 var keys = _.keys(obj);
106 for (i = 0, length = keys.length; i < length; i++) {
107 iteratee(obj[keys[i]], keys[i], obj);
108 }
109 }
110 return obj;
111 };
112
113 // Return the results of applying the iteratee to each element.
114 _.map = _.collect = function(obj, iteratee, context) {
115 if (obj == null) return [];
116 iteratee = _.iteratee(iteratee, context);
117 var keys = obj.length !== +obj.length && _.keys(obj),
118 length = (keys || obj).length,
119 results = Array(length),
120 currentKey;
121 for (var index = 0; index < length; index++) {
122 currentKey = keys ? keys[index] : index;
123 results[index] = iteratee(obj[currentKey], currentKey, obj);
124 }
125 return results;
126 };
127
128 var reduceError = 'Reduce of empty array with no initial value';
129
130 // **Reduce** builds up a single result from a list of values, aka `inject`,
131 // or `foldl`.
132 _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) {
133 if (obj == null) obj = [];
134 iteratee = createCallback(iteratee, context, 4);
135 var keys = obj.length !== +obj.length && _.keys(obj),
136 length = (keys || obj).length,
137 index = 0, currentKey;
138 if (arguments.length < 3) {
139 if (!length) throw new TypeError(reduceError);
140 memo = obj[keys ? keys[index++] : index++];
141 }
142 for (; index < length; index++) {
143 currentKey = keys ? keys[index] : index;
144 memo = iteratee(memo, obj[currentKey], currentKey, obj);
145 }
146 return memo;
147 };
148
149 // The right-associative version of reduce, also known as `foldr`.
150 _.reduceRight = _.foldr = function(obj, iteratee, memo, context) {
151 if (obj == null) obj = [];
152 iteratee = createCallback(iteratee, context, 4);
153 var keys = obj.length !== + obj.length && _.keys(obj),
154 index = (keys || obj).length,
155 currentKey;
156 if (arguments.length < 3) {
157 if (!index) throw new TypeError(reduceError);
158 memo = obj[keys ? keys[--index] : --index];
159 }
160 while (index--) {
161 currentKey = keys ? keys[index] : index;
162 memo = iteratee(memo, obj[currentKey], currentKey, obj);
163 }
164 return memo;
165 };
166
167 // Return the first value which passes a truth test. Aliased as `detect`.
168 _.find = _.detect = function(obj, predicate, context) {
169 var result;
170 predicate = _.iteratee(predicate, context);
171 _.some(obj, function(value, index, list) {
172 if (predicate(value, index, list)) {
173 result = value;
174 return true;
175 }
176 });
177 return result;
178 };
179
180 // Return all the elements that pass a truth test.
181 // Aliased as `select`.
182 _.filter = _.select = function(obj, predicate, context) {
183 var results = [];
184 if (obj == null) return results;
185 predicate = _.iteratee(predicate, context);
186 _.each(obj, function(value, index, list) {
187 if (predicate(value, index, list)) results.push(value);
188 });
189 return results;
190 };
191
192 // Return all the elements for which a truth test fails.
193 _.reject = function(obj, predicate, context) {
194 return _.filter(obj, _.negate(_.iteratee(predicate)), context);
195 };
196
197 // Determine whether all of the elements match a truth test.
198 // Aliased as `all`.
199 _.every = _.all = function(obj, predicate, context) {
200 if (obj == null) return true;
201 predicate = _.iteratee(predicate, context);
202 var keys = obj.length !== +obj.length && _.keys(obj),
203 length = (keys || obj).length,
204 index, currentKey;
205 for (index = 0; index < length; index++) {
206 currentKey = keys ? keys[index] : index;
207 if (!predicate(obj[currentKey], currentKey, obj)) return false;
208 }
209 return true;
210 };
211
212 // Determine if at least one element in the object matches a truth test.
213 // Aliased as `any`.
214 _.some = _.any = function(obj, predicate, context) {
215 if (obj == null) return false;
216 predicate = _.iteratee(predicate, context);
217 var keys = obj.length !== +obj.length && _.keys(obj),
218 length = (keys || obj).length,
219 index, currentKey;
220 for (index = 0; index < length; index++) {
221 currentKey = keys ? keys[index] : index;
222 if (predicate(obj[currentKey], currentKey, obj)) return true;
223 }
224 return false;
225 };
226
227 // Determine if the array or object contains a given value (using `===`).
228 // Aliased as `include`.
229 _.contains = _.include = function(obj, target) {
230 if (obj == null) return false;
231 if (obj.length !== +obj.length) obj = _.values(obj);
232 return _.indexOf(obj, target) >= 0;
233 };
234
235 // Invoke a method (with arguments) on every item in a collection.
236 _.invoke = function(obj, method) {
237 var args = slice.call(arguments, 2);
238 var isFunc = _.isFunction(method);
239 return _.map(obj, function(value) {
240 return (isFunc ? method : value[method]).apply(value, args);
241 });
242 };
243
244 // Convenience version of a common use case of `map`: fetching a property.
245 _.pluck = function(obj, key) {
246 return _.map(obj, _.property(key));
247 };
248
249 // Convenience version of a common use case of `filter`: selecting only objects
250 // containing specific `key:value` pairs.
251 _.where = function(obj, attrs) {
252 return _.filter(obj, _.matches(attrs));
253 };
254
255 // Convenience version of a common use case of `find`: getting the first object
256 // containing specific `key:value` pairs.
257 _.findWhere = function(obj, attrs) {
258 return _.find(obj, _.matches(attrs));
259 };
260
261 // Return the maximum element (or element-based computation).
262 _.max = function(obj, iteratee, context) {
263 var result = -Infinity, lastComputed = -Infinity,
264 value, computed;
265 if (iteratee == null && obj != null) {
266 obj = obj.length === +obj.length ? obj : _.values(obj);
267 for (var i = 0, length = obj.length; i < length; i++) {
268 value = obj[i];
269 if (value > result) {
270 result = value;
271 }
272 }
273 } else {
274 iteratee = _.iteratee(iteratee, context);
275 _.each(obj, function(value, index, list) {
276 computed = iteratee(value, index, list);
277 if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
278 result = value;
279 lastComputed = computed;
280 }
281 });
282 }
283 return result;
284 };
285
286 // Return the minimum element (or element-based computation).
287 _.min = function(obj, iteratee, context) {
288 var result = Infinity, lastComputed = Infinity,
289 value, computed;
290 if (iteratee == null && obj != null) {
291 obj = obj.length === +obj.length ? obj : _.values(obj);
292 for (var i = 0, length = obj.length; i < length; i++) {
293 value = obj[i];
294 if (value < result) {
295 result = value;
296 }
297 }
298 } else {
299 iteratee = _.iteratee(iteratee, context);
300 _.each(obj, function(value, index, list) {
301 computed = iteratee(value, index, list);
302 if (computed < lastComputed || computed === Infinity && result === Infinity) {
303 result = value;
304 lastComputed = computed;
305 }
306 });
307 }
308 return result;
309 };
310
311 // Shuffle a collection, using the modern version of the
312 // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
313 _.shuffle = function(obj) {
314 var set = obj && obj.length === +obj.length ? obj : _.values(obj);
315 var length = set.length;
316 var shuffled = Array(length);
317 for (var index = 0, rand; index < length; index++) {
318 rand = _.random(0, index);
319 if (rand !== index) shuffled[index] = shuffled[rand];
320 shuffled[rand] = set[index];
321 }
322 return shuffled;
323 };
324
325 // Sample **n** random values from a collection.
326 // If **n** is not specified, returns a single random element.
327 // The internal `guard` argument allows it to work with `map`.
328 _.sample = function(obj, n, guard) {
329 if (n == null || guard) {
330 if (obj.length !== +obj.length) obj = _.values(obj);
331 return obj[_.random(obj.length - 1)];
332 }
333 return _.shuffle(obj).slice(0, Math.max(0, n));
334 };
335
336 // Sort the object's values by a criterion produced by an iteratee.
337 _.sortBy = function(obj, iteratee, context) {
338 iteratee = _.iteratee(iteratee, context);
339 return _.pluck(_.map(obj, function(value, index, list) {
340 return {
341 value: value,
342 index: index,
343 criteria: iteratee(value, index, list)
344 };
345 }).sort(function(left, right) {
346 var a = left.criteria;
347 var b = right.criteria;
348 if (a !== b) {
349 if (a > b || a === void 0) return 1;
350 if (a < b || b === void 0) return -1;
351 }
352 return left.index - right.index;
353 }), 'value');
354 };
355
356 // An internal function used for aggregate "group by" operations.
357 var group = function(behavior) {
358 return function(obj, iteratee, context) {
359 var result = {};
360 iteratee = _.iteratee(iteratee, context);
361 _.each(obj, function(value, index) {
362 var key = iteratee(value, index, obj);
363 behavior(result, value, key);
364 });
365 return result;
366 };
367 };
368
369 // Groups the object's values by a criterion. Pass either a string attribute
370 // to group by, or a function that returns the criterion.
371 _.groupBy = group(function(result, value, key) {
372 if (_.has(result, key)) result[key].push(value); else result[key] = [value];
373 });
374
375 // Indexes the object's values by a criterion, similar to `groupBy`, but for
376 // when you know that your index values will be unique.
377 _.indexBy = group(function(result, value, key) {
378 result[key] = value;
379 });
380
381 // Counts instances of an object that group by a certain criterion. Pass
382 // either a string attribute to count by, or a function that returns the
383 // criterion.
384 _.countBy = group(function(result, value, key) {
385 if (_.has(result, key)) result[key]++; else result[key] = 1;
386 });
387
388 // Use a comparator function to figure out the smallest index at which
389 // an object should be inserted so as to maintain order. Uses binary search.
390 _.sortedIndex = function(array, obj, iteratee, context) {
391 iteratee = _.iteratee(iteratee, context, 1);
392 var value = iteratee(obj);
393 var low = 0, high = array.length;
394 while (low < high) {
395 var mid = low + high >>> 1;
396 if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
397 }
398 return low;
399 };
400
401 // Safely create a real, live array from anything iterable.
402 _.toArray = function(obj) {
403 if (!obj) return [];
404 if (_.isArray(obj)) return slice.call(obj);
405 if (obj.length === +obj.length) return _.map(obj, _.identity);
406 return _.values(obj);
407 };
408
409 // Return the number of elements in an object.
410 _.size = function(obj) {
411 if (obj == null) return 0;
412 return obj.length === +obj.length ? obj.length : _.keys(obj).length;
413 };
414
415 // Split a collection into two arrays: one whose elements all satisfy the given
416 // predicate, and one whose elements all do not satisfy the predicate.
417 _.partition = function(obj, predicate, context) {
418 predicate = _.iteratee(predicate, context);
419 var pass = [], fail = [];
420 _.each(obj, function(value, key, obj) {
421 (predicate(value, key, obj) ? pass : fail).push(value);
422 });
423 return [pass, fail];
424 };
425
426 // Array Functions
427 // ---------------
428
429 // Get the first element of an array. Passing **n** will return the first N
430 // values in the array. Aliased as `head` and `take`. The **guard** check
431 // allows it to work with `_.map`.
432 _.first = _.head = _.take = function(array, n, guard) {
433 if (array == null) return void 0;
434 if (n == null || guard) return array[0];
435 if (n < 0) return [];
436 return slice.call(array, 0, n);
437 };
438
439 // Returns everything but the last entry of the array. Especially useful on
440 // the arguments object. Passing **n** will return all the values in
441 // the array, excluding the last N. The **guard** check allows it to work with
442 // `_.map`.
443 _.initial = function(array, n, guard) {
444 return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
445 };
446
447 // Get the last element of an array. Passing **n** will return the last N
448 // values in the array. The **guard** check allows it to work with `_.map`.
449 _.last = function(array, n, guard) {
450 if (array == null) return void 0;
451 if (n == null || guard) return array[array.length - 1];
452 return slice.call(array, Math.max(array.length - n, 0));
453 };
454
455 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
456 // Especially useful on the arguments object. Passing an **n** will return
457 // the rest N values in the array. The **guard**
458 // check allows it to work with `_.map`.
459 _.rest = _.tail = _.drop = function(array, n, guard) {
460 return slice.call(array, n == null || guard ? 1 : n);
461 };
462
463 // Trim out all falsy values from an array.
464 _.compact = function(array) {
465 return _.filter(array, _.identity);
466 };
467
468 // Internal implementation of a recursive `flatten` function.
469 var flatten = function(input, shallow, strict, output) {
470 if (shallow && _.every(input, _.isArray)) {
471 return concat.apply(output, input);
472 }
473 for (var i = 0, length = input.length; i < length; i++) {
474 var value = input[i];
475 if (!_.isArray(value) && !_.isArguments(value)) {
476 if (!strict) output.push(value);
477 } else if (shallow) {
478 push.apply(output, value);
479 } else {
480 flatten(value, shallow, strict, output);
481 }
482 }
483 return output;
484 };
485
486 // Flatten out an array, either recursively (by default), or just one level.
487 _.flatten = function(array, shallow) {
488 return flatten(array, shallow, false, []);
489 };
490
491 // Return a version of the array that does not contain the specified value(s).
492 _.without = function(array) {
493 return _.difference(array, slice.call(arguments, 1));
494 };
495
496 // Produce a duplicate-free version of the array. If the array has already
497 // been sorted, you have the option of using a faster algorithm.
498 // Aliased as `unique`.
499 _.uniq = _.unique = function(array, isSorted, iteratee, context) {
500 if (array == null) return [];
501 if (!_.isBoolean(isSorted)) {
502 context = iteratee;
503 iteratee = isSorted;
504 isSorted = false;
505 }
506 if (iteratee != null) iteratee = _.iteratee(iteratee, context);
507 var result = [];
508 var seen = [];
509 for (var i = 0, length = array.length; i < length; i++) {
510 var value = array[i];
511 if (isSorted) {
512 if (!i || seen !== value) result.push(value);
513 seen = value;
514 } else if (iteratee) {
515 var computed = iteratee(value, i, array);
516 if (_.indexOf(seen, computed) < 0) {
517 seen.push(computed);
518 result.push(value);
519 }
520 } else if (_.indexOf(result, value) < 0) {
521 result.push(value);
522 }
523 }
524 return result;
525 };
526
527 // Produce an array that contains the union: each distinct element from all of
528 // the passed-in arrays.
529 _.union = function() {
530 return _.uniq(flatten(arguments, true, true, []));
531 };
532
533 // Produce an array that contains every item shared between all the
534 // passed-in arrays.
535 _.intersection = function(array) {
536 if (array == null) return [];
537 var result = [];
538 var argsLength = arguments.length;
539 for (var i = 0, length = array.length; i < length; i++) {
540 var item = array[i];
541 if (_.contains(result, item)) continue;
542 for (var j = 1; j < argsLength; j++) {
543 if (!_.contains(arguments[j], item)) break;
544 }
545 if (j === argsLength) result.push(item);
546 }
547 return result;
548 };
549
550 // Take the difference between one array and a number of other arrays.
551 // Only the elements present in just the first array will remain.
552 _.difference = function(array) {
553 var rest = flatten(slice.call(arguments, 1), true, true, []);
554 return _.filter(array, function(value){
555 return !_.contains(rest, value);
556 });
557 };
558
559 // Zip together multiple lists into a single array -- elements that share
560 // an index go together.
561 _.zip = function(array) {
562 if (array == null) return [];
563 var length = _.max(arguments, 'length').length;
564 var results = Array(length);
565 for (var i = 0; i < length; i++) {
566 results[i] = _.pluck(arguments, i);
567 }
568 return results;
569 };
570
571 // Converts lists into objects. Pass either a single array of `[key, value]`
572 // pairs, or two parallel arrays of the same length -- one of keys, and one of
573 // the corresponding values.
574 _.object = function(list, values) {
575 if (list == null) return {};
576 var result = {};
577 for (var i = 0, length = list.length; i < length; i++) {
578 if (values) {
579 result[list[i]] = values[i];
580 } else {
581 result[list[i][0]] = list[i][1];
582 }
583 }
584 return result;
585 };
586
587 // Return the position of the first occurrence of an item in an array,
588 // or -1 if the item is not included in the array.
589 // If the array is large and already in sort order, pass `true`
590 // for **isSorted** to use binary search.
591 _.indexOf = function(array, item, isSorted) {
592 if (array == null) return -1;
593 var i = 0, length = array.length;
594 if (isSorted) {
595 if (typeof isSorted == 'number') {
596 i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
597 } else {
598 i = _.sortedIndex(array, item);
599 return array[i] === item ? i : -1;
600 }
601 }
602 for (; i < length; i++) if (array[i] === item) return i;
603 return -1;
604 };
605
606 _.lastIndexOf = function(array, item, from) {
607 if (array == null) return -1;
608 var idx = array.length;
609 if (typeof from == 'number') {
610 idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
611 }
612 while (--idx >= 0) if (array[idx] === item) return idx;
613 return -1;
614 };
615
616 // Generate an integer Array containing an arithmetic progression. A port of
617 // the native Python `range()` function. See
618 // [the Python documentation](http://docs.python.org/library/functions.html#range).
619 _.range = function(start, stop, step) {
620 if (arguments.length <= 1) {
621 stop = start || 0;
622 start = 0;
623 }
624 step = step || 1;
625
626 var length = Math.max(Math.ceil((stop - start) / step), 0);
627 var range = Array(length);
628
629 for (var idx = 0; idx < length; idx++, start += step) {
630 range[idx] = start;
631 }
632
633 return range;
634 };
635
636 // Function (ahem) Functions
637 // ------------------
638
639 // Reusable constructor function for prototype setting.
640 var Ctor = function(){};
641
642 // Create a function bound to a given object (assigning `this`, and arguments,
643 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
644 // available.
645 _.bind = function(func, context) {
646 var args, bound;
647 if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
648 if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
649 args = slice.call(arguments, 2);
650 bound = function() {
651 if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
652 Ctor.prototype = func.prototype;
653 var self = new Ctor;
654 Ctor.prototype = null;
655 var result = func.apply(self, args.concat(slice.call(arguments)));
656 if (_.isObject(result)) return result;
657 return self;
658 };
659 return bound;
660 };
661
662 // Partially apply a function by creating a version that has had some of its
663 // arguments pre-filled, without changing its dynamic `this` context. _ acts
664 // as a placeholder, allowing any combination of arguments to be pre-filled.
665 _.partial = function(func) {
666 var boundArgs = slice.call(arguments, 1);
667 return function() {
668 var position = 0;
669 var args = boundArgs.slice();
670 for (var i = 0, length = args.length; i < length; i++) {
671 if (args[i] === _) args[i] = arguments[position++];
672 }
673 while (position < arguments.length) args.push(arguments[position++]);
674 return func.apply(this, args);
675 };
676 };
677
678 // Bind a number of an object's methods to that object. Remaining arguments
679 // are the method names to be bound. Useful for ensuring that all callbacks
680 // defined on an object belong to it.
681 _.bindAll = function(obj) {
682 var i, length = arguments.length, key;
683 if (length <= 1) throw new Error('bindAll must be passed function names');
684 for (i = 1; i < length; i++) {
685 key = arguments[i];
686 obj[key] = _.bind(obj[key], obj);
687 }
688 return obj;
689 };
690
691 // Memoize an expensive function by storing its results.
692 _.memoize = function(func, hasher) {
693 var memoize = function(key) {
694 var cache = memoize.cache;
695 var address = hasher ? hasher.apply(this, arguments) : key;
696 if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
697 return cache[address];
698 };
699 memoize.cache = {};
700 return memoize;
701 };
702
703 // Delays a function for the given number of milliseconds, and then calls
704 // it with the arguments supplied.
705 _.delay = function(func, wait) {
706 var args = slice.call(arguments, 2);
707 return setTimeout(function(){
708 return func.apply(null, args);
709 }, wait);
710 };
711
712 // Defers a function, scheduling it to run after the current call stack has
713 // cleared.
714 _.defer = function(func) {
715 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
716 };
717
718 // Returns a function, that, when invoked, will only be triggered at most once
719 // during a given window of time. Normally, the throttled function will run
720 // as much as it can, without ever going more than once per `wait` duration;
721 // but if you'd like to disable the execution on the leading edge, pass
722 // `{leading: false}`. To disable execution on the trailing edge, ditto.
723 _.throttle = function(func, wait, options) {
724 var context, args, result;
725 var timeout = null;
726 var previous = 0;
727 if (!options) options = {};
728 var later = function() {
729 previous = options.leading === false ? 0 : _.now();
730 timeout = null;
731 result = func.apply(context, args);
732 if (!timeout) context = args = null;
733 };
734 return function() {
735 var now = _.now();
736 if (!previous && options.leading === false) previous = now;
737 var remaining = wait - (now - previous);
738 context = this;
739 args = arguments;
740 if (remaining <= 0 || remaining > wait) {
741 clearTimeout(timeout);
742 timeout = null;
743 previous = now;
744 result = func.apply(context, args);
745 if (!timeout) context = args = null;
746 } else if (!timeout && options.trailing !== false) {
747 timeout = setTimeout(later, remaining);
748 }
749 return result;
750 };
751 };
752
753 // Returns a function, that, as long as it continues to be invoked, will not
754 // be triggered. The function will be called after it stops being called for
755 // N milliseconds. If `immediate` is passed, trigger the function on the
756 // leading edge, instead of the trailing.
757 _.debounce = function(func, wait, immediate) {
758 var timeout, args, context, timestamp, result;
759
760 var later = function() {
761 var last = _.now() - timestamp;
762
763 if (last < wait && last > 0) {
764 timeout = setTimeout(later, wait - last);
765 } else {
766 timeout = null;
767 if (!immediate) {
768 result = func.apply(context, args);
769 if (!timeout) context = args = null;
770 }
771 }
772 };
773
774 return function() {
775 context = this;
776 args = arguments;
777 timestamp = _.now();
778 var callNow = immediate && !timeout;
779 if (!timeout) timeout = setTimeout(later, wait);
780 if (callNow) {
781 result = func.apply(context, args);
782 context = args = null;
783 }
784
785 return result;
786 };
787 };
788
789 // Returns the first function passed as an argument to the second,
790 // allowing you to adjust arguments, run code before and after, and
791 // conditionally execute the original function.
792 _.wrap = function(func, wrapper) {
793 return _.partial(wrapper, func);
794 };
795
796 // Returns a negated version of the passed-in predicate.
797 _.negate = function(predicate) {
798 return function() {
799 return !predicate.apply(this, arguments);
800 };
801 };
802
803 // Returns a function that is the composition of a list of functions, each
804 // consuming the return value of the function that follows.
805 _.compose = function() {
806 var args = arguments;
807 var start = args.length - 1;
808 return function() {
809 var i = start;
810 var result = args[start].apply(this, arguments);
811 while (i--) result = args[i].call(this, result);
812 return result;
813 };
814 };
815
816 // Returns a function that will only be executed after being called N times.
817 _.after = function(times, func) {
818 return function() {
819 if (--times < 1) {
820 return func.apply(this, arguments);
821 }
822 };
823 };
824
825 // Returns a function that will only be executed before being called N times.
826 _.before = function(times, func) {
827 var memo;
828 return function() {
829 if (--times > 0) {
830 memo = func.apply(this, arguments);
831 } else {
832 func = null;
833 }
834 return memo;
835 };
836 };
837
838 // Returns a function that will be executed at most one time, no matter how
839 // often you call it. Useful for lazy initialization.
840 _.once = _.partial(_.before, 2);
841
842 // Object Functions
843 // ----------------
844
845 // Retrieve the names of an object's properties.
846 // Delegates to **ECMAScript 5**'s native `Object.keys`
847 _.keys = function(obj) {
848 if (!_.isObject(obj)) return [];
849 if (nativeKeys) return nativeKeys(obj);
850 var keys = [];
851 for (var key in obj) if (_.has(obj, key)) keys.push(key);
852 return keys;
853 };
854
855 // Retrieve the values of an object's properties.
856 _.values = function(obj) {
857 var keys = _.keys(obj);
858 var length = keys.length;
859 var values = Array(length);
860 for (var i = 0; i < length; i++) {
861 values[i] = obj[keys[i]];
862 }
863 return values;
864 };
865
866 // Convert an object into a list of `[key, value]` pairs.
867 _.pairs = function(obj) {
868 var keys = _.keys(obj);
869 var length = keys.length;
870 var pairs = Array(length);
871 for (var i = 0; i < length; i++) {
872 pairs[i] = [keys[i], obj[keys[i]]];
873 }
874 return pairs;
875 };
876
877 // Invert the keys and values of an object. The values must be serializable.
878 _.invert = function(obj) {
879 var result = {};
880 var keys = _.keys(obj);
881 for (var i = 0, length = keys.length; i < length; i++) {
882 result[obj[keys[i]]] = keys[i];
883 }
884 return result;
885 };
886
887 // Return a sorted list of the function names available on the object.
888 // Aliased as `methods`
889 _.functions = _.methods = function(obj) {
890 var names = [];
891 for (var key in obj) {
892 if (_.isFunction(obj[key])) names.push(key);
893 }
894 return names.sort();
895 };
896
897 // Extend a given object with all the properties in passed-in object(s).
898 _.extend = function(obj) {
899 if (!_.isObject(obj)) return obj;
900 var source, prop;
901 for (var i = 1, length = arguments.length; i < length; i++) {
902 source = arguments[i];
903 for (prop in source) {
904 if (hasOwnProperty.call(source, prop)) {
905 obj[prop] = source[prop];
906 }
907 }
908 }
909 return obj;
910 };
911
912 // Return a copy of the object only containing the whitelisted properties.
913 _.pick = function(obj, iteratee, context) {
914 var result = {}, key;
915 if (obj == null) return result;
916 if (_.isFunction(iteratee)) {
917 iteratee = createCallback(iteratee, context);
918 for (key in obj) {
919 var value = obj[key];
920 if (iteratee(value, key, obj)) result[key] = value;
921 }
922 } else {
923 var keys = concat.apply([], slice.call(arguments, 1));
924 obj = new Object(obj);
925 for (var i = 0, length = keys.length; i < length; i++) {
926 key = keys[i];
927 if (key in obj) result[key] = obj[key];
928 }
929 }
930 return result;
931 };
932
933 // Return a copy of the object without the blacklisted properties.
934 _.omit = function(obj, iteratee, context) {
935 if (_.isFunction(iteratee)) {
936 iteratee = _.negate(iteratee);
937 } else {
938 var keys = _.map(concat.apply([], slice.call(arguments, 1)), String);
939 iteratee = function(value, key) {
940 return !_.contains(keys, key);
941 };
942 }
943 return _.pick(obj, iteratee, context);
944 };
945
946 // Fill in a given object with default properties.
947 _.defaults = function(obj) {
948 if (!_.isObject(obj)) return obj;
949 for (var i = 1, length = arguments.length; i < length; i++) {
950 var source = arguments[i];
951 for (var prop in source) {
952 if (obj[prop] === void 0) obj[prop] = source[prop];
953 }
954 }
955 return obj;
956 };
957
958 // Create a (shallow-cloned) duplicate of an object.
959 _.clone = function(obj) {
960 if (!_.isObject(obj)) return obj;
961 return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
962 };
963
964 // Invokes interceptor with the obj, and then returns obj.
965 // The primary purpose of this method is to "tap into" a method chain, in
966 // order to perform operations on intermediate results within the chain.
967 _.tap = function(obj, interceptor) {
968 interceptor(obj);
969 return obj;
970 };
971
972 // Internal recursive comparison function for `isEqual`.
973 var eq = function(a, b, aStack, bStack) {
974 // Identical objects are equal. `0 === -0`, but they aren't identical.
975 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
976 if (a === b) return a !== 0 || 1 / a === 1 / b;
977 // A strict comparison is necessary because `null == undefined`.
978 if (a == null || b == null) return a === b;
979 // Unwrap any wrapped objects.
980 if (a instanceof _) a = a._wrapped;
981 if (b instanceof _) b = b._wrapped;
982 // Compare `[[Class]]` names.
983 var className = toString.call(a);
984 if (className !== toString.call(b)) return false;
985 switch (className) {
986 // Strings, numbers, regular expressions, dates, and booleans are compared by value.
987 case '[object RegExp]':
988 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
989 case '[object String]':
990 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
991 // equivalent to `new String("5")`.
992 return '' + a === '' + b;
993 case '[object Number]':
994 // `NaN`s are equivalent, but non-reflexive.
995 // Object(NaN) is equivalent to NaN
996 if (+a !== +a) return +b !== +b;
997 // An `egal` comparison is performed for other numeric values.
998 return +a === 0 ? 1 / +a === 1 / b : +a === +b;
999 case '[object Date]':
1000 case '[object Boolean]':
1001 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1002 // millisecond representations. Note that invalid dates with millisecond representations
1003 // of `NaN` are not equivalent.
1004 return +a === +b;
1005 }
1006 if (typeof a != 'object' || typeof b != 'object') return false;
1007 // Assume equality for cyclic structures. The algorithm for detecting cyclic
1008 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1009 var length = aStack.length;
1010 while (length--) {
1011 // Linear search. Performance is inversely proportional to the number of
1012 // unique nested structures.
1013 if (aStack[length] === a) return bStack[length] === b;
1014 }
1015 // Objects with different constructors are not equivalent, but `Object`s
1016 // from different frames are.
1017 var aCtor = a.constructor, bCtor = b.constructor;
1018 if (
1019 aCtor !== bCtor &&
1020 // Handle Object.create(x) cases
1021 'constructor' in a && 'constructor' in b &&
1022 !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
1023 _.isFunction(bCtor) && bCtor instanceof bCtor)
1024 ) {
1025 return false;
1026 }
1027 // Add the first object to the stack of traversed objects.
1028 aStack.push(a);
1029 bStack.push(b);
1030 var size, result;
1031 // Recursively compare objects and arrays.
1032 if (className === '[object Array]') {
1033 // Compare array lengths to determine if a deep comparison is necessary.
1034 size = a.length;
1035 result = size === b.length;
1036 if (result) {
1037 // Deep compare the contents, ignoring non-numeric properties.
1038 while (size--) {
1039 if (!(result = eq(a[size], b[size], aStack, bStack))) break;
1040 }
1041 }
1042 } else {
1043 // Deep compare objects.
1044 var keys = _.keys(a), key;
1045 size = keys.length;
1046 // Ensure that both objects contain the same number of properties before comparing deep equality.
1047 result = _.keys(b).length === size;
1048 if (result) {
1049 while (size--) {
1050 // Deep compare each member
1051 key = keys[size];
1052 if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
1053 }
1054 }
1055 }
1056 // Remove the first object from the stack of traversed objects.
1057 aStack.pop();
1058 bStack.pop();
1059 return result;
1060 };
1061
1062 // Perform a deep comparison to check if two objects are equal.
1063 _.isEqual = function(a, b) {
1064 return eq(a, b, [], []);
1065 };
1066
1067 // Is a given array, string, or object empty?
1068 // An "empty" object has no enumerable own-properties.
1069 _.isEmpty = function(obj) {
1070 if (obj == null) return true;
1071 if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0;
1072 for (var key in obj) if (_.has(obj, key)) return false;
1073 return true;
1074 };
1075
1076 // Is a given value a DOM element?
1077 _.isElement = function(obj) {
1078 return !!(obj && obj.nodeType === 1);
1079 };
1080
1081 // Is a given value an array?
1082 // Delegates to ECMA5's native Array.isArray
1083 _.isArray = nativeIsArray || function(obj) {
1084 return toString.call(obj) === '[object Array]';
1085 };
1086
1087 // Is a given variable an object?
1088 _.isObject = function(obj) {
1089 var type = typeof obj;
1090 return type === 'function' || type === 'object' && !!obj;
1091 };
1092
1093 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
1094 _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
1095 _['is' + name] = function(obj) {
1096 return toString.call(obj) === '[object ' + name + ']';
1097 };
1098 });
1099
1100 // Define a fallback version of the method in browsers (ahem, IE), where
1101 // there isn't any inspectable "Arguments" type.
1102 if (!_.isArguments(arguments)) {
1103 _.isArguments = function(obj) {
1104 return _.has(obj, 'callee');
1105 };
1106 }
1107
1108 // Optimize `isFunction` if appropriate. Work around an IE 11 bug.
1109 if (typeof /./ !== 'function') {
1110 _.isFunction = function(obj) {
1111 return typeof obj == 'function' || false;
1112 };
1113 }
1114
1115 // Is a given object a finite number?
1116 _.isFinite = function(obj) {
1117 return isFinite(obj) && !isNaN(parseFloat(obj));
1118 };
1119
1120 // Is the given value `NaN`? (NaN is the only number which does not equal itself).
1121 _.isNaN = function(obj) {
1122 return _.isNumber(obj) && obj !== +obj;
1123 };
1124
1125 // Is a given value a boolean?
1126 _.isBoolean = function(obj) {
1127 return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
1128 };
1129
1130 // Is a given value equal to null?
1131 _.isNull = function(obj) {
1132 return obj === null;
1133 };
1134
1135 // Is a given variable undefined?
1136 _.isUndefined = function(obj) {
1137 return obj === void 0;
1138 };
1139
1140 // Shortcut function for checking if an object has a given property directly
1141 // on itself (in other words, not on a prototype).
1142 _.has = function(obj, key) {
1143 return obj != null && hasOwnProperty.call(obj, key);
1144 };
1145
1146 // Utility Functions
1147 // -----------------
1148
1149 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1150 // previous owner. Returns a reference to the Underscore object.
1151 _.noConflict = function() {
1152 root._ = previousUnderscore;
1153 return this;
1154 };
1155
1156 // Keep the identity function around for default iteratees.
1157 _.identity = function(value) {
1158 return value;
1159 };
1160
1161 _.constant = function(value) {
1162 return function() {
1163 return value;
1164 };
1165 };
1166
1167 _.noop = function(){};
1168
1169 _.property = function(key) {
1170 return function(obj) {
1171 return obj[key];
1172 };
1173 };
1174
1175 // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
1176 _.matches = function(attrs) {
1177 var pairs = _.pairs(attrs), length = pairs.length;
1178 return function(obj) {
1179 if (obj == null) return !length;
1180 obj = new Object(obj);
1181 for (var i = 0; i < length; i++) {
1182 var pair = pairs[i], key = pair[0];
1183 if (pair[1] !== obj[key] || !(key in obj)) return false;
1184 }
1185 return true;
1186 };
1187 };
1188
1189 // Run a function **n** times.
1190 _.times = function(n, iteratee, context) {
1191 var accum = Array(Math.max(0, n));
1192 iteratee = createCallback(iteratee, context, 1);
1193 for (var i = 0; i < n; i++) accum[i] = iteratee(i);
1194 return accum;
1195 };
1196
1197 // Return a random integer between min and max (inclusive).
1198 _.random = function(min, max) {
1199 if (max == null) {
1200 max = min;
1201 min = 0;
1202 }
1203 return min + Math.floor(Math.random() * (max - min + 1));
1204 };
1205
1206 // A (possibly faster) way to get the current timestamp as an integer.
1207 _.now = Date.now || function() {
1208 return new Date().getTime();
1209 };
1210
1211 // List of HTML entities for escaping.
1212 var escapeMap = {
1213 '&': '&amp;',
1214 '<': '&lt;',
1215 '>': '&gt;',
1216 '"': '&quot;',
1217 "'": '&#x27;',
1218 '`': '&#x60;'
1219 };
1220 var unescapeMap = _.invert(escapeMap);
1221
1222 // Functions for escaping and unescaping strings to/from HTML interpolation.
1223 var createEscaper = function(map) {
1224 var escaper = function(match) {
1225 return map[match];
1226 };
1227 // Regexes for identifying a key that needs to be escaped
1228 var source = '(?:' + _.keys(map).join('|') + ')';
1229 var testRegexp = RegExp(source);
1230 var replaceRegexp = RegExp(source, 'g');
1231 return function(string) {
1232 string = string == null ? '' : '' + string;
1233 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
1234 };
1235 };
1236 _.escape = createEscaper(escapeMap);
1237 _.unescape = createEscaper(unescapeMap);
1238
1239 // If the value of the named `property` is a function then invoke it with the
1240 // `object` as context; otherwise, return it.
1241 _.result = function(object, property) {
1242 if (object == null) return void 0;
1243 var value = object[property];
1244 return _.isFunction(value) ? object[property]() : value;
1245 };
1246
1247 // Generate a unique integer id (unique within the entire client session).
1248 // Useful for temporary DOM ids.
1249 var idCounter = 0;
1250 _.uniqueId = function(prefix) {
1251 var id = ++idCounter + '';
1252 return prefix ? prefix + id : id;
1253 };
1254
1255 // By default, Underscore uses ERB-style template delimiters, change the
1256 // following template settings to use alternative delimiters.
1257 _.templateSettings = {
1258 evaluate : /<%([\s\S]+?)%>/g,
1259 interpolate : /<%=([\s\S]+?)%>/g,
1260 escape : /<%-([\s\S]+?)%>/g
1261 };
1262
1263 // When customizing `templateSettings`, if you don't want to define an
1264 // interpolation, evaluation or escaping regex, we need one that is
1265 // guaranteed not to match.
1266 var noMatch = /(.)^/;
1267
1268 // Certain characters need to be escaped so that they can be put into a
1269 // string literal.
1270 var escapes = {
1271 "'": "'",
1272 '\\': '\\',
1273 '\r': 'r',
1274 '\n': 'n',
1275 '\u2028': 'u2028',
1276 '\u2029': 'u2029'
1277 };
1278
1279 var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
1280
1281 var escapeChar = function(match) {
1282 return '\\' + escapes[match];
1283 };
1284
1285 // JavaScript micro-templating, similar to John Resig's implementation.
1286 // Underscore templating handles arbitrary delimiters, preserves whitespace,
1287 // and correctly escapes quotes within interpolated code.
1288 // NB: `oldSettings` only exists for backwards compatibility.
1289 _.template = function(text, settings, oldSettings) {
1290 if (!settings && oldSettings) settings = oldSettings;
1291 settings = _.defaults({}, settings, _.templateSettings);
1292
1293 // Combine delimiters into one regular expression via alternation.
1294 var matcher = RegExp([
1295 (settings.escape || noMatch).source,
1296 (settings.interpolate || noMatch).source,
1297 (settings.evaluate || noMatch).source
1298 ].join('|') + '|$', 'g');
1299
1300 // Compile the template source, escaping string literals appropriately.
1301 var index = 0;
1302 var source = "__p+='";
1303 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
1304 source += text.slice(index, offset).replace(escaper, escapeChar);
1305 index = offset + match.length;
1306
1307 if (escape) {
1308 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
1309 } else if (interpolate) {
1310 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
1311 } else if (evaluate) {
1312 source += "';\n" + evaluate + "\n__p+='";
1313 }
1314
1315 // Adobe VMs need the match returned to produce the correct offest.
1316 return match;
1317 });
1318 source += "';\n";
1319
1320 // If a variable is not specified, place data values in local scope.
1321 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
1322
1323 source = "var __t,__p='',__j=Array.prototype.join," +
1324 "print=function(){__p+=__j.call(arguments,'');};\n" +
1325 source + 'return __p;\n';
1326
1327 try {
1328 var render = new Function(settings.variable || 'obj', '_', source);
1329 } catch (e) {
1330 e.source = source;
1331 throw e;
1332 }
1333
1334 var template = function(data) {
1335 return render.call(this, data, _);
1336 };
1337
1338 // Provide the compiled source as a convenience for precompilation.
1339 var argument = settings.variable || 'obj';
1340 template.source = 'function(' + argument + '){\n' + source + '}';
1341
1342 return template;
1343 };
1344
1345 // Add a "chain" function. Start chaining a wrapped Underscore object.
1346 _.chain = function(obj) {
1347 var instance = _(obj);
1348 instance._chain = true;
1349 return instance;
1350 };
1351
1352 // OOP
1353 // ---------------
1354 // If Underscore is called as a function, it returns a wrapped object that
1355 // can be used OO-style. This wrapper holds altered versions of all the
1356 // underscore functions. Wrapped objects may be chained.
1357
1358 // Helper function to continue chaining intermediate results.
1359 var result = function(obj) {
1360 return this._chain ? _(obj).chain() : obj;
1361 };
1362
1363 // Add your own custom functions to the Underscore object.
1364 _.mixin = function(obj) {
1365 _.each(_.functions(obj), function(name) {
1366 var func = _[name] = obj[name];
1367 _.prototype[name] = function() {
1368 var args = [this._wrapped];
1369 push.apply(args, arguments);
1370 return result.call(this, func.apply(_, args));
1371 };
1372 });
1373 };
1374
1375 // Add all of the Underscore functions to the wrapper object.
1376 _.mixin(_);
1377
1378 // Add all mutator Array functions to the wrapper.
1379 _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1380 var method = ArrayProto[name];
1381 _.prototype[name] = function() {
1382 var obj = this._wrapped;
1383 method.apply(obj, arguments);
1384 if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
1385 return result.call(this, obj);
1386 };
1387 });
1388
1389 // Add all accessor Array functions to the wrapper.
1390 _.each(['concat', 'join', 'slice'], function(name) {
1391 var method = ArrayProto[name];
1392 _.prototype[name] = function() {
1393 return result.call(this, method.apply(this._wrapped, arguments));
1394 };
1395 });
1396
1397 // Extracts the result from a wrapped and chained object.
1398 _.prototype.value = function() {
1399 return this._wrapped;
1400 };
1401
1402 // AMD registration happens at the end for compatibility with AMD loaders
1403 // that may not enforce next-turn semantics on modules. Even though general
1404 // practice for AMD registration is to be anonymous, underscore registers
1405 // as a named module because, like jQuery, it is a base library that is
1406 // popular enough to be bundled in a third party lib, but not be part of
1407 // an AMD load request. Those cases could generate an error when an
1408 // anonymous define() is called outside of a loader request.
1409 if (typeof define === 'function' && define.amd) {
1410 define('underscore', [], function() {
1411 return _;
1412 });
1413 }
1414 }.call(this));
5 var n="1.13.1",r="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||Function("return this")()||{},t=Array.prototype,e=Object.prototype,u="undefined"!=typeof Symbol?Symbol.prototype:null,o=t.push,i=t.slice,a=e.toString,f=e.hasOwnProperty,c="undefined"!=typeof ArrayBuffer,l="undefined"!=typeof DataView,s=Array.isArray,p=Object.keys,v=Object.create,h=c&&ArrayBuffer.isView,y=isNaN,d=isFinite,g=!{toString:null}.propertyIsEnumerable("toString"),b=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],m=Math.pow(2,53)-1;function j(n,r){return r=null==r?n.length-1:+r,function(){for(var t=Math.max(arguments.length-r,0),e=Array(t),u=0;u<t;u++)e[u]=arguments[u+r];switch(r){case 0:return n.call(this,e);case 1:return n.call(this,arguments[0],e);case 2:return n.call(this,arguments[0],arguments[1],e)}var o=Array(r+1);for(u=0;u<r;u++)o[u]=arguments[u];return o[r]=e,n.apply(this,o)}}function _(n){var r=typeof n;return"function"===r||"object"===r&&!!n}function w(n){return void 0===n}function A(n){return!0===n||!1===n||"[object Boolean]"===a.call(n)}function x(n){var r="[object "+n+"]";return function(n){return a.call(n)===r}}var S=x("String"),O=x("Number"),M=x("Date"),E=x("RegExp"),B=x("Error"),N=x("Symbol"),I=x("ArrayBuffer"),T=x("Function"),k=r.document&&r.document.childNodes;"function"!=typeof/./&&"object"!=typeof Int8Array&&"function"!=typeof k&&(T=function(n){return"function"==typeof n||!1});var D=T,R=x("Object"),F=l&&R(new DataView(new ArrayBuffer(8))),V="undefined"!=typeof Map&&R(new Map),P=x("DataView");var q=F?function(n){return null!=n&&D(n.getInt8)&&I(n.buffer)}:P,U=s||x("Array");function W(n,r){return null!=n&&f.call(n,r)}var z=x("Arguments");!function(){z(arguments)||(z=function(n){return W(n,"callee")})}();var L=z;function $(n){return O(n)&&y(n)}function C(n){return function(){return n}}function K(n){return function(r){var t=n(r);return"number"==typeof t&&t>=0&&t<=m}}function J(n){return function(r){return null==r?void 0:r[n]}}var G=J("byteLength"),H=K(G),Q=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:C(!1),Y=J("length");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e<t;++e)r[n[e]]=!0;return{contains:function(n){return r[n]},push:function(t){return r[t]=!0,n.push(t)}}}(r);var t=b.length,u=n.constructor,o=D(u)&&u.prototype||e,i="constructor";for(W(n,i)&&!r.contains(i)&&r.push(i);t--;)(i=b[t])in n&&n[i]!==o[i]&&!r.contains(i)&&r.push(i)}function nn(n){if(!_(n))return[];if(p)return p(n);var r=[];for(var t in n)W(n,t)&&r.push(t);return g&&Z(n,r),r}function rn(n,r){var t=nn(r),e=t.length;if(null==n)return!e;for(var u=Object(n),o=0;o<e;o++){var i=t[o];if(r[i]!==u[i]||!(i in u))return!1}return!0}function tn(n){return n instanceof tn?n:this instanceof tn?void(this._wrapped=n):new tn(n)}function en(n){return new Uint8Array(n.buffer||n,n.byteOffset||0,G(n))}tn.VERSION=n,tn.prototype.value=function(){return this._wrapped},tn.prototype.valueOf=tn.prototype.toJSON=tn.prototype.value,tn.prototype.toString=function(){return String(this._wrapped)};var un="[object DataView]";function on(n,r,t,e){if(n===r)return 0!==n||1/n==1/r;if(null==n||null==r)return!1;if(n!=n)return r!=r;var o=typeof n;return("function"===o||"object"===o||"object"==typeof r)&&function n(r,t,e,o){r instanceof tn&&(r=r._wrapped);t instanceof tn&&(t=t._wrapped);var i=a.call(r);if(i!==a.call(t))return!1;if(F&&"[object Object]"==i&&q(r)){if(!q(t))return!1;i=un}switch(i){case"[object RegExp]":case"[object String]":return""+r==""+t;case"[object Number]":return+r!=+r?+t!=+t:0==+r?1/+r==1/t:+r==+t;case"[object Date]":case"[object Boolean]":return+r==+t;case"[object Symbol]":return u.valueOf.call(r)===u.valueOf.call(t);case"[object ArrayBuffer]":case un:return n(en(r),en(t),e,o)}var f="[object Array]"===i;if(!f&&X(r)){if(G(r)!==G(t))return!1;if(r.buffer===t.buffer&&r.byteOffset===t.byteOffset)return!0;f=!0}if(!f){if("object"!=typeof r||"object"!=typeof t)return!1;var c=r.constructor,l=t.constructor;if(c!==l&&!(D(c)&&c instanceof c&&D(l)&&l instanceof l)&&"constructor"in r&&"constructor"in t)return!1}o=o||[];var s=(e=e||[]).length;for(;s--;)if(e[s]===r)return o[s]===t;if(e.push(r),o.push(t),f){if((s=r.length)!==t.length)return!1;for(;s--;)if(!on(r[s],t[s],e,o))return!1}else{var p,v=nn(r);if(s=v.length,nn(t).length!==s)return!1;for(;s--;)if(p=v[s],!W(t,p)||!on(r[p],t[p],e,o))return!1}return e.pop(),o.pop(),!0}(n,r,t,e)}function an(n){if(!_(n))return[];var r=[];for(var t in n)r.push(t);return g&&Z(n,r),r}function fn(n){var r=Y(n);return function(t){if(null==t)return!1;var e=an(t);if(Y(e))return!1;for(var u=0;u<r;u++)if(!D(t[n[u]]))return!1;return n!==hn||!D(t[cn])}}var cn="forEach",ln="has",sn=["clear","delete"],pn=["get",ln,"set"],vn=sn.concat(cn,pn),hn=sn.concat(pn),yn=["add"].concat(sn,cn,ln),dn=V?fn(vn):x("Map"),gn=V?fn(hn):x("WeakMap"),bn=V?fn(yn):x("Set"),mn=x("WeakSet");function jn(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=n[r[u]];return e}function _n(n){for(var r={},t=nn(n),e=0,u=t.length;e<u;e++)r[n[t[e]]]=t[e];return r}function wn(n){var r=[];for(var t in n)D(n[t])&&r.push(t);return r.sort()}function An(n,r){return function(t){var e=arguments.length;if(r&&(t=Object(t)),e<2||null==t)return t;for(var u=1;u<e;u++)for(var o=arguments[u],i=n(o),a=i.length,f=0;f<a;f++){var c=i[f];r&&void 0!==t[c]||(t[c]=o[c])}return t}}var xn=An(an),Sn=An(nn),On=An(an,!0);function Mn(n){if(!_(n))return{};if(v)return v(n);var r=function(){};r.prototype=n;var t=new r;return r.prototype=null,t}function En(n){return _(n)?U(n)?n.slice():xn({},n):n}function Bn(n){return U(n)?n:[n]}function Nn(n){return tn.toPath(n)}function In(n,r){for(var t=r.length,e=0;e<t;e++){if(null==n)return;n=n[r[e]]}return t?n:void 0}function Tn(n,r,t){var e=In(n,Nn(r));return w(e)?t:e}function kn(n){return n}function Dn(n){return n=Sn({},n),function(r){return rn(r,n)}}function Rn(n){return n=Nn(n),function(r){return In(r,n)}}function Fn(n,r,t){if(void 0===r)return n;switch(null==t?3:t){case 1:return function(t){return n.call(r,t)};case 3:return function(t,e,u){return n.call(r,t,e,u)};case 4:return function(t,e,u,o){return n.call(r,t,e,u,o)}}return function(){return n.apply(r,arguments)}}function Vn(n,r,t){return null==n?kn:D(n)?Fn(n,r,t):_(n)&&!U(n)?Dn(n):Rn(n)}function Pn(n,r){return Vn(n,r,1/0)}function qn(n,r,t){return tn.iteratee!==Pn?tn.iteratee(n,r):Vn(n,r,t)}function Un(){}function Wn(n,r){return null==r&&(r=n,n=0),n+Math.floor(Math.random()*(r-n+1))}tn.toPath=Bn,tn.iteratee=Pn;var zn=Date.now||function(){return(new Date).getTime()};function Ln(n){var r=function(r){return n[r]},t="(?:"+nn(n).join("|")+")",e=RegExp(t),u=RegExp(t,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,r):n}}var $n={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},Cn=Ln($n),Kn=Ln(_n($n)),Jn=tn.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},Gn=/(.)^/,Hn={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},Qn=/\\|'|\r|\n|\u2028|\u2029/g;function Xn(n){return"\\"+Hn[n]}var Yn=/^\s*(\w|\$)+\s*$/;var Zn=0;function nr(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var rr=j((function(n,r){var t=rr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a<o;a++)i[a]=r[a]===t?arguments[u++]:r[a];for(;u<arguments.length;)i.push(arguments[u++]);return nr(n,e,this,this,i)};return e}));rr.placeholder=tn;var tr=j((function(n,r,t){if(!D(n))throw new TypeError("Bind must be called on a function");var e=j((function(u){return nr(n,e,r,this,t.concat(u))}));return e})),er=K(Y);function ur(n,r,t,e){if(e=e||[],r||0===r){if(r<=0)return e.concat(n)}else r=1/0;for(var u=e.length,o=0,i=Y(n);o<i;o++){var a=n[o];if(er(a)&&(U(a)||L(a)))if(r>1)ur(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f<c;)e[u++]=a[f++];else t||(e[u++]=a)}return e}var or=j((function(n,r){var t=(r=ur(r,!1,!1)).length;if(t<1)throw new Error("bindAll must be passed function names");for(;t--;){var e=r[t];n[e]=tr(n[e],n)}return n}));var ir=j((function(n,r,t){return setTimeout((function(){return n.apply(null,t)}),r)})),ar=rr(ir,tn,1);function fr(n){return function(){return!n.apply(this,arguments)}}function cr(n,r){var t;return function(){return--n>0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var lr=rr(cr,2);function sr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o<i;o++)if(r(n[e=u[o]],e,n))return e}function pr(n){return function(r,t,e){t=qn(t,e);for(var u=Y(r),o=n>0?0:u-1;o>=0&&o<u;o+=n)if(t(r[o],o,r))return o;return-1}}var vr=pr(1),hr=pr(-1);function yr(n,r,t,e){for(var u=(t=qn(t,e,1))(r),o=0,i=Y(n);o<i;){var a=Math.floor((o+i)/2);t(n[a])<u?o=a+1:i=a}return o}function dr(n,r,t){return function(e,u,o){var a=0,f=Y(e);if("number"==typeof o)n>0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),$))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o<f;o+=n)if(e[o]===u)return o;return-1}}var gr=dr(1,vr,yr),br=dr(-1,hr);function mr(n,r,t){var e=(er(n)?vr:sr)(n,r,t);if(void 0!==e&&-1!==e)return n[e]}function jr(n,r,t){var e,u;if(r=Fn(r,t),er(n))for(e=0,u=n.length;e<u;e++)r(n[e],e,n);else{var o=nn(n);for(e=0,u=o.length;e<u;e++)r(n[o[e]],o[e],n)}return n}function _r(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=Array(u),i=0;i<u;i++){var a=e?e[i]:i;o[i]=r(n[a],a,n)}return o}function wr(n){var r=function(r,t,e,u){var o=!er(r)&&nn(r),i=(o||r).length,a=n>0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a<i;a+=n){var f=o?o[a]:a;e=t(e,r[f],f,r)}return e};return function(n,t,e,u){var o=arguments.length>=3;return r(n,Fn(t,u,4),e,o)}}var Ar=wr(1),xr=wr(-1);function Sr(n,r,t){var e=[];return r=qn(r,t),jr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Or(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(!r(n[i],i,n))return!1}return!0}function Mr(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(r(n[i],i,n))return!0}return!1}function Er(n,r,t,e){return er(n)||(n=jn(n)),("number"!=typeof t||e)&&(t=0),gr(n,r,t)>=0}var Br=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),_r(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Nr(n,r){return _r(n,Rn(r))}function Ir(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e>o&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Tr(n,r,t){if(null==r||t)return er(n)||(n=jn(n)),n[Wn(n.length-1)];var e=er(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i<r;i++){var a=Wn(i,o),f=e[i];e[i]=e[a],e[a]=f}return e.slice(0,r)}function kr(n,r){return function(t,e,u){var o=r?[[],[]]:{};return e=qn(e,u),jr(t,(function(r,u){var i=e(r,u,t);n(o,r,i)})),o}}var Dr=kr((function(n,r,t){W(n,t)?n[t].push(r):n[t]=[r]})),Rr=kr((function(n,r,t){n[t]=r})),Fr=kr((function(n,r,t){W(n,t)?n[t]++:n[t]=1})),Vr=kr((function(n,r,t){n[t?0:1].push(r)}),!0),Pr=/[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;function qr(n,r,t){return r in t}var Ur=j((function(n,r){var t={},e=r[0];if(null==n)return t;D(e)?(r.length>1&&(e=Fn(e,r[1])),r=an(n)):(e=qr,r=ur(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u<o;u++){var i=r[u],a=n[i];e(a,i,n)&&(t[i]=a)}return t})),Wr=j((function(n,r){var t,e=r[0];return D(e)?(e=fr(e),r.length>1&&(t=r[1])):(r=_r(ur(r,!1,!1),String),e=function(n,t){return!Er(r,t)}),Ur(n,e,t)}));function zr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function Lr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:zr(n,n.length-r)}function $r(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=ur(r,!0,!0),Sr(n,(function(n){return!Er(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);i<a;i++){var f=n[i],c=t?t(f,i,n):f;r&&!t?(i&&o===c||u.push(f),o=c):t?Er(o,c)||(o.push(c),u.push(f)):Er(u,f)||u.push(f)}return u}var Gr=j((function(n){return Jr(ur(n,!0,!0))}));function Hr(n){for(var r=n&&Ir(n,Y).length||0,t=Array(r),e=0;e<r;e++)t[e]=Nr(n,e);return t}var Qr=j(Hr);function Xr(n,r){return n._chain?tn(r).chain():r}function Yr(n){return jr(wn(n),(function(r){var t=tn[r]=n[r];tn.prototype[r]=function(){var n=[this._wrapped];return o.apply(n,arguments),Xr(this,t.apply(tn,n))}})),tn}jr(["pop","push","reverse","shift","sort","splice","unshift"],(function(n){var r=t[n];tn.prototype[n]=function(){var t=this._wrapped;return null!=t&&(r.apply(t,arguments),"shift"!==n&&"splice"!==n||0!==t.length||delete t[0]),Xr(this,t)}})),jr(["concat","join","slice"],(function(n){var r=t[n];tn.prototype[n]=function(){var n=this._wrapped;return null!=n&&(n=r.apply(n,arguments)),Xr(this,n)}}));var Zr=Yr({__proto__:null,VERSION:n,restArguments:j,isObject:_,isNull:function(n){return null===n},isUndefined:w,isBoolean:A,isElement:function(n){return!(!n||1!==n.nodeType)},isString:S,isNumber:O,isDate:M,isRegExp:E,isError:B,isSymbol:N,isArrayBuffer:I,isDataView:q,isArray:U,isFunction:D,isArguments:L,isFinite:function(n){return!N(n)&&d(n)&&!isNaN(parseFloat(n))},isNaN:$,isTypedArray:X,isEmpty:function(n){if(null==n)return!0;var r=Y(n);return"number"==typeof r&&(U(n)||S(n)||L(n))?0===r:0===Y(nn(n))},isMatch:rn,isEqual:function(n,r){return on(n,r)},isMap:dn,isWeakMap:gn,isSet:bn,isWeakSet:mn,keys:nn,allKeys:an,values:jn,pairs:function(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=[r[u],n[r[u]]];return e},invert:_n,functions:wn,methods:wn,extend:xn,extendOwn:Sn,assign:Sn,defaults:On,create:function(n,r){var t=Mn(n);return r&&Sn(t,r),t},clone:En,tap:function(n,r){return r(n),n},get:Tn,has:function(n,r){for(var t=(r=Nn(r)).length,e=0;e<t;e++){var u=r[e];if(!W(n,u))return!1;n=n[u]}return!!t},mapObject:function(n,r,t){r=qn(r,t);for(var e=nn(n),u=e.length,o={},i=0;i<u;i++){var a=e[i];o[a]=r(n[a],a,n)}return o},identity:kn,constant:C,noop:Un,toPath:Bn,property:Rn,propertyOf:function(n){return null==n?Un:function(r){return Tn(n,r)}},matcher:Dn,matches:Dn,times:function(n,r,t){var e=Array(Math.max(0,n));r=Fn(r,t,1);for(var u=0;u<n;u++)e[u]=r(u);return e},random:Wn,now:zn,escape:Cn,unescape:Kn,templateSettings:Jn,template:function(n,r,t){!r&&t&&(r=t),r=On({},r,tn.templateSettings);var e=RegExp([(r.escape||Gn).source,(r.interpolate||Gn).source,(r.evaluate||Gn).source].join("|")+"|$","g"),u=0,o="__p+='";n.replace(e,(function(r,t,e,i,a){return o+=n.slice(u,a).replace(Qn,Xn),u=a+r.length,t?o+="'+\n((__t=("+t+"))==null?'':_.escape(__t))+\n'":e?o+="'+\n((__t=("+e+"))==null?'':__t)+\n'":i&&(o+="';\n"+i+"\n__p+='"),r})),o+="';\n";var i,a=r.variable;if(a){if(!Yn.test(a))throw new Error("variable is not a bare identifier: "+a)}else o="with(obj||{}){\n"+o+"}\n",a="obj";o="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{i=new Function(a,"_",o)}catch(n){throw n.source=o,n}var f=function(n){return i.call(this,n,tn)};return f.source="function("+a+"){\n"+o+"}",f},result:function(n,r,t){var e=(r=Nn(r)).length;if(!e)return D(t)?t.call(n):t;for(var u=0;u<e;u++){var o=null==n?void 0:n[r[u]];void 0===o&&(o=t,u=e),n=D(o)?o.call(n):o}return n},uniqueId:function(n){var r=++Zn+"";return n?n+r:r},chain:function(n){var r=tn(n);return r._chain=!0,r},iteratee:Pn,partial:rr,bind:tr,bindAll:or,memoize:function(n,r){var t=function(e){var u=t.cache,o=""+(r?r.apply(this,arguments):e);return W(u,o)||(u[o]=n.apply(this,arguments)),u[o]};return t.cache={},t},delay:ir,defer:ar,throttle:function(n,r,t){var e,u,o,i,a=0;t||(t={});var f=function(){a=!1===t.leading?0:zn(),e=null,i=n.apply(u,o),e||(u=o=null)},c=function(){var c=zn();a||!1!==t.leading||(a=c);var l=r-(c-a);return u=this,o=arguments,l<=0||l>r?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o,i,a,f=function(){var c=zn()-u;r>c?e=setTimeout(f,r-c):(e=null,t||(i=n.apply(a,o)),e||(o=a=null))},c=j((function(c){return a=this,o=c,u=zn(),e||(e=setTimeout(f,r),t&&(i=n.apply(a,o))),i}));return c.cancel=function(){clearTimeout(e),e=o=a=null},c},wrap:function(n,r){return rr(r,n)},negate:fr,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:cr,once:lr,findKey:sr,findIndex:vr,findLastIndex:hr,sortedIndex:yr,indexOf:gr,lastIndexOf:br,find:mr,detect:mr,findWhere:function(n,r){return mr(n,Dn(r))},each:jr,forEach:jr,map:_r,collect:_r,reduce:Ar,foldl:Ar,inject:Ar,reduceRight:xr,foldr:xr,filter:Sr,select:Sr,reject:function(n,r,t){return Sr(n,fr(qn(r)),t)},every:Or,all:Or,some:Mr,any:Mr,contains:Er,includes:Er,include:Er,invoke:Br,pluck:Nr,where:function(n,r){return Sr(n,Dn(r))},max:Ir,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e<o&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))<i||u===1/0&&o===1/0)&&(o=n,i=u)}));return o},shuffle:function(n){return Tr(n,1/0)},sample:Tr,sortBy:function(n,r,t){var e=0;return r=qn(r,t),Nr(_r(n,(function(n,t,u){return{value:n,index:e++,criteria:r(n,t,u)}})).sort((function(n,r){var t=n.criteria,e=r.criteria;if(t!==e){if(t>e||void 0===t)return 1;if(t<e||void 0===e)return-1}return n.index-r.index})),"value")},groupBy:Dr,indexBy:Rr,countBy:Fr,partition:Vr,toArray:function(n){return n?U(n)?i.call(n):S(n)?n.match(Pr):er(n)?_r(n,kn):jn(n):[]},size:function(n){return null==n?0:er(n)?n.length:nn(n).length},pick:Ur,omit:Wr,first:Lr,head:Lr,take:Lr,initial:zr,last:function(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[n.length-1]:$r(n,Math.max(0,n.length-r))},rest:$r,tail:$r,drop:$r,compact:function(n){return Sr(n,Boolean)},flatten:function(n,r){return ur(n,r,!1)},without:Kr,uniq:Jr,unique:Jr,union:Gr,intersection:function(n){for(var r=[],t=arguments.length,e=0,u=Y(n);e<u;e++){var o=n[e];if(!Er(r,o)){var i;for(i=1;i<t&&Er(arguments[i],o);i++);i===t&&r.push(o)}}return r},difference:Cr,unzip:Hr,transpose:Hr,zip:Qr,object:function(n,r){for(var t={},e=0,u=Y(n);e<u;e++)r?t[n[e]]=r[e]:t[n[e][0]]=n[e][1];return t},range:function(n,r,t){null==r&&(r=n||0,n=0),t||(t=r<n?-1:1);for(var e=Math.max(Math.ceil((r-n)/t),0),u=Array(e),o=0;o<e;o++,n+=t)u[o]=n;return u},chunk:function(n,r){if(null==r||r<1)return[];for(var t=[],e=0,u=n.length;e<u;)t.push(i.call(n,e,e+=r));return t},mixin:Yr,default:tn});return Zr._=Zr,Zr}));
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
20
1 <!DOCTYPE html>
32
4 <html xmlns="http://www.w3.org/1999/xhtml">
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>NBNSProtocol Class &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../_static/jquery.js"></script>
23 <script type="text/javascript" src="../_static/underscore.js"></script>
24 <script type="text/javascript" src="../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../index.html" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>NBNSProtocol Class &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
11 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
12 <script src="../_static/jquery.js"></script>
13 <script src="../_static/underscore.js"></script>
14 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="../_static/doctools.js"></script>
16 <link rel="index" title="Index" href="../genindex.html" />
17 <link rel="search" title="Search" href="../search.html" />
2618 <link rel="next" title="NetBIOS class" href="nmb_NetBIOS.html" />
2719 <link rel="prev" title="Welcome to pysmb’s documentation!" href="../index.html" />
28 </head>
29 <body role="document">
20 </head><body>
3021 <div class="related" role="navigation" aria-label="related navigation">
3122 <h3>Navigation</h3>
3223 <ul>
3425 <a href="../genindex.html" title="General Index"
3526 accesskey="I">index</a></li>
3627 <li class="right" >
28 <a href="../py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
3731 <a href="nmb_NetBIOS.html" title="NetBIOS class"
3832 accesskey="N">next</a> |</li>
3933 <li class="right" >
4034 <a href="../index.html" title="Welcome to pysmb’s documentation!"
4135 accesskey="P">previous</a> |</li>
42 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">NBNSProtocol Class</a></li>
4338 </ul>
44 </div>
45 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
46 <div class="sphinxsidebarwrapper">
47 <h4>Previous topic</h4>
48 <p class="topless"><a href="../index.html"
49 title="previous chapter">Welcome to pysmb&#8217;s documentation!</a></p>
50 <h4>Next topic</h4>
51 <p class="topless"><a href="nmb_NetBIOS.html"
52 title="next chapter">NetBIOS class</a></p>
53 <div role="note" aria-label="source link">
54 <h3>This Page</h3>
55 <ul class="this-page-menu">
56 <li><a href="../_sources/api/nmb_NBNSProtocol.txt"
57 rel="nofollow">Show Source</a></li>
58 </ul>
59 </div>
60 <div id="searchbox" style="display: none" role="search">
61 <h3>Quick search</h3>
62 <form class="search" action="../search.html" method="get">
63 <input type="text" name="q" />
64 <input type="submit" value="Go" />
65 <input type="hidden" name="check_keywords" value="yes" />
66 <input type="hidden" name="area" value="default" />
67 </form>
68 <p class="searchtip" style="font-size: 90%">
69 Enter search terms or a module, class or function name.
70 </p>
71 </div>
72 <script type="text/javascript">$('#searchbox').show(0);</script>
73 </div>
74 </div>
39 </div>
7540
7641 <div class="document">
7742 <div class="documentwrapper">
7843 <div class="bodywrapper">
7944 <div class="body" role="main">
8045
81 <div class="section" id="nbnsprotocol-class">
82 <h1>NBNSProtocol Class<a class="headerlink" href="#nbnsprotocol-class" title="Permalink to this headline">¶</a></h1>
46 <section id="nbnsprotocol-class">
47 <h1>NBNSProtocol Class<a class="headerlink" href="#nbnsprotocol-class" title="Permalink to this heading">¶</a></h1>
8348 <p>pysmb has a <em>NBNSProtocol</em> implementation for Twisted framework.
8449 This allows you to perform name query asynchronously without having your application to block and wait for the results.</p>
85 <dl class="docutils">
86 <dt>In your project,</dt>
87 <dd><ol class="first last arabic simple">
88 <li>Create a NBNSProtocol instance.</li>
89 <li>Just call <em>queryName</em> method which will return a <em>Deferred</em> instance. Add your callback function to the <em>Deferred</em> instance via <em>addCallback</em> method to receive the results of the name query.</li>
90 <li>When you are done with the NBNSProtocol instance, call its &lt;NBNSProtocol instance&gt;.transport.stopListening method to remove this instance from the reactor.</li>
50 <dl class="simple">
51 <dt>In your project,</dt><dd><ol class="arabic simple">
52 <li><p>Create a NBNSProtocol instance.</p></li>
53 <li><p>Just call <em>queryName</em> method which will return a <em>Deferred</em> instance. Add your callback function to the <em>Deferred</em> instance via <em>addCallback</em> method to receive the results of the name query.</p></li>
54 <li><p>When you are done with the NBNSProtocol instance, call its &lt;NBNSProtocol instance&gt;.transport.stopListening method to remove this instance from the reactor.</p></li>
9155 </ol>
9256 </dd>
9357 </dl>
94 <dl class="class">
95 <dt id="nmb.NetBIOSProtocol.NBNSProtocol">
96 <em class="property">class </em><code class="descclassname">nmb.NetBIOSProtocol.</code><code class="descname">NBNSProtocol</code><span class="sig-paren">(</span><em>broadcast=True</em>, <em>listen_port=0</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOSProtocol.html#NBNSProtocol"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOSProtocol.NBNSProtocol" title="Permalink to this definition">¶</a></dt>
97 <dd><dl class="method">
98 <dt id="nmb.NetBIOSProtocol.NBNSProtocol.__init__">
99 <code class="descname">__init__</code><span class="sig-paren">(</span><em>broadcast=True</em>, <em>listen_port=0</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOSProtocol.html#NBNSProtocol.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOSProtocol.NBNSProtocol.__init__" title="Permalink to this definition">¶</a></dt>
100 <dd><p>Instantiate a NBNSProtocol instance.</p>
101 <p>This automatically calls reactor.listenUDP method to start listening for incoming packets, so you <strong>must not</strong> call the listenUDP method again.</p>
102 <table class="docutils field-list" frame="void" rules="none">
103 <col class="field-name" />
104 <col class="field-body" />
105 <tbody valign="top">
106 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
107 <li><strong>broadcast</strong> (<em>boolean</em>) &#8211; A boolean flag to indicate if we should setup the listening UDP port in broadcast mode</li>
108 <li><strong>listen_port</strong> (<em>integer</em>) &#8211; Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number.</li>
109 </ul>
110 </td>
111 </tr>
112 </tbody>
113 </table>
114 </dd></dl>
115
116 <dl class="method">
117 <dt id="nmb.NetBIOSProtocol.NBNSProtocol.queryIPForName">
118 <code class="descname">queryIPForName</code><span class="sig-paren">(</span><em>ip</em>, <em>port=137</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOSProtocol.html#NBNSProtocol.queryIPForName"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOSProtocol.NBNSProtocol.queryIPForName" title="Permalink to this definition">¶</a></dt>
119 <dd><p>Send a query to the machine with <em>ip</em> and hopes that the machine will reply back with its name.</p>
120 <p>The implementation of this function is contributed by Jason Anderson.</p>
121 <table class="docutils field-list" frame="void" rules="none">
122 <col class="field-name" />
123 <col class="field-body" />
124 <tbody valign="top">
125 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
126 <li><strong>ip</strong> (<em>string</em>) &#8211; If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.
127 If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</li>
128 <li><strong>port</strong> (<em>integer</em>) &#8211; The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</li>
129 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds to wait for a reply, after which the method will return None</li>
130 </ul>
131 </td>
132 </tr>
133 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a list of names of the machine at <em>ip</em>.
134 On timeout, the errback function will be called with a Failure instance wrapping around a NetBIOSTimeout exception</p>
135 </td>
136 </tr>
137 </tbody>
138 </table>
139 </dd></dl>
140
141 <dl class="method">
142 <dt id="nmb.NetBIOSProtocol.NBNSProtocol.queryName">
143 <code class="descname">queryName</code><span class="sig-paren">(</span><em>name</em>, <em>ip=''</em>, <em>port=137</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOSProtocol.html#NBNSProtocol.queryName"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOSProtocol.NBNSProtocol.queryName" title="Permalink to this definition">¶</a></dt>
144 <dd><p>Send a query on the network and hopes that if machine matching the <em>name</em> will reply with its IP address.</p>
145 <table class="docutils field-list" frame="void" rules="none">
146 <col class="field-name" />
147 <col class="field-body" />
148 <tbody valign="top">
149 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
150 <li><strong>ip</strong> (<em>string</em>) &#8211; If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.
151 If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</li>
152 <li><strong>port</strong> (<em>integer</em>) &#8211; The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</li>
153 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds to wait for a reply, after which the returned Deferred instance will be called with a NetBIOSTimeout exception.</li>
154 </ul>
155 </td>
156 </tr>
157 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a list of IP addresses in dotted notation (aaa.bbb.ccc.ddd).
158 On timeout, the errback function will be called with a Failure instance wrapping around a NetBIOSTimeout exception</p>
159 </td>
160 </tr>
161 </tbody>
162 </table>
163 </dd></dl>
164
165 </dd></dl>
166
167 <dl class="class">
168 <dt id="nmb.NetBIOSProtocol.NetBIOSTimeout">
169 <em class="property">class </em><code class="descclassname">nmb.NetBIOSProtocol.</code><code class="descname">NetBIOSTimeout</code><a class="reference internal" href="../_modules/nmb/NetBIOSProtocol.html#NetBIOSTimeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOSProtocol.NetBIOSTimeout" title="Permalink to this definition">¶</a></dt>
170 <dd><p>Raised in NBNSProtocol via Deferred.errback method when queryName method has timeout waiting for reply</p>
171 </dd></dl>
172
173 </div>
58 </section>
17459
17560
61 <div class="clearer"></div>
17662 </div>
63 </div>
64 </div>
65 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
66 <div class="sphinxsidebarwrapper">
67 <div>
68 <h4>Previous topic</h4>
69 <p class="topless"><a href="../index.html"
70 title="previous chapter">Welcome to pysmb’s documentation!</a></p>
71 </div>
72 <div>
73 <h4>Next topic</h4>
74 <p class="topless"><a href="nmb_NetBIOS.html"
75 title="next chapter">NetBIOS class</a></p>
76 </div>
77 <div role="note" aria-label="source link">
78 <h3>This Page</h3>
79 <ul class="this-page-menu">
80 <li><a href="../_sources/api/nmb_NBNSProtocol.rst.txt"
81 rel="nofollow">Show Source</a></li>
82 </ul>
83 </div>
84 <div id="searchbox" style="display: none" role="search">
85 <h3 id="searchlabel">Quick search</h3>
86 <div class="searchformwrapper">
87 <form class="search" action="../search.html" method="get">
88 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
89 <input type="submit" value="Go" />
90 </form>
91 </div>
92 </div>
93 <script>document.getElementById('searchbox').style.display = "block"</script>
17794 </div>
17895 </div>
17996 <div class="clearer"></div>
185102 <a href="../genindex.html" title="General Index"
186103 >index</a></li>
187104 <li class="right" >
105 <a href="../py-modindex.html" title="Python Module Index"
106 >modules</a> |</li>
107 <li class="right" >
188108 <a href="nmb_NetBIOS.html" title="NetBIOS class"
189109 >next</a> |</li>
190110 <li class="right" >
191111 <a href="../index.html" title="Welcome to pysmb’s documentation!"
192112 >previous</a> |</li>
193 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
113 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
114 <li class="nav-item nav-item-this"><a href="">NBNSProtocol Class</a></li>
194115 </ul>
195116 </div>
196117 <div class="footer" role="contentinfo">
197 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
198 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
118 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
119 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
199120 </div>
200121 </body>
201122 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
20
1 <!DOCTYPE html>
32
4 <html xmlns="http://www.w3.org/1999/xhtml">
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>NetBIOS class &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../_static/jquery.js"></script>
23 <script type="text/javascript" src="../_static/underscore.js"></script>
24 <script type="text/javascript" src="../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../index.html" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>NetBIOS class &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
11 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
12 <script src="../_static/jquery.js"></script>
13 <script src="../_static/underscore.js"></script>
14 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="../_static/doctools.js"></script>
16 <link rel="index" title="Index" href="../genindex.html" />
17 <link rel="search" title="Search" href="../search.html" />
2618 <link rel="next" title="SMBConnection Class" href="smb_SMBConnection.html" />
2719 <link rel="prev" title="NBNSProtocol Class" href="nmb_NBNSProtocol.html" />
28 </head>
29 <body role="document">
20 </head><body>
3021 <div class="related" role="navigation" aria-label="related navigation">
3122 <h3>Navigation</h3>
3223 <ul>
3425 <a href="../genindex.html" title="General Index"
3526 accesskey="I">index</a></li>
3627 <li class="right" >
28 <a href="../py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
3731 <a href="smb_SMBConnection.html" title="SMBConnection Class"
3832 accesskey="N">next</a> |</li>
3933 <li class="right" >
4034 <a href="nmb_NBNSProtocol.html" title="NBNSProtocol Class"
4135 accesskey="P">previous</a> |</li>
42 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">NetBIOS class</a></li>
4338 </ul>
44 </div>
45 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
46 <div class="sphinxsidebarwrapper">
47 <h4>Previous topic</h4>
48 <p class="topless"><a href="nmb_NBNSProtocol.html"
49 title="previous chapter">NBNSProtocol Class</a></p>
50 <h4>Next topic</h4>
51 <p class="topless"><a href="smb_SMBConnection.html"
52 title="next chapter">SMBConnection Class</a></p>
53 <div role="note" aria-label="source link">
54 <h3>This Page</h3>
55 <ul class="this-page-menu">
56 <li><a href="../_sources/api/nmb_NetBIOS.txt"
57 rel="nofollow">Show Source</a></li>
58 </ul>
59 </div>
60 <div id="searchbox" style="display: none" role="search">
61 <h3>Quick search</h3>
62 <form class="search" action="../search.html" method="get">
63 <input type="text" name="q" />
64 <input type="submit" value="Go" />
65 <input type="hidden" name="check_keywords" value="yes" />
66 <input type="hidden" name="area" value="default" />
67 </form>
68 <p class="searchtip" style="font-size: 90%">
69 Enter search terms or a module, class or function name.
70 </p>
71 </div>
72 <script type="text/javascript">$('#searchbox').show(0);</script>
73 </div>
74 </div>
39 </div>
7540
7641 <div class="document">
7742 <div class="documentwrapper">
7843 <div class="bodywrapper">
7944 <div class="body" role="main">
8045
81 <div class="section" id="netbios-class">
82 <h1>NetBIOS class<a class="headerlink" href="#netbios-class" title="Permalink to this headline">¶</a></h1>
83 <dl class="docutils">
84 <dt>To use the NetBIOS class in your application,</dt>
85 <dd><ol class="first last arabic simple">
86 <li>Create a new NetBIOS instance</li>
87 <li>Call <em>queryName</em> method for each name you wish to query. The method will block until a reply is received from the remote SMB/CIFS service, or until timeout.</li>
88 <li>When you are done, call <em>close</em> method to release the underlying resources.</li>
46 <section id="netbios-class">
47 <h1>NetBIOS class<a class="headerlink" href="#netbios-class" title="Permalink to this heading">¶</a></h1>
48 <dl class="simple">
49 <dt>To use the NetBIOS class in your application,</dt><dd><ol class="arabic simple">
50 <li><p>Create a new NetBIOS instance</p></li>
51 <li><p>Call <em>queryName</em> method for each name you wish to query. The method will block until a reply is received from the remote SMB/CIFS service, or until timeout.</p></li>
52 <li><p>When you are done, call <em>close</em> method to release the underlying resources.</p></li>
8953 </ol>
9054 </dd>
9155 </dl>
92 <dl class="class">
93 <dt id="nmb.NetBIOS.NetBIOS">
94 <em class="property">class </em><code class="descclassname">nmb.NetBIOS.</code><code class="descname">NetBIOS</code><span class="sig-paren">(</span><em>broadcast=True</em>, <em>listen_port=0</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS" title="Permalink to this definition">¶</a></dt>
95 <dd><dl class="method">
96 <dt id="nmb.NetBIOS.NetBIOS.__init__">
97 <code class="descname">__init__</code><span class="sig-paren">(</span><em>broadcast=True</em>, <em>listen_port=0</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.__init__" title="Permalink to this definition">¶</a></dt>
56 <dl class="py class">
57 <dt class="sig sig-object py" id="nmb.NetBIOS.NetBIOS">
58 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">nmb.NetBIOS.</span></span><span class="sig-name descname"><span class="pre">NetBIOS</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">broadcast</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">listen_port</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS" title="Permalink to this definition">¶</a></dt>
59 <dd><dl class="py method">
60 <dt class="sig sig-object py" id="nmb.NetBIOS.NetBIOS.__init__">
61 <span class="sig-name descname"><span class="pre">__init__</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">broadcast</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">listen_port</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.__init__"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.__init__" title="Permalink to this definition">¶</a></dt>
9862 <dd><p>Instantiate a NetBIOS instance, and creates a IPv4 UDP socket to listen/send NBNS packets.</p>
99 <table class="docutils field-list" frame="void" rules="none">
100 <col class="field-name" />
101 <col class="field-body" />
102 <tbody valign="top">
103 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
104 <li><strong>broadcast</strong> (<em>boolean</em>) &#8211; A boolean flag to indicate if we should setup the listening UDP port in broadcast mode</li>
105 <li><strong>listen_port</strong> (<em>integer</em>) &#8211; Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number.</li>
63 <dl class="field-list simple">
64 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
65 <dd class="field-odd"><ul class="simple">
66 <li><p><strong>broadcast</strong> (<em>boolean</em>) – A boolean flag to indicate if we should setup the listening UDP port in broadcast mode</p></li>
67 <li><p><strong>listen_port</strong> (<em>integer</em>) – Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number.</p></li>
10668 </ul>
107 </td>
108 </tr>
109 </tbody>
110 </table>
69 </dd>
70 </dl>
11171 </dd></dl>
11272
113 <dl class="method">
114 <dt id="nmb.NetBIOS.NetBIOS.close">
115 <code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.close" title="Permalink to this definition">¶</a></dt>
73 <dl class="py method">
74 <dt class="sig sig-object py" id="nmb.NetBIOS.NetBIOS.close">
75 <span class="sig-name descname"><span class="pre">close</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.close"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.close" title="Permalink to this definition">¶</a></dt>
11676 <dd><p>Close the underlying and free resources.</p>
11777 <p>The NetBIOS instance should not be used to perform any operations after this method returns.</p>
118 <table class="docutils field-list" frame="void" rules="none">
119 <col class="field-name" />
120 <col class="field-body" />
121 <tbody valign="top">
122 <tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">None</td>
123 </tr>
124 </tbody>
125 </table>
78 <dl class="field-list simple">
79 <dt class="field-odd">Returns<span class="colon">:</span></dt>
80 <dd class="field-odd"><p>None</p>
81 </dd>
82 </dl>
12683 </dd></dl>
12784
128 <dl class="method">
129 <dt id="nmb.NetBIOS.NetBIOS.queryIPForName">
130 <code class="descname">queryIPForName</code><span class="sig-paren">(</span><em>ip</em>, <em>port=137</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.queryIPForName"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.queryIPForName" title="Permalink to this definition">¶</a></dt>
85 <dl class="py method">
86 <dt class="sig sig-object py" id="nmb.NetBIOS.NetBIOS.queryIPForName">
87 <span class="sig-name descname"><span class="pre">queryIPForName</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">ip</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">port</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">137</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.queryIPForName"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.queryIPForName" title="Permalink to this definition">¶</a></dt>
13188 <dd><p>Send a query to the machine with <em>ip</em> and hopes that the machine will reply back with its name.</p>
13289 <p>The implementation of this function is contributed by Jason Anderson.</p>
133 <table class="docutils field-list" frame="void" rules="none">
134 <col class="field-name" />
135 <col class="field-body" />
136 <tbody valign="top">
137 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
138 <li><strong>ip</strong> (<em>string</em>) &#8211; If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.
139 If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</li>
140 <li><strong>port</strong> (<em>integer</em>) &#8211; The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</li>
141 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds to wait for a reply, after which the method will return None</li>
90 <dl class="field-list simple">
91 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
92 <dd class="field-odd"><ul class="simple">
93 <li><p><strong>ip</strong> (<em>string</em>) – If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.
94 If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</p></li>
95 <li><p><strong>port</strong> (<em>integer</em>) – The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</p></li>
96 <li><p><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds to wait for a reply, after which the method will return None</p></li>
14297 </ul>
143 </td>
144 </tr>
145 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A list of string containing the names of the machine at <em>ip</em>. On timeout, returns None.</p>
146 </td>
147 </tr>
148 </tbody>
149 </table>
98 </dd>
99 <dt class="field-even">Returns<span class="colon">:</span></dt>
100 <dd class="field-even"><p>A list of string containing the names of the machine at <em>ip</em>. On timeout, returns None.</p>
101 </dd>
102 </dl>
150103 </dd></dl>
151104
152 <dl class="method">
153 <dt id="nmb.NetBIOS.NetBIOS.queryName">
154 <code class="descname">queryName</code><span class="sig-paren">(</span><em>name</em>, <em>ip=''</em>, <em>port=137</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.queryName"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.queryName" title="Permalink to this definition">¶</a></dt>
105 <dl class="py method">
106 <dt class="sig sig-object py" id="nmb.NetBIOS.NetBIOS.queryName">
107 <span class="sig-name descname"><span class="pre">queryName</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">ip</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">''</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">port</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">137</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.queryName"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.queryName" title="Permalink to this definition">¶</a></dt>
155108 <dd><p>Send a query on the network and hopes that if machine matching the <em>name</em> will reply with its IP address.</p>
156 <table class="docutils field-list" frame="void" rules="none">
157 <col class="field-name" />
158 <col class="field-body" />
159 <tbody valign="top">
160 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
161 <li><strong>ip</strong> (<em>string</em>) &#8211; If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.
162 If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</li>
163 <li><strong>port</strong> (<em>integer</em>) &#8211; The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</li>
164 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds to wait for a reply, after which the method will return None</li>
109 <dl class="field-list simple">
110 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
111 <dd class="field-odd"><ul class="simple">
112 <li><p><strong>ip</strong> (<em>string</em>) – If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.
113 If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</p></li>
114 <li><p><strong>port</strong> (<em>integer</em>) – The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</p></li>
115 <li><p><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds to wait for a reply, after which the method will return None</p></li>
165116 </ul>
166 </td>
167 </tr>
168 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A list of IP addresses in dotted notation (aaa.bbb.ccc.ddd). On timeout, returns None.</p>
169 </td>
170 </tr>
171 </tbody>
172 </table>
117 </dd>
118 <dt class="field-even">Returns<span class="colon">:</span></dt>
119 <dd class="field-even"><p>A list of IP addresses in dotted notation (aaa.bbb.ccc.ddd). On timeout, returns None.</p>
120 </dd>
121 </dl>
173122 </dd></dl>
174123
175124 </dd></dl>
176125
177 </div>
126 </section>
178127
179128
129 <div class="clearer"></div>
180130 </div>
131 </div>
132 </div>
133 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
134 <div class="sphinxsidebarwrapper">
135 <div>
136 <h4>Previous topic</h4>
137 <p class="topless"><a href="nmb_NBNSProtocol.html"
138 title="previous chapter">NBNSProtocol Class</a></p>
139 </div>
140 <div>
141 <h4>Next topic</h4>
142 <p class="topless"><a href="smb_SMBConnection.html"
143 title="next chapter">SMBConnection Class</a></p>
144 </div>
145 <div role="note" aria-label="source link">
146 <h3>This Page</h3>
147 <ul class="this-page-menu">
148 <li><a href="../_sources/api/nmb_NetBIOS.rst.txt"
149 rel="nofollow">Show Source</a></li>
150 </ul>
151 </div>
152 <div id="searchbox" style="display: none" role="search">
153 <h3 id="searchlabel">Quick search</h3>
154 <div class="searchformwrapper">
155 <form class="search" action="../search.html" method="get">
156 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
157 <input type="submit" value="Go" />
158 </form>
159 </div>
160 </div>
161 <script>document.getElementById('searchbox').style.display = "block"</script>
181162 </div>
182163 </div>
183164 <div class="clearer"></div>
189170 <a href="../genindex.html" title="General Index"
190171 >index</a></li>
191172 <li class="right" >
173 <a href="../py-modindex.html" title="Python Module Index"
174 >modules</a> |</li>
175 <li class="right" >
192176 <a href="smb_SMBConnection.html" title="SMBConnection Class"
193177 >next</a> |</li>
194178 <li class="right" >
195179 <a href="nmb_NBNSProtocol.html" title="NBNSProtocol Class"
196180 >previous</a> |</li>
197 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
181 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
182 <li class="nav-item nav-item-this"><a href="">NetBIOS class</a></li>
198183 </ul>
199184 </div>
200185 <div class="footer" role="contentinfo">
201 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
202 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
186 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
187 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
203188 </div>
204189 </body>
205190 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>SMBConnection Class &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../_static/jquery.js"></script>
23 <script type="text/javascript" src="../_static/underscore.js"></script>
24 <script type="text/javascript" src="../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../index.html" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>SMBConnection Class &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
11 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
12 <script src="../_static/jquery.js"></script>
13 <script src="../_static/underscore.js"></script>
14 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="../_static/doctools.js"></script>
16 <link rel="index" title="Index" href="../genindex.html" />
17 <link rel="search" title="Search" href="../search.html" />
2618 <link rel="next" title="SMbHandler Class" href="smb_SMBHandler.html" />
2719 <link rel="prev" title="NetBIOS class" href="nmb_NetBIOS.html" />
28 </head>
29 <body role="document">
20 </head><body>
3021 <div class="related" role="navigation" aria-label="related navigation">
3122 <h3>Navigation</h3>
3223 <ul>
3425 <a href="../genindex.html" title="General Index"
3526 accesskey="I">index</a></li>
3627 <li class="right" >
28 <a href="../py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
3731 <a href="smb_SMBHandler.html" title="SMbHandler Class"
3832 accesskey="N">next</a> |</li>
3933 <li class="right" >
4034 <a href="nmb_NetBIOS.html" title="NetBIOS class"
4135 accesskey="P">previous</a> |</li>
42 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">SMBConnection Class</a></li>
4338 </ul>
44 </div>
45 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
46 <div class="sphinxsidebarwrapper">
47 <h3><a href="../index.html">Table Of Contents</a></h3>
48 <ul>
49 <li><a class="reference internal" href="#">SMBConnection Class</a><ul>
50 <li><a class="reference internal" href="#example">Example</a></li>
51 <li><a class="reference internal" href="#smb2-support">SMB2 Support</a></li>
52 <li><a class="reference internal" href="#caveats">Caveats</a></li>
53 </ul>
54 </li>
55 </ul>
56
57 <h4>Previous topic</h4>
58 <p class="topless"><a href="nmb_NetBIOS.html"
59 title="previous chapter">NetBIOS class</a></p>
60 <h4>Next topic</h4>
61 <p class="topless"><a href="smb_SMBHandler.html"
62 title="next chapter">SMbHandler Class</a></p>
63 <div role="note" aria-label="source link">
64 <h3>This Page</h3>
65 <ul class="this-page-menu">
66 <li><a href="../_sources/api/smb_SMBConnection.txt"
67 rel="nofollow">Show Source</a></li>
68 </ul>
69 </div>
70 <div id="searchbox" style="display: none" role="search">
71 <h3>Quick search</h3>
72 <form class="search" action="../search.html" method="get">
73 <input type="text" name="q" />
74 <input type="submit" value="Go" />
75 <input type="hidden" name="check_keywords" value="yes" />
76 <input type="hidden" name="area" value="default" />
77 </form>
78 <p class="searchtip" style="font-size: 90%">
79 Enter search terms or a module, class or function name.
80 </p>
81 </div>
82 <script type="text/javascript">$('#searchbox').show(0);</script>
83 </div>
84 </div>
39 </div>
8540
8641 <div class="document">
8742 <div class="documentwrapper">
8843 <div class="bodywrapper">
8944 <div class="body" role="main">
9045
91 <div class="section" id="smbconnection-class">
92 <h1>SMBConnection Class<a class="headerlink" href="#smbconnection-class" title="Permalink to this headline">¶</a></h1>
46 <section id="smbconnection-class">
47 <h1>SMBConnection Class<a class="headerlink" href="#smbconnection-class" title="Permalink to this heading">¶</a></h1>
9348 <p>The SMBConnection is suitable for developers who wish to use pysmb to perform file operations with a remote SMB/CIFS server sequentially.</p>
9449 <p>Each file operation method, when invoked, will block and return after it has completed or has encountered an error.</p>
95 <div class="section" id="example">
96 <h2>Example<a class="headerlink" href="#example" title="Permalink to this headline">¶</a></h2>
50 <section id="example">
51 <h2>Example<a class="headerlink" href="#example" title="Permalink to this heading">¶</a></h2>
9752 <p>The following illustrates a simple file retrieving implementation.:</p>
98 <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">tempfile</span>
53 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">tempfile</span>
9954 <span class="kn">from</span> <span class="nn">smb.SMBConnection</span> <span class="kn">import</span> <span class="n">SMBConnection</span>
10055
10156 <span class="c1"># There will be some mechanism to capture userID, password, client_machine_name, server_name and server_ip</span>
10257 <span class="c1"># client_machine_name can be an arbitary ASCII string</span>
10358 <span class="c1"># server_name should match the remote machine name, or else the connection will be rejected</span>
104 <span class="n">conn</span> <span class="o">=</span> <span class="n">SMBConnection</span><span class="p">(</span><span class="n">userID</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">client_machine_name</span><span class="p">,</span> <span class="n">server_name</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
59 <span class="n">conn</span> <span class="o">=</span> <span class="n">SMBConnection</span><span class="p">(</span><span class="n">userID</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">client_machine_name</span><span class="p">,</span> <span class="n">server_name</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span>
10560 <span class="k">assert</span> <span class="n">conn</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">server_ip</span><span class="p">,</span> <span class="mi">139</span><span class="p">)</span>
10661
10762 <span class="n">file_obj</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">NamedTemporaryFile</span><span class="p">()</span>
11570 <span class="n">file_obj</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
11671 </pre></div>
11772 </div>
118 </div>
119 <div class="section" id="smb2-support">
120 <h2>SMB2 Support<a class="headerlink" href="#smb2-support" title="Permalink to this headline">¶</a></h2>
73 </section>
74 <section id="smb2-support">
75 <h2>SMB2 Support<a class="headerlink" href="#smb2-support" title="Permalink to this heading">¶</a></h2>
12176 <p>Starting from pysmb 1.1.0, pysmb will utilize SMB2 protocol for communication if the remote SMB/CIFS service supports SMB2.
12277 Otherwise, it will fallback automatically back to using SMB1 protocol.</p>
12378 <p>To disable SMB2 protocol in pysmb, set the <em>SUPPORT_SMB2</em> flag in the <em>smb_structs</em> module to <em>False</em> before creating the <em>SMBConnection</em> instance.:</p>
124 <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">smb</span> <span class="kn">import</span> <span class="n">smb_structs</span>
125 <span class="n">smb_structs</span><span class="o">.</span><span class="n">SUPPORT_SMB2</span> <span class="o">=</span> <span class="bp">False</span>
79 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">smb</span> <span class="kn">import</span> <span class="n">smb_structs</span>
80 <span class="n">smb_structs</span><span class="o">.</span><span class="n">SUPPORT_SMB2</span> <span class="o">=</span> <span class="kc">False</span>
12681 </pre></div>
12782 </div>
128 </div>
129 <div class="section" id="caveats">
130 <h2>Caveats<a class="headerlink" href="#caveats" title="Permalink to this headline">¶</a></h2>
83 </section>
84 <section id="caveats">
85 <h2>Caveats<a class="headerlink" href="#caveats" title="Permalink to this heading">¶</a></h2>
13186 <ul class="simple">
132 <li>It is not meant to be used asynchronously.</li>
133 <li>A single <em>SMBConnection</em> instance should not be used to perform more than one operation concurrently at the same time.</li>
134 <li>Do not keep a <em>SMBConnection</em> instance &#8220;idle&#8221; for too long, i.e. keeping a <em>SMBConnection</em> instance but not using it.
87 <li><p>It is not meant to be used asynchronously.</p></li>
88 <li><p>A single <em>SMBConnection</em> instance should not be used to perform more than one operation concurrently at the same time.</p></li>
89 <li><p>Do not keep a <em>SMBConnection</em> instance “idle” for too long, i.e. keeping a <em>SMBConnection</em> instance but not using it.
13590 Most SMB/CIFS servers have some sort of keepalive mechanism and impose a timeout limit.
136 If the clients fail to respond within the timeout limit, the SMB/CIFS server may disconnect the client.</li>
137 </ul>
138 <dl class="class">
139 <dt id="smb.SMBConnection.SMBConnection">
140 <em class="property">class </em><code class="descclassname">smb.SMBConnection.</code><code class="descname">SMBConnection</code><span class="sig-paren">(</span><em>username</em>, <em>password</em>, <em>my_name</em>, <em>remote_name</em>, <em>domain=''</em>, <em>use_ntlm_v2=True</em>, <em>sign_options=2</em>, <em>is_direct_tcp=False</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection" title="Permalink to this definition">¶</a></dt>
141 <dd><dl class="method">
142 <dt id="smb.SMBConnection.SMBConnection.__init__">
143 <code class="descname">__init__</code><span class="sig-paren">(</span><em>username</em>, <em>password</em>, <em>my_name</em>, <em>remote_name</em>, <em>domain=''</em>, <em>use_ntlm_v2=True</em>, <em>sign_options=2</em>, <em>is_direct_tcp=False</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.__init__" title="Permalink to this definition">¶</a></dt>
91 If the clients fail to respond within the timeout limit, the SMB/CIFS server may disconnect the client.</p></li>
92 </ul>
93 <dl class="py class">
94 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection">
95 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.SMBConnection.</span></span><span class="sig-name descname"><span class="pre">SMBConnection</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">username</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">password</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">my_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">remote_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">domain</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">''</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">use_ntlm_v2</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sign_options</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">2</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">is_direct_tcp</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection" title="Permalink to this definition">¶</a></dt>
96 <dd><dl class="py method">
97 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.__init__">
98 <span class="sig-name descname"><span class="pre">__init__</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">username</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">password</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">my_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">remote_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">domain</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">''</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">use_ntlm_v2</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sign_options</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">2</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">is_direct_tcp</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.__init__"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.__init__" title="Permalink to this definition">¶</a></dt>
14499 <dd><p>Create a new SMBConnection instance.</p>
145100 <p><em>username</em> and <em>password</em> are the user credentials required to authenticate the underlying SMB connection with the remote server.
101 <em>password</em> can be a string or a callable returning a string.
146102 File operations can only be proceeded after the connection has been authenticated successfully.</p>
147103 <p>Note that you need to call <em>connect</em> method to actually establish the SMB connection to the remote server and perform authentication.</p>
148104 <p>The default TCP port for most SMB/CIFS servers using NetBIOS over TCP/IP is 139.
149105 Some newer server installations might also support Direct hosting of SMB over TCP/IP; for these servers, the default TCP port is 445.</p>
150 <table class="docutils field-list" frame="void" rules="none">
151 <col class="field-name" />
152 <col class="field-body" />
153 <tbody valign="top">
154 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
155 <li><strong>my_name</strong> (<em>string</em>) &#8211; The local NetBIOS machine name that will identify where this connection is originating from.
156 You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of <code class="docutils literal"><span class="pre">\/:*?&quot;;|+</span></code></li>
157 <li><strong>remote_name</strong> (<em>string</em>) &#8211; The NetBIOS machine name of the remote server.
158 On windows, you can find out the machine name by right-clicking on the &#8220;My Computer&#8221; and selecting &#8220;Properties&#8221;.
159 This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.</li>
160 <li><strong>domain</strong> (<em>string</em>) &#8211; The network domain. On windows, it is known as the workgroup. Usually, it is safe to leave this parameter as an empty string.</li>
161 <li><strong>use_ntlm_v2</strong> (<em>boolean</em>) &#8211; Indicates whether pysmb should be NTLMv1 or NTLMv2 authentication algorithm for authentication.
106 <dl class="field-list simple">
107 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
108 <dd class="field-odd"><ul class="simple">
109 <li><p><strong>my_name</strong> (<em>string</em>) – The local NetBIOS machine name that will identify where this connection is originating from.
110 You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of <code class="docutils literal notranslate"><span class="pre">\/:*?&quot;;|+</span></code></p></li>
111 <li><p><strong>remote_name</strong> (<em>string</em>) – The NetBIOS machine name of the remote server.
112 On windows, you can find out the machine name by right-clicking on the “My Computer” and selecting “Properties”.
113 This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.</p></li>
114 <li><p><strong>domain</strong> (<em>string</em>) – The network domain. On windows, it is known as the workgroup. Usually, it is safe to leave this parameter as an empty string.</p></li>
115 <li><p><strong>use_ntlm_v2</strong> (<em>boolean</em>) – Indicates whether pysmb should be NTLMv1 or NTLMv2 authentication algorithm for authentication.
162116 The choice of NTLMv1 and NTLMv2 is configured on the remote server, and there is no mechanism to auto-detect which algorithm has been configured.
163 Hence, we can only &#8220;guess&#8221; or try both algorithms.
164 On Sambda, Windows Vista and Windows 7, NTLMv2 is enabled by default. On Windows XP, we can use NTLMv1 before NTLMv2.</li>
165 <li><strong>sign_options</strong> (<em>int</em>) &#8211; Determines whether SMB messages will be signed. Default is <em>SIGN_WHEN_REQUIRED</em>.
117 Hence, we can only “guess” or try both algorithms.
118 On Sambda, Windows Vista and Windows 7, NTLMv2 is enabled by default. On Windows XP, we can use NTLMv1 before NTLMv2.</p></li>
119 <li><p><strong>sign_options</strong> (<em>int</em>) – Determines whether SMB messages will be signed. Default is <em>SIGN_WHEN_REQUIRED</em>.
166120 If <em>SIGN_WHEN_REQUIRED</em> (value=2), SMB messages will only be signed when remote server requires signing.
167121 If <em>SIGN_WHEN_SUPPORTED</em> (value=1), SMB messages will be signed when remote server supports signing but not requires signing.
168 If <em>SIGN_NEVER</em> (value=0), SMB messages will never be signed regardless of remote server&#8217;s configurations; access errors will occur if the remote server requires signing.</li>
169 <li><strong>is_direct_tcp</strong> (<em>boolean</em>) &#8211; Controls whether the NetBIOS over TCP/IP (is_direct_tcp=False) or the newer Direct hosting of SMB over TCP/IP (is_direct_tcp=True) will be used for the communication.
170 The default parameter is False which will use NetBIOS over TCP/IP for wider compatibility (TCP port: 139).</li>
171 </ul>
172 </td>
173 </tr>
174 </tbody>
175 </table>
176 </dd></dl>
177
178 <dl class="method">
179 <dt id="smb.SMBConnection.SMBConnection.close">
180 <code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.close" title="Permalink to this definition">¶</a></dt>
122 If <em>SIGN_NEVER</em> (value=0), SMB messages will never be signed regardless of remote server’s configurations; access errors will occur if the remote server requires signing.</p></li>
123 <li><p><strong>is_direct_tcp</strong> (<em>boolean</em>) – Controls whether the NetBIOS over TCP/IP (is_direct_tcp=False) or the newer Direct hosting of SMB over TCP/IP (is_direct_tcp=True) will be used for the communication.
124 The default parameter is False which will use NetBIOS over TCP/IP for wider compatibility (TCP port: 139).</p></li>
125 </ul>
126 </dd>
127 </dl>
128 </dd></dl>
129
130 <dl class="py method">
131 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.close">
132 <span class="sig-name descname"><span class="pre">close</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.close"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.close" title="Permalink to this definition">¶</a></dt>
181133 <dd><p>Terminate the SMB connection (if it has been started) and release any sources held by the underlying socket.</p>
182134 </dd></dl>
183135
184 <dl class="method">
185 <dt id="smb.SMBConnection.SMBConnection.connect">
186 <code class="descname">connect</code><span class="sig-paren">(</span><em>ip</em>, <em>port=139</em>, <em>sock_family=2</em>, <em>timeout=60</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.connect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.connect" title="Permalink to this definition">¶</a></dt>
136 <dl class="py method">
137 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.connect">
138 <span class="sig-name descname"><span class="pre">connect</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">ip</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">port</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">139</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sock_family</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">60</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.connect"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.connect" title="Permalink to this definition">¶</a></dt>
187139 <dd><p>Establish the SMB connection to the remote SMB/CIFS server.</p>
188140 <p>You must call this method before attempting any of the file operations with the remote server.
189141 This method will block until the SMB connection has attempted at least one authentication.</p>
190 <table class="docutils field-list" frame="void" rules="none">
191 <col class="field-name" />
192 <col class="field-body" />
193 <tbody valign="top">
194 <tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">A boolean value indicating the result of the authentication atttempt: True if authentication is successful; False, if otherwise.</td>
195 </tr>
196 </tbody>
197 </table>
198 </dd></dl>
199
200 <dl class="method">
201 <dt id="smb.SMBConnection.SMBConnection.createDirectory">
202 <code class="descname">createDirectory</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.createDirectory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.createDirectory" title="Permalink to this definition">¶</a></dt>
142 <dl class="field-list simple">
143 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
144 <dd class="field-odd"><ul class="simple">
145 <li><p><strong>port</strong> – Defaults to 139. If you are using direct TCP mode (is_direct_tcp=true when creating this SMBConnection instance), use 445.</p></li>
146 <li><p><strong>sock_family</strong> – In Python 3.x, use <em>None</em> as we can infer the socket family from the provided <em>ip</em>. In Python 2.x, it must be either <em>socket.AF_INET</em> or <em>socket.AF_INET6</em>.</p></li>
147 </ul>
148 </dd>
149 <dt class="field-even">Returns<span class="colon">:</span></dt>
150 <dd class="field-even"><p>A boolean value indicating the result of the authentication atttempt: True if authentication is successful; False, if otherwise.</p>
151 </dd>
152 </dl>
153 </dd></dl>
154
155 <dl class="py method">
156 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.createDirectory">
157 <span class="sig-name descname"><span class="pre">createDirectory</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.createDirectory"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.createDirectory" title="Permalink to this definition">¶</a></dt>
203158 <dd><p>Creates a new directory <em>path</em> on the <em>service_name</em>.</p>
204 <table class="docutils field-list" frame="void" rules="none">
205 <col class="field-name" />
206 <col class="field-body" />
207 <tbody valign="top">
208 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
209 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; Contains the name of the shared folder.</li>
210 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; The path of the new folder (relative to) the shared folder.
211 If the path contains non-English characters, an unicode string must be used to pass in the path.</li>
212 </ul>
213 </td>
214 </tr>
215 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">None</p>
216 </td>
217 </tr>
218 </tbody>
219 </table>
220 </dd></dl>
221
222 <dl class="method">
223 <dt id="smb.SMBConnection.SMBConnection.deleteDirectory">
224 <code class="descname">deleteDirectory</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.deleteDirectory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.deleteDirectory" title="Permalink to this definition">¶</a></dt>
159 <dl class="field-list simple">
160 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
161 <dd class="field-odd"><ul class="simple">
162 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</p></li>
163 <li><p><strong>path</strong> (<em>string/unicode</em>) – The path of the new folder (relative to) the shared folder.
164 If the path contains non-English characters, an unicode string must be used to pass in the path.</p></li>
165 </ul>
166 </dd>
167 <dt class="field-even">Returns<span class="colon">:</span></dt>
168 <dd class="field-even"><p>None</p>
169 </dd>
170 </dl>
171 </dd></dl>
172
173 <dl class="py method">
174 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.deleteDirectory">
175 <span class="sig-name descname"><span class="pre">deleteDirectory</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.deleteDirectory"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.deleteDirectory" title="Permalink to this definition">¶</a></dt>
225176 <dd><p>Delete the empty folder at <em>path</em> on <em>service_name</em></p>
226 <table class="docutils field-list" frame="void" rules="none">
227 <col class="field-name" />
228 <col class="field-body" />
229 <tbody valign="top">
230 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
231 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; Contains the name of the shared folder.</li>
232 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; The path of the to-be-deleted folder (relative to) the shared folder.
233 If the path contains non-English characters, an unicode string must be used to pass in the path.</li>
234 </ul>
235 </td>
236 </tr>
237 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">None</p>
238 </td>
239 </tr>
240 </tbody>
241 </table>
242 </dd></dl>
243
244 <dl class="method">
245 <dt id="smb.SMBConnection.SMBConnection.deleteFiles">
246 <code class="descname">deleteFiles</code><span class="sig-paren">(</span><em>service_name</em>, <em>path_file_pattern</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.deleteFiles"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.deleteFiles" title="Permalink to this definition">¶</a></dt>
177 <dl class="field-list simple">
178 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
179 <dd class="field-odd"><ul class="simple">
180 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</p></li>
181 <li><p><strong>path</strong> (<em>string/unicode</em>) – The path of the to-be-deleted folder (relative to) the shared folder.
182 If the path contains non-English characters, an unicode string must be used to pass in the path.</p></li>
183 </ul>
184 </dd>
185 <dt class="field-even">Returns<span class="colon">:</span></dt>
186 <dd class="field-even"><p>None</p>
187 </dd>
188 </dl>
189 </dd></dl>
190
191 <dl class="py method">
192 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.deleteFiles">
193 <span class="sig-name descname"><span class="pre">deleteFiles</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path_file_pattern</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">delete_matching_folders</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.deleteFiles"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.deleteFiles" title="Permalink to this definition">¶</a></dt>
247194 <dd><p>Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.</p>
248 <table class="docutils field-list" frame="void" rules="none">
249 <col class="field-name" />
250 <col class="field-body" />
251 <tbody valign="top">
252 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
253 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; Contains the name of the shared folder.</li>
254 <li><strong>path_file_pattern</strong> (<em>string/unicode</em>) &#8211; The pathname of the file(s) to be deleted, relative to the service_name.
195 <p>If delete_matching_folders is True, immediate sub-folders that match the path_file_pattern will be deleted recursively.</p>
196 <dl class="field-list simple">
197 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
198 <dd class="field-odd"><ul class="simple">
199 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</p></li>
200 <li><p><strong>path_file_pattern</strong> (<em>string/unicode</em>) – The pathname of the file(s) to be deleted, relative to the service_name.
255201 Wildcards may be used in th filename component of the path.
256 If your path/filename contains non-English characters, you must pass in an unicode string.</li>
257 </ul>
258 </td>
259 </tr>
260 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">None</p>
261 </td>
262 </tr>
263 </tbody>
264 </table>
265 </dd></dl>
266
267 <dl class="method">
268 <dt id="smb.SMBConnection.SMBConnection.echo">
269 <code class="descname">echo</code><span class="sig-paren">(</span><em>data</em>, <em>timeout=10</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.echo"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.echo" title="Permalink to this definition">¶</a></dt>
202 If your path/filename contains non-English characters, you must pass in an unicode string.</p></li>
203 </ul>
204 </dd>
205 <dt class="field-even">Returns<span class="colon">:</span></dt>
206 <dd class="field-even"><p>None</p>
207 </dd>
208 </dl>
209 </dd></dl>
210
211 <dl class="py method">
212 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.echo">
213 <span class="sig-name descname"><span class="pre">echo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">10</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.echo"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.echo" title="Permalink to this definition">¶</a></dt>
270214 <dd><p>Send an echo command containing <em>data</em> to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same <em>data</em>.</p>
271 <table class="docutils field-list" frame="void" rules="none">
272 <col class="field-name" />
273 <col class="field-body" />
274 <tbody valign="top">
275 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>data</strong> (<em>string</em>) &#8211; Data to send to the remote server.</td>
276 </tr>
277 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">The <em>data</em> parameter</td>
278 </tr>
279 </tbody>
280 </table>
281 </dd></dl>
282
283 <dl class="method">
284 <dt id="smb.SMBConnection.SMBConnection.getAttributes">
285 <code class="descname">getAttributes</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.getAttributes"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.getAttributes" title="Permalink to this definition">¶</a></dt>
215 <dl class="field-list simple">
216 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
217 <dd class="field-odd"><p><strong>data</strong> (<em>bytes</em>) – Data to send to the remote server. Must be a bytes object.</p>
218 </dd>
219 <dt class="field-even">Returns<span class="colon">:</span></dt>
220 <dd class="field-even"><p>The <em>data</em> parameter</p>
221 </dd>
222 </dl>
223 </dd></dl>
224
225 <dl class="py method">
226 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.getAttributes">
227 <span class="sig-name descname"><span class="pre">getAttributes</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.getAttributes"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.getAttributes" title="Permalink to this definition">¶</a></dt>
286228 <dd><p>Retrieve information about the file at <em>path</em> on the <em>service_name</em>.</p>
287 <table class="docutils field-list" frame="void" rules="none">
288 <col class="field-name" />
289 <col class="field-body" />
290 <tbody valign="top">
291 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
292 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
293 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be raised.</li>
294 </ul>
295 </td>
296 </tr>
297 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <a class="reference internal" href="smb_SharedFile.html"><em>smb.base.SharedFile</em></a> instance containing the attributes of the file.</p>
298 </td>
299 </tr>
300 </tbody>
301 </table>
302 </dd></dl>
303
304 <dl class="method">
305 <dt id="smb.SMBConnection.SMBConnection.listPath">
306 <code class="descname">listPath</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>search=55</em>, <em>pattern='*'</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.listPath"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.listPath" title="Permalink to this definition">¶</a></dt>
229 <dl class="field-list simple">
230 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
231 <dd class="field-odd"><ul class="simple">
232 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></p></li>
233 <li><p><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><span class="doc">OperationFailure</span></a> will be raised.</p></li>
234 </ul>
235 </dd>
236 <dt class="field-even">Returns<span class="colon">:</span></dt>
237 <dd class="field-even"><p>A <a class="reference internal" href="smb_SharedFile.html"><span class="doc">smb.base.SharedFile</span></a> instance containing the attributes of the file.</p>
238 </dd>
239 </dl>
240 </dd></dl>
241
242 <dl class="py method">
243 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.getSecurity">
244 <span class="sig-name descname"><span class="pre">getSecurity</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.getSecurity"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.getSecurity" title="Permalink to this definition">¶</a></dt>
245 <dd><p>Retrieve the security descriptor of the file at <em>path</em> on the <em>service_name</em>.</p>
246 <dl class="field-list simple">
247 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
248 <dd class="field-odd"><ul class="simple">
249 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></p></li>
250 <li><p><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><span class="doc">OperationFailure</span></a> will be raised.</p></li>
251 </ul>
252 </dd>
253 <dt class="field-even">Returns<span class="colon">:</span></dt>
254 <dd class="field-even"><p>A <a class="reference internal" href="smb_security_descriptors.html#smb.security_descriptors.SecurityDescriptor" title="smb.security_descriptors.SecurityDescriptor"><code class="xref py py-class docutils literal notranslate"><span class="pre">smb.security_descriptors.SecurityDescriptor</span></code></a> instance containing the security information of the file.</p>
255 </dd>
256 </dl>
257 </dd></dl>
258
259 <dl class="py method">
260 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.listPath">
261 <span class="sig-name descname"><span class="pre">listPath</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">search</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">65591</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">pattern</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'*'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.listPath"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.listPath" title="Permalink to this definition">¶</a></dt>
307262 <dd><p>Retrieve a directory listing of files/folders at <em>path</em></p>
308 <table class="docutils field-list" frame="void" rules="none">
309 <col class="field-name" />
310 <col class="field-body" />
311 <tbody valign="top">
312 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
313 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
314 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; path relative to the <em>service_name</em> where we are interested to learn about its files/sub-folders.</li>
315 <li><strong>search</strong> (<em>integer</em>) &#8211; integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py).
316 The default <em>search</em> value will query for all read-only, hidden, system, archive files and directories.</li>
317 <li><strong>pattern</strong> (<em>string/unicode</em>) &#8211; the filter to apply to the results before returning to the client.</li>
318 </ul>
319 </td>
320 </tr>
321 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A list of <a class="reference internal" href="smb_SharedFile.html"><em>smb.base.SharedFile</em></a> instances.</p>
322 </td>
323 </tr>
324 </tbody>
325 </table>
326 </dd></dl>
327
328 <dl class="method">
329 <dt id="smb.SMBConnection.SMBConnection.listShares">
330 <code class="descname">listShares</code><span class="sig-paren">(</span><em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.listShares"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.listShares" title="Permalink to this definition">¶</a></dt>
263 <p>For simplicity, pysmb defines a “normal” file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.
264 It ignores other attributes like compression, indexed, sparse, temporary and encryption.</p>
265 <p>Note that the default search parameter will query for all read-only (SMB_FILE_ATTRIBUTE_READONLY), hidden (SMB_FILE_ATTRIBUTE_HIDDEN),
266 system (SMB_FILE_ATTRIBUTE_SYSTEM), archive (SMB_FILE_ATTRIBUTE_ARCHIVE), normal (SMB_FILE_ATTRIBUTE_INCL_NORMAL) files
267 and directories (SMB_FILE_ATTRIBUTE_DIRECTORY).
268 If you do not need to include “normal” files in the result, define your own search parameter without the SMB_FILE_ATTRIBUTE_INCL_NORMAL constant.
269 SMB_FILE_ATTRIBUTE_NORMAL should be used by itself and not be used with other bit constants.</p>
270 <dl class="field-list simple">
271 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
272 <dd class="field-odd"><ul class="simple">
273 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></p></li>
274 <li><p><strong>path</strong> (<em>string/unicode</em>) – path relative to the <em>service_name</em> where we are interested to learn about its files/sub-folders.</p></li>
275 <li><p><strong>search</strong> (<em>integer</em>) – integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py).</p></li>
276 <li><p><strong>pattern</strong> (<em>string/unicode</em>) – the filter to apply to the results before returning to the client.</p></li>
277 </ul>
278 </dd>
279 <dt class="field-even">Returns<span class="colon">:</span></dt>
280 <dd class="field-even"><p>A list of <a class="reference internal" href="smb_SharedFile.html"><span class="doc">smb.base.SharedFile</span></a> instances.</p>
281 </dd>
282 </dl>
283 </dd></dl>
284
285 <dl class="py method">
286 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.listShares">
287 <span class="sig-name descname"><span class="pre">listShares</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.listShares"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.listShares" title="Permalink to this definition">¶</a></dt>
331288 <dd><p>Retrieve a list of shared resources on remote server.</p>
332 <table class="docutils field-list" frame="void" rules="none">
333 <col class="field-name" />
334 <col class="field-body" />
335 <tbody valign="top">
336 <tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">A list of <a class="reference internal" href="smb_SharedDevice.html"><em>smb.base.SharedDevice</em></a> instances describing the shared resource</td>
337 </tr>
338 </tbody>
339 </table>
340 </dd></dl>
341
342 <dl class="method">
343 <dt id="smb.SMBConnection.SMBConnection.listSnapshots">
344 <code class="descname">listSnapshots</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.listSnapshots"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.listSnapshots" title="Permalink to this definition">¶</a></dt>
289 <dl class="field-list simple">
290 <dt class="field-odd">Returns<span class="colon">:</span></dt>
291 <dd class="field-odd"><p>A list of <a class="reference internal" href="smb_SharedDevice.html"><span class="doc">smb.base.SharedDevice</span></a> instances describing the shared resource</p>
292 </dd>
293 </dl>
294 </dd></dl>
295
296 <dl class="py method">
297 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.listSnapshots">
298 <span class="sig-name descname"><span class="pre">listSnapshots</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.listSnapshots"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.listSnapshots" title="Permalink to this definition">¶</a></dt>
345299 <dd><p>Retrieve a list of available snapshots (shadow copies) for <em>path</em>.</p>
346300 <p>Note that snapshot features are only supported on Windows Vista Business, Enterprise and Ultimate, and on all Windows 7 editions.</p>
347 <table class="docutils field-list" frame="void" rules="none">
348 <col class="field-name" />
349 <col class="field-body" />
350 <tbody valign="top">
351 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
352 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
353 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; path relative to the <em>service_name</em> where we are interested in the list of available snapshots</li>
354 </ul>
355 </td>
356 </tr>
357 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A list of python <em>datetime.DateTime</em> instances in GMT/UTC time zone</p>
358 </td>
359 </tr>
360 </tbody>
361 </table>
362 </dd></dl>
363
364 <dl class="method">
365 <dt id="smb.SMBConnection.SMBConnection.rename">
366 <code class="descname">rename</code><span class="sig-paren">(</span><em>service_name</em>, <em>old_path</em>, <em>new_path</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.rename"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.rename" title="Permalink to this definition">¶</a></dt>
301 <dl class="field-list simple">
302 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
303 <dd class="field-odd"><ul class="simple">
304 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></p></li>
305 <li><p><strong>path</strong> (<em>string/unicode</em>) – path relative to the <em>service_name</em> where we are interested in the list of available snapshots</p></li>
306 </ul>
307 </dd>
308 <dt class="field-even">Returns<span class="colon">:</span></dt>
309 <dd class="field-even"><p>A list of python <em>datetime.DateTime</em> instances in GMT/UTC time zone</p>
310 </dd>
311 </dl>
312 </dd></dl>
313
314 <dl class="py method">
315 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.rename">
316 <span class="sig-name descname"><span class="pre">rename</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">old_path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">new_path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.rename"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.rename" title="Permalink to this definition">¶</a></dt>
367317 <dd><p>Rename a file or folder at <em>old_path</em> to <em>new_path</em> shared at <em>service_name</em>. Note that this method cannot be used to rename file/folder across different shared folders</p>
368318 <p><em>old_path</em> and <em>new_path</em> are string/unicode referring to the old and new path of the renamed resources (relative to) the shared folder.
369319 If the path contains non-English characters, an unicode string must be used to pass in the path.</p>
370 <table class="docutils field-list" frame="void" rules="none">
371 <col class="field-name" />
372 <col class="field-body" />
373 <tbody valign="top">
374 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>service_name</strong> (<em>string/unicode</em>) &#8211; Contains the name of the shared folder.</td>
375 </tr>
376 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
377 </tr>
378 </tbody>
379 </table>
380 </dd></dl>
381
382 <dl class="method">
383 <dt id="smb.SMBConnection.SMBConnection.resetFileAttributes">
384 <code class="descname">resetFileAttributes</code><span class="sig-paren">(</span><em>service_name</em>, <em>path_file_pattern</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.resetFileAttributes"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.resetFileAttributes" title="Permalink to this definition">¶</a></dt>
320 <dl class="field-list simple">
321 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
322 <dd class="field-odd"><p><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</p>
323 </dd>
324 <dt class="field-even">Returns<span class="colon">:</span></dt>
325 <dd class="field-even"><p>None</p>
326 </dd>
327 </dl>
328 </dd></dl>
329
330 <dl class="py method">
331 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.resetFileAttributes">
332 <span class="sig-name descname"><span class="pre">resetFileAttributes</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path_file_pattern</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">file_attributes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">128</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.resetFileAttributes"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.resetFileAttributes" title="Permalink to this definition">¶</a></dt>
385333 <dd><p>Reset file attributes of one or more regular files or folders.
386334 It supports the use of wildcards in file names, allowing for unlocking of multiple files/folders in a single request.
387335 This function is very helpful when deleting files/folders that are read-only.
388 Note: this function is currently only implemented for SMB2! Technically, it sets the FILE_ATTRIBUTE_NORMAL flag, therefore clearing all other flags. (See <a class="reference external" href="https://msdn.microsoft.com/en-us/library/cc232110.aspx">https://msdn.microsoft.com/en-us/library/cc232110.aspx</a> for further information)</p>
389 <table class="docutils field-list" frame="void" rules="none">
390 <col class="field-name" />
391 <col class="field-body" />
392 <tbody valign="top">
393 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
394 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; Contains the name of the shared folder.</li>
395 <li><strong>path_file_pattern</strong> (<em>string/unicode</em>) &#8211; The pathname of the file(s) to be deleted, relative to the service_name.
336 By default, it sets the ATTR_NORMAL flag, therefore clearing all other flags.
337 (See <a class="reference external" href="https://msdn.microsoft.com/en-us/library/cc232110.aspx">https://msdn.microsoft.com/en-us/library/cc232110.aspx</a> for further information)</p>
338 <p>Note: this function is currently only implemented for SMB2!</p>
339 <dl class="field-list simple">
340 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
341 <dd class="field-odd"><ul class="simple">
342 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</p></li>
343 <li><p><strong>path_file_pattern</strong> (<em>string/unicode</em>) – The pathname of the file(s) to be deleted, relative to the service_name.
396344 Wildcards may be used in the filename component of the path.
397 If your path/filename contains non-English characters, you must pass in an unicode string.</li>
398 </ul>
399 </td>
400 </tr>
401 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">None</p>
402 </td>
403 </tr>
404 </tbody>
405 </table>
406 </dd></dl>
407
408 <dl class="method">
409 <dt id="smb.SMBConnection.SMBConnection.retrieveFile">
410 <code class="descname">retrieveFile</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.retrieveFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.retrieveFile" title="Permalink to this definition">¶</a></dt>
345 If your path/filename contains non-English characters, you must pass in an unicode string.</p></li>
346 <li><p><strong>file_attributes</strong> (<em>int</em>) – The desired file attributes to set. Defaults to <cite>ATTR_NORMAL</cite>.</p></li>
347 </ul>
348 </dd>
349 <dt class="field-even">Returns<span class="colon">:</span></dt>
350 <dd class="field-even"><p>None</p>
351 </dd>
352 </dl>
353 </dd></dl>
354
355 <dl class="py method">
356 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.retrieveFile">
357 <span class="sig-name descname"><span class="pre">retrieveFile</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">file_obj</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.retrieveFile"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.retrieveFile" title="Permalink to this definition">¶</a></dt>
411358 <dd><p>Retrieve the contents of the file at <em>path</em> on the <em>service_name</em> and write these contents to the provided <em>file_obj</em>.</p>
412359 <p>Use <em>retrieveFileFromOffset()</em> method if you wish to specify the offset to read from the remote <em>path</em> and/or the number of bytes to write to the <em>file_obj</em>.</p>
413 <table class="docutils field-list" frame="void" rules="none">
414 <col class="field-name" />
415 <col class="field-body" />
416 <tbody valign="top">
417 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
418 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
419 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be raised.</li>
420 <li><strong>file_obj</strong> &#8211; A file-like object that has a <em>write</em> method. Data will be written continuously to <em>file_obj</em> until EOF is received from the remote service.</li>
421 </ul>
422 </td>
423 </tr>
424 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A 2-element tuple of ( file attributes of the file on server, number of bytes written to <em>file_obj</em> ).
360 <dl class="field-list simple">
361 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
362 <dd class="field-odd"><ul class="simple">
363 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></p></li>
364 <li><p><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><span class="doc">OperationFailure</span></a> will be raised.</p></li>
365 <li><p><strong>file_obj</strong> – A file-like object that has a <em>write</em> method. Data will be written continuously to <em>file_obj</em> until EOF is received from the remote service. In Python3, this file-like object must have a <em>write</em> method which accepts a bytes parameter.</p></li>
366 </ul>
367 </dd>
368 <dt class="field-even">Returns<span class="colon">:</span></dt>
369 <dd class="field-even"><p>A 2-element tuple of ( file attributes of the file on server, number of bytes written to <em>file_obj</em> ).
425370 The file attributes is an integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py)</p>
426 </td>
427 </tr>
428 </tbody>
429 </table>
430 </dd></dl>
431
432 <dl class="method">
433 <dt id="smb.SMBConnection.SMBConnection.retrieveFileFromOffset">
434 <code class="descname">retrieveFileFromOffset</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>offset=0L</em>, <em>max_length=-1L</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.retrieveFileFromOffset"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.retrieveFileFromOffset" title="Permalink to this definition">¶</a></dt>
371 </dd>
372 </dl>
373 </dd></dl>
374
375 <dl class="py method">
376 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.retrieveFileFromOffset">
377 <span class="sig-name descname"><span class="pre">retrieveFileFromOffset</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">file_obj</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">offset</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">max_length</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">-</span> <span class="pre">1</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.retrieveFileFromOffset"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.retrieveFileFromOffset" title="Permalink to this definition">¶</a></dt>
435378 <dd><p>Retrieve the contents of the file at <em>path</em> on the <em>service_name</em> and write these contents to the provided <em>file_obj</em>.</p>
436 <table class="docutils field-list" frame="void" rules="none">
437 <col class="field-name" />
438 <col class="field-body" />
439 <tbody valign="top">
440 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
441 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
442 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be raised.</li>
443 <li><strong>file_obj</strong> &#8211; A file-like object that has a <em>write</em> method. Data will be written continuously to <em>file_obj</em> up to <em>max_length</em> number of bytes.</li>
444 <li><strong>offset</strong> (<em>integer/long</em>) &#8211; the offset in the remote <em>path</em> where the first byte will be read and written to <em>file_obj</em>. Must be either zero or a positive integer/long value.</li>
445 <li><strong>max_length</strong> (<em>integer/long</em>) &#8211; maximum number of bytes to read from the remote <em>path</em> and write to the <em>file_obj</em>. Specify a negative value to read from <em>offset</em> to the EOF.
446 If zero, the method returns immediately after the file is opened successfully for reading.</li>
447 </ul>
448 </td>
449 </tr>
450 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A 2-element tuple of ( file attributes of the file on server, number of bytes written to <em>file_obj</em> ).
379 <dl class="field-list simple">
380 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
381 <dd class="field-odd"><ul class="simple">
382 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></p></li>
383 <li><p><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><span class="doc">OperationFailure</span></a> will be raised.</p></li>
384 <li><p><strong>file_obj</strong> – A file-like object that has a <em>write</em> method. Data will be written continuously to <em>file_obj</em> up to <em>max_length</em> number of bytes. In Python3, this file-like object must have a <em>write</em> method which accepts a bytes parameter.</p></li>
385 <li><p><strong>offset</strong> (<em>integer/long</em>) – the offset in the remote <em>path</em> where the first byte will be read and written to <em>file_obj</em>. Must be either zero or a positive integer/long value.</p></li>
386 <li><p><strong>max_length</strong> (<em>integer/long</em>) – maximum number of bytes to read from the remote <em>path</em> and write to the <em>file_obj</em>. Specify a negative value to read from <em>offset</em> to the EOF.
387 If zero, the method returns immediately after the file is opened successfully for reading.</p></li>
388 </ul>
389 </dd>
390 <dt class="field-even">Returns<span class="colon">:</span></dt>
391 <dd class="field-even"><p>A 2-element tuple of ( file attributes of the file on server, number of bytes written to <em>file_obj</em> ).
451392 The file attributes is an integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py)</p>
452 </td>
453 </tr>
454 </tbody>
455 </table>
456 </dd></dl>
457
458 <dl class="method">
459 <dt id="smb.SMBConnection.SMBConnection.storeFile">
460 <code class="descname">storeFile</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.storeFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.storeFile" title="Permalink to this definition">¶</a></dt>
393 </dd>
394 </dl>
395 </dd></dl>
396
397 <dl class="py method">
398 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.storeFile">
399 <span class="sig-name descname"><span class="pre">storeFile</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">file_obj</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.storeFile"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.storeFile" title="Permalink to this definition">¶</a></dt>
461400 <dd><p>Store the contents of the <em>file_obj</em> at <em>path</em> on the <em>service_name</em>.
462401 If the file already exists on the remote server, it will be truncated and overwritten.</p>
463 <table class="docutils field-list" frame="void" rules="none">
464 <col class="field-name" />
465 <col class="field-body" />
466 <tbody valign="top">
467 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
468 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
469 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; Path of the file on the remote server. If the file at <em>path</em> does not exist, it will be created. Otherwise, it will be overwritten.
470 If the <em>path</em> refers to a folder or the file cannot be opened for writing, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be raised.</li>
471 <li><strong>file_obj</strong> &#8211; A file-like object that has a <em>read</em> method. Data will read continuously from <em>file_obj</em> until EOF.</li>
472 </ul>
473 </td>
474 </tr>
475 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">Number of bytes uploaded</p>
476 </td>
477 </tr>
478 </tbody>
479 </table>
480 </dd></dl>
481
482 <dl class="method">
483 <dt id="smb.SMBConnection.SMBConnection.storeFileFromOffset">
484 <code class="descname">storeFileFromOffset</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>offset=0L</em>, <em>truncate=False</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.storeFileFromOffset"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.storeFileFromOffset" title="Permalink to this definition">¶</a></dt>
402 <dl class="field-list simple">
403 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
404 <dd class="field-odd"><ul class="simple">
405 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></p></li>
406 <li><p><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file at <em>path</em> does not exist, it will be created. Otherwise, it will be overwritten.
407 If the <em>path</em> refers to a folder or the file cannot be opened for writing, an <a class="reference internal" href="smb_exceptions.html"><span class="doc">OperationFailure</span></a> will be raised.</p></li>
408 <li><p><strong>file_obj</strong> – A file-like object that has a <em>read</em> method. Data will read continuously from <em>file_obj</em> until EOF. In Python3, this file-like object must have a <em>read</em> method which returns a bytes parameter.</p></li>
409 </ul>
410 </dd>
411 <dt class="field-even">Returns<span class="colon">:</span></dt>
412 <dd class="field-even"><p>Number of bytes uploaded</p>
413 </dd>
414 </dl>
415 </dd></dl>
416
417 <dl class="py method">
418 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.storeFileFromOffset">
419 <span class="sig-name descname"><span class="pre">storeFileFromOffset</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">service_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">file_obj</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">offset</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">truncate</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">30</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.storeFileFromOffset"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.storeFileFromOffset" title="Permalink to this definition">¶</a></dt>
485420 <dd><p>Store the contents of the <em>file_obj</em> at <em>path</em> on the <em>service_name</em>.</p>
486 <table class="docutils field-list" frame="void" rules="none">
487 <col class="field-name" />
488 <col class="field-body" />
489 <tbody valign="top">
490 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
491 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
492 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; Path of the file on the remote server. If the file at <em>path</em> does not exist, it will be created.
493 If the <em>path</em> refers to a folder or the file cannot be opened for writing, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be raised.</li>
494 <li><strong>file_obj</strong> &#8211; A file-like object that has a <em>read</em> method. Data will read continuously from <em>file_obj</em> until EOF.</li>
495 <li><strong>offset</strong> &#8211; Long integer value which specifies the offset in the remote server to start writing. First byte of the file is 0.</li>
496 <li><strong>truncate</strong> &#8211; Boolean value. If True and the file exists on the remote server, it will be truncated first before writing. Default is False.</li>
497 </ul>
498 </td>
499 </tr>
500 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the file position where the next byte will be written.</p>
501 </td>
502 </tr>
503 </tbody>
504 </table>
505 </dd></dl>
506
507 <dl class="attribute">
508 <dt id="smb.SMBConnection.SMBConnection.SIGN_NEVER">
509 <code class="descname">SIGN_NEVER</code><em class="property"> = 0</em><a class="headerlink" href="#smb.SMBConnection.SMBConnection.SIGN_NEVER" title="Permalink to this definition">¶</a></dt>
510 <dd><p>SMB messages will never be signed regardless of remote server&#8217;s configurations; access errors will occur if the remote server requires signing.</p>
511 </dd></dl>
512
513 <dl class="attribute">
514 <dt id="smb.SMBConnection.SMBConnection.SIGN_WHEN_REQUIRED">
515 <code class="descname">SIGN_WHEN_REQUIRED</code><em class="property"> = 2</em><a class="headerlink" href="#smb.SMBConnection.SMBConnection.SIGN_WHEN_REQUIRED" title="Permalink to this definition">¶</a></dt>
421 <dl class="field-list simple">
422 <dt class="field-odd">Parameters<span class="colon">:</span></dt>
423 <dd class="field-odd"><ul class="simple">
424 <li><p><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></p></li>
425 <li><p><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file at <em>path</em> does not exist, it will be created.
426 If the <em>path</em> refers to a folder or the file cannot be opened for writing, an <a class="reference internal" href="smb_exceptions.html"><span class="doc">OperationFailure</span></a> will be raised.</p></li>
427 <li><p><strong>file_obj</strong> – A file-like object that has a <em>read</em> method. Data will read continuously from <em>file_obj</em> until EOF.</p></li>
428 <li><p><strong>offset</strong> – Long integer value which specifies the offset in the remote server to start writing. First byte of the file is 0.</p></li>
429 <li><p><strong>truncate</strong> – Boolean value. If True and the file exists on the remote server, it will be truncated first before writing. Default is False.</p></li>
430 </ul>
431 </dd>
432 <dt class="field-even">Returns<span class="colon">:</span></dt>
433 <dd class="field-even"><p>the file position where the next byte will be written.</p>
434 </dd>
435 </dl>
436 </dd></dl>
437
438 <dl class="py attribute">
439 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.SIGN_NEVER">
440 <span class="sig-name descname"><span class="pre">SIGN_NEVER</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">0</span></em><a class="headerlink" href="#smb.SMBConnection.SMBConnection.SIGN_NEVER" title="Permalink to this definition">¶</a></dt>
441 <dd><p>SMB messages will never be signed regardless of remote server’s configurations; access errors will occur if the remote server requires signing.</p>
442 </dd></dl>
443
444 <dl class="py attribute">
445 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.SIGN_WHEN_REQUIRED">
446 <span class="sig-name descname"><span class="pre">SIGN_WHEN_REQUIRED</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">2</span></em><a class="headerlink" href="#smb.SMBConnection.SMBConnection.SIGN_WHEN_REQUIRED" title="Permalink to this definition">¶</a></dt>
516447 <dd><p>SMB messages will only be signed when remote server requires signing.</p>
517448 </dd></dl>
518449
519 <dl class="attribute">
520 <dt id="smb.SMBConnection.SMBConnection.SIGN_WHEN_SUPPORTED">
521 <code class="descname">SIGN_WHEN_SUPPORTED</code><em class="property"> = 1</em><a class="headerlink" href="#smb.SMBConnection.SMBConnection.SIGN_WHEN_SUPPORTED" title="Permalink to this definition">¶</a></dt>
450 <dl class="py attribute">
451 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.SIGN_WHEN_SUPPORTED">
452 <span class="sig-name descname"><span class="pre">SIGN_WHEN_SUPPORTED</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">1</span></em><a class="headerlink" href="#smb.SMBConnection.SMBConnection.SIGN_WHEN_SUPPORTED" title="Permalink to this definition">¶</a></dt>
522453 <dd><p>SMB messages will be signed when remote server supports signing but not requires signing.</p>
523454 </dd></dl>
524455
525 <dl class="attribute">
526 <dt id="smb.SMBConnection.SMBConnection.isUsingSMB2">
527 <code class="descname">isUsingSMB2</code><a class="headerlink" href="#smb.SMBConnection.SMBConnection.isUsingSMB2" title="Permalink to this definition">¶</a></dt>
456 <dl class="py property">
457 <dt class="sig sig-object py" id="smb.SMBConnection.SMBConnection.isUsingSMB2">
458 <em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">isUsingSMB2</span></span><a class="headerlink" href="#smb.SMBConnection.SMBConnection.isUsingSMB2" title="Permalink to this definition">¶</a></dt>
528459 <dd><p>A convenient property to return True if the underlying SMB connection is using SMB2 protocol.</p>
529460 </dd></dl>
530461
531462 </dd></dl>
532463
464 </section>
465 </section>
466
467
468 <div class="clearer"></div>
469 </div>
470 </div>
471 </div>
472 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
473 <div class="sphinxsidebarwrapper">
474 <div>
475 <h3><a href="../index.html">Table of Contents</a></h3>
476 <ul>
477 <li><a class="reference internal" href="#">SMBConnection Class</a><ul>
478 <li><a class="reference internal" href="#example">Example</a></li>
479 <li><a class="reference internal" href="#smb2-support">SMB2 Support</a></li>
480 <li><a class="reference internal" href="#caveats">Caveats</a></li>
481 </ul>
482 </li>
483 </ul>
484
485 </div>
486 <div>
487 <h4>Previous topic</h4>
488 <p class="topless"><a href="nmb_NetBIOS.html"
489 title="previous chapter">NetBIOS class</a></p>
490 </div>
491 <div>
492 <h4>Next topic</h4>
493 <p class="topless"><a href="smb_SMBHandler.html"
494 title="next chapter">SMbHandler Class</a></p>
495 </div>
496 <div role="note" aria-label="source link">
497 <h3>This Page</h3>
498 <ul class="this-page-menu">
499 <li><a href="../_sources/api/smb_SMBConnection.rst.txt"
500 rel="nofollow">Show Source</a></li>
501 </ul>
502 </div>
503 <div id="searchbox" style="display: none" role="search">
504 <h3 id="searchlabel">Quick search</h3>
505 <div class="searchformwrapper">
506 <form class="search" action="../search.html" method="get">
507 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
508 <input type="submit" value="Go" />
509 </form>
510 </div>
533511 </div>
534 </div>
535
536
537 </div>
512 <script>document.getElementById('searchbox').style.display = "block"</script>
538513 </div>
539514 </div>
540515 <div class="clearer"></div>
546521 <a href="../genindex.html" title="General Index"
547522 >index</a></li>
548523 <li class="right" >
524 <a href="../py-modindex.html" title="Python Module Index"
525 >modules</a> |</li>
526 <li class="right" >
549527 <a href="smb_SMBHandler.html" title="SMbHandler Class"
550528 >next</a> |</li>
551529 <li class="right" >
552530 <a href="nmb_NetBIOS.html" title="NetBIOS class"
553531 >previous</a> |</li>
554 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
532 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
533 <li class="nav-item nav-item-this"><a href="">SMBConnection Class</a></li>
555534 </ul>
556535 </div>
557536 <div class="footer" role="contentinfo">
558 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
559 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
537 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
538 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
560539 </div>
561540 </body>
562541 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>SMbHandler Class &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../_static/jquery.js"></script>
23 <script type="text/javascript" src="../_static/underscore.js"></script>
24 <script type="text/javascript" src="../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../index.html" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>SMbHandler Class &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
11 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
12 <script src="../_static/jquery.js"></script>
13 <script src="../_static/underscore.js"></script>
14 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="../_static/doctools.js"></script>
16 <link rel="index" title="Index" href="../genindex.html" />
17 <link rel="search" title="Search" href="../search.html" />
2618 <link rel="next" title="SMBProtocolFactory Class" href="smb_SMBProtocolFactory.html" />
2719 <link rel="prev" title="SMBConnection Class" href="smb_SMBConnection.html" />
28 </head>
29 <body role="document">
20 </head><body>
3021 <div class="related" role="navigation" aria-label="related navigation">
3122 <h3>Navigation</h3>
3223 <ul>
3425 <a href="../genindex.html" title="General Index"
3526 accesskey="I">index</a></li>
3627 <li class="right" >
28 <a href="../py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
3731 <a href="smb_SMBProtocolFactory.html" title="SMBProtocolFactory Class"
3832 accesskey="N">next</a> |</li>
3933 <li class="right" >
4034 <a href="smb_SMBConnection.html" title="SMBConnection Class"
4135 accesskey="P">previous</a> |</li>
42 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">SMbHandler Class</a></li>
4338 </ul>
44 </div>
45 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
46 <div class="sphinxsidebarwrapper">
47 <h3><a href="../index.html">Table Of Contents</a></h3>
48 <ul>
49 <li><a class="reference internal" href="#">SMbHandler Class</a><ul>
50 <li><a class="reference internal" href="#notes">Notes</a></li>
51 <li><a class="reference internal" href="#example">Example</a></li>
52 </ul>
53 </li>
54 </ul>
55
56 <h4>Previous topic</h4>
57 <p class="topless"><a href="smb_SMBConnection.html"
58 title="previous chapter">SMBConnection Class</a></p>
59 <h4>Next topic</h4>
60 <p class="topless"><a href="smb_SMBProtocolFactory.html"
61 title="next chapter">SMBProtocolFactory Class</a></p>
62 <div role="note" aria-label="source link">
63 <h3>This Page</h3>
64 <ul class="this-page-menu">
65 <li><a href="../_sources/api/smb_SMBHandler.txt"
66 rel="nofollow">Show Source</a></li>
67 </ul>
68 </div>
69 <div id="searchbox" style="display: none" role="search">
70 <h3>Quick search</h3>
71 <form class="search" action="../search.html" method="get">
72 <input type="text" name="q" />
73 <input type="submit" value="Go" />
74 <input type="hidden" name="check_keywords" value="yes" />
75 <input type="hidden" name="area" value="default" />
76 </form>
77 <p class="searchtip" style="font-size: 90%">
78 Enter search terms or a module, class or function name.
79 </p>
80 </div>
81 <script type="text/javascript">$('#searchbox').show(0);</script>
82 </div>
83 </div>
39 </div>
8440
8541 <div class="document">
8642 <div class="documentwrapper">
8743 <div class="bodywrapper">
8844 <div class="body" role="main">
8945
90 <div class="section" id="smbhandler-class">
91 <h1>SMbHandler Class<a class="headerlink" href="#smbhandler-class" title="Permalink to this headline">¶</a></h1>
92 <p>The SMBHandler class provides support for &#8220;<a class="reference external" href="smb://">smb://</a>&#8221; URLs in the <a class="reference external" href="http://docs.python.org/library/urllib2.html">urllib2</a> python package.</p>
93 <div class="section" id="notes">
94 <h2>Notes<a class="headerlink" href="#notes" title="Permalink to this headline">¶</a></h2>
46 <section id="smbhandler-class">
47 <h1>SMbHandler Class<a class="headerlink" href="#smbhandler-class" title="Permalink to this heading">¶</a></h1>
48 <p>The SMBHandler class provides support for “<a class="reference external" href="smb://">smb://</a>” URLs in the <a class="reference external" href="http://docs.python.org/library/urllib2.html">urllib2</a> python package.</p>
49 <section id="notes">
50 <h2>Notes<a class="headerlink" href="#notes" title="Permalink to this heading">¶</a></h2>
9551 <ul class="simple">
96 <li>Note that you need to pass in a valid hostname or IP address for the host component of the URL.
97 Do not use the Windows/NetBIOS machine name for the host component.</li>
98 <li>The first component of the path in the URL points to the name of the shared folder.
99 Subsequent path components will point to the directory/folder of the file.</li>
100 <li>You can retrieve and upload files, but you cannot delete files/folders or create folders.
101 In uploads, if the parent folders do not exist, an <em>urllib2.URLError</em> will be raised.</li>
102 </ul>
103 </div>
104 <div class="section" id="example">
105 <h2>Example<a class="headerlink" href="#example" title="Permalink to this headline">¶</a></h2>
106 <p>The following code snippet illustrates file retrieval.:</p>
107 <div class="highlight-python"><div class="highlight"><pre><span class="c1"># -*- coding: utf-8 -*-</span>
52 <li><p>The host component of the URL must be one of the following:</p>
53 <ul>
54 <li><p>A fully-qualified hostname that can be resolved by your local DNS service. Example: myserver.test.com</p></li>
55 <li><p>An IP address. Example: 192.168.1.1</p></li>
56 <li><p>A comma-separated string “&lt;NBName&gt;,&lt;IP&gt;” where <em>&lt;NBName&gt;</em> is the Windows/NetBIOS machine name for remote SMB service, and <em>&lt;IP&gt;</em> is the service’s IP address. Example: MYSERVER,192.168.1.1</p></li>
57 </ul>
58 </li>
59 <li><p>The first component of the path in the URL points to the name of the shared folder.
60 Subsequent path components will point to the directory/folder of the file.</p></li>
61 <li><p>You can retrieve and upload files, but you cannot delete files/folders or create folders.
62 In uploads, if the parent folders do not exist, an <em>urllib2.URLError</em> will be raised.</p></li>
63 </ul>
64 </section>
65 <section id="example">
66 <h2>Example<a class="headerlink" href="#example" title="Permalink to this heading">¶</a></h2>
67 <p>The following code snippet illustrates file retrieval with Python 2.:</p>
68 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># -*- coding: utf-8 -*-</span>
10869 <span class="kn">import</span> <span class="nn">urllib2</span>
10970 <span class="kn">from</span> <span class="nn">smb.SMBHandler</span> <span class="kn">import</span> <span class="n">SMBHandler</span>
11071
11576 <span class="n">fh</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
11677
11778 <span class="c1"># For paths/files with unicode characters, simply pass in the URL as an unicode string</span>
118 <span class="n">fh2</span> <span class="o">=</span> <span class="n">director</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">u&#39;smb://myuserID:[email protected]/sharedfolder/测试文件夹/垃圾文件.dat&#39;</span><span class="p">)</span>
79 <span class="n">fh2</span> <span class="o">=</span> <span class="n">director</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="sa">u</span><span class="s1">&#39;smb://myuserID:[email protected]/sharedfolder/测试文件夹/垃圾文件.dat&#39;</span><span class="p">)</span>
11980
12081 <span class="c1"># Process fh2 like a file-like object and then close it.</span>
12182 <span class="n">fh2</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
12283 </pre></div>
12384 </div>
124 <p>The following code snippet illustrates file upload. You need to provide a file-like object for the <em>data</em> parameter in the <em>open()</em> method:</p>
125 <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">urllib2</span>
85 <p>The following code snippet illustrates file upload with Python 2. You need to provide a file-like object for the <em>data</em> parameter in the <em>open()</em> method:</p>
86 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">urllib2</span>
12687 <span class="kn">from</span> <span class="nn">smb.SMBHandler</span> <span class="kn">import</span> <span class="n">SMBHandler</span>
12788
12889 <span class="n">file_fh</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;local_file.dat&#39;</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span>
13495 <span class="n">fh</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
13596 </pre></div>
13697 </div>
137 </div>
138 </div>
139
140
98 <p>The following code snippet illustrates file retrieval with Python 3.:</p>
99 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">urllib</span>
100 <span class="kn">from</span> <span class="nn">smb.SMBHandler</span> <span class="kn">import</span> <span class="n">SMBHandler</span>
101
102 <span class="n">director</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">build_opener</span><span class="p">(</span><span class="n">SMBHandler</span><span class="p">)</span>
103 <span class="n">fh</span> <span class="o">=</span> <span class="n">director</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">&#39;smb://myuserID:[email protected]/sharedfolder/rfc1001.txt&#39;</span><span class="p">)</span>
104
105 <span class="c1"># Process fh like a file-like object and then close it.</span>
106 <span class="n">fh</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
107
108 <span class="c1"># For paths/files with unicode characters, simply pass in the URL as an unicode string</span>
109 <span class="n">fh2</span> <span class="o">=</span> <span class="n">director</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="sa">u</span><span class="s1">&#39;smb://myuserID:[email protected]/sharedfolder/测试文件夹/垃圾文件.dat&#39;</span><span class="p">)</span>
110
111 <span class="c1"># Process fh2 like a file-like object and then close it.</span>
112 <span class="n">fh2</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
113 </pre></div>
114 </div>
115 <p>The following code snippet illustrates file upload with Python 3. You need to provide a file-like object for the <em>data</em> parameter in the <em>open()</em> method:</p>
116 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">urllib</span>
117 <span class="kn">from</span> <span class="nn">smb.SMBHandler</span> <span class="kn">import</span> <span class="n">SMBHandler</span>
118
119 <span class="n">file_fh</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;local_file.dat&#39;</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span>
120
121 <span class="n">director</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">build_opener</span><span class="p">(</span><span class="n">SMBHandler</span><span class="p">)</span>
122 <span class="n">fh</span> <span class="o">=</span> <span class="n">director</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">&#39;smb://myuserID:[email protected]/sharedfolder/upload_file.dat&#39;</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">file_fh</span><span class="p">)</span>
123
124 <span class="c1"># Reading from fh will only return an empty string</span>
125 <span class="n">fh</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
126 </pre></div>
127 </div>
128 </section>
129 </section>
130
131
132 <div class="clearer"></div>
141133 </div>
134 </div>
135 </div>
136 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
137 <div class="sphinxsidebarwrapper">
138 <div>
139 <h3><a href="../index.html">Table of Contents</a></h3>
140 <ul>
141 <li><a class="reference internal" href="#">SMbHandler Class</a><ul>
142 <li><a class="reference internal" href="#notes">Notes</a></li>
143 <li><a class="reference internal" href="#example">Example</a></li>
144 </ul>
145 </li>
146 </ul>
147
148 </div>
149 <div>
150 <h4>Previous topic</h4>
151 <p class="topless"><a href="smb_SMBConnection.html"
152 title="previous chapter">SMBConnection Class</a></p>
153 </div>
154 <div>
155 <h4>Next topic</h4>
156 <p class="topless"><a href="smb_SMBProtocolFactory.html"
157 title="next chapter">SMBProtocolFactory Class</a></p>
158 </div>
159 <div role="note" aria-label="source link">
160 <h3>This Page</h3>
161 <ul class="this-page-menu">
162 <li><a href="../_sources/api/smb_SMBHandler.rst.txt"
163 rel="nofollow">Show Source</a></li>
164 </ul>
165 </div>
166 <div id="searchbox" style="display: none" role="search">
167 <h3 id="searchlabel">Quick search</h3>
168 <div class="searchformwrapper">
169 <form class="search" action="../search.html" method="get">
170 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
171 <input type="submit" value="Go" />
172 </form>
173 </div>
174 </div>
175 <script>document.getElementById('searchbox').style.display = "block"</script>
142176 </div>
143177 </div>
144178 <div class="clearer"></div>
150184 <a href="../genindex.html" title="General Index"
151185 >index</a></li>
152186 <li class="right" >
187 <a href="../py-modindex.html" title="Python Module Index"
188 >modules</a> |</li>
189 <li class="right" >
153190 <a href="smb_SMBProtocolFactory.html" title="SMBProtocolFactory Class"
154191 >next</a> |</li>
155192 <li class="right" >
156193 <a href="smb_SMBConnection.html" title="SMBConnection Class"
157194 >previous</a> |</li>
158 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
195 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
196 <li class="nav-item nav-item-this"><a href="">SMbHandler Class</a></li>
159197 </ul>
160198 </div>
161199 <div class="footer" role="contentinfo">
162 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
163 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
200 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
201 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
164202 </div>
165203 </body>
166204 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>SMBProtocolFactory Class &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../_static/jquery.js"></script>
23 <script type="text/javascript" src="../_static/underscore.js"></script>
24 <script type="text/javascript" src="../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../index.html" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>SMBProtocolFactory Class &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
11 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
12 <script src="../_static/jquery.js"></script>
13 <script src="../_static/underscore.js"></script>
14 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="../_static/doctools.js"></script>
16 <link rel="index" title="Index" href="../genindex.html" />
17 <link rel="search" title="Search" href="../search.html" />
2618 <link rel="next" title="SharedDevice Class" href="smb_SharedDevice.html" />
2719 <link rel="prev" title="SMbHandler Class" href="smb_SMBHandler.html" />
28 </head>
29 <body role="document">
20 </head><body>
3021 <div class="related" role="navigation" aria-label="related navigation">
3122 <h3>Navigation</h3>
3223 <ul>
3425 <a href="../genindex.html" title="General Index"
3526 accesskey="I">index</a></li>
3627 <li class="right" >
28 <a href="../py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
3731 <a href="smb_SharedDevice.html" title="SharedDevice Class"
3832 accesskey="N">next</a> |</li>
3933 <li class="right" >
4034 <a href="smb_SMBHandler.html" title="SMbHandler Class"
4135 accesskey="P">previous</a> |</li>
42 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">SMBProtocolFactory Class</a></li>
4338 </ul>
44 </div>
39 </div>
40
41 <div class="document">
42 <div class="documentwrapper">
43 <div class="bodywrapper">
44 <div class="body" role="main">
45
46 <section id="smbprotocolfactory-class">
47 <h1>SMBProtocolFactory Class<a class="headerlink" href="#smbprotocolfactory-class" title="Permalink to this heading">¶</a></h1>
48 <p>For those who want to utilize pysmb in Twisted framework, pysmb has a <em>smb.SMBProtocol.SMBProtocol</em> implementation.
49 In most cases, you do not need to touch or import the <em>SMBProtocol</em> directly. All the SMB functionalities are exposed in the <em>SMBProtocolFactory</em>.</p>
50 <dl class="simple">
51 <dt>In your project,</dt><dd><ol class="arabic simple">
52 <li><p>Create a new class and subclass <em>SMBProtocolFactory</em>.</p></li>
53 <li><p>Override the <em>SMBProtocolFactory.onAuthOK</em> and <em>SMBProtocolFactory.onAuthFailed</em> instance methods to provide your own post-authenthentication handling.
54 Once <em>SMBProtocolFactory.onAuthOK</em> has been called by pymsb internals, your application is ready to communicate with the remote SMB/CIFS service through
55 the <em>SMBProtocolFactory</em> public methods such as <em>SMBProtocolFactory.storeFile</em>, <em>SMBProtocolFactory.retrieveFile</em>, etc.</p></li>
56 <li><p>When you want to disconnect from the remote SMB/CIFS server, just call <em>SMBProtocolFactory.closeConnection</em> method.</p></li>
57 </ol>
58 </dd>
59 </dl>
60 <p>All the <em>SMBProtocolFactory</em> public methods that provide file functionlities will return a <em>twisted.internet.defer.Deferred</em> instance.
61 A <a class="reference internal" href="smb_exceptions.html"><span class="doc">NotReadyError</span></a> exception is raised when the underlying SMB is not authenticated.
62 If the underlying SMB connection has been terminated, a <a class="reference internal" href="smb_exceptions.html"><span class="doc">NotConnectedError</span></a> exception is raised.</p>
63 <p>All the file operation methods in <em>SMBProtocolFactory</em> class accept a <em>timeout</em> parameter. This parameter specifies the time limit where pysmb will wait for the
64 entire file operation (except <em>storeFile</em> and <em>retrieveFile</em> methods) to complete. If the file operation fails to complete within the timeout period, the returned
65 <em>Deferred</em> instance’s <em>errback</em> method will be called with a <em>SMBTimeout</em> exception.</p>
66 <p>If you are interested in learning the results of the operation or to know when the operation has completed, you should
67 add a handling method to the returned <em>Deferred</em> instance via <em>Deferred.addCallback</em>. If the file operation fails, the <em>Deferred.errback</em> function will be called
68 with an <a class="reference internal" href="smb_exceptions.html"><span class="doc">OperationFailure</span></a>; on timeout, it will be called with a <a class="reference internal" href="smb_exceptions.html"><span class="doc">SMBTimeout</span></a>.</p>
69 <section id="example">
70 <h2>Example<a class="headerlink" href="#example" title="Permalink to this heading">¶</a></h2>
71 <p>The following illustrates a simple file retrieving implementation.:</p>
72 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">tempfile</span>
73 <span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
74 <span class="kn">from</span> <span class="nn">smb.SMBProtocol</span> <span class="kn">import</span> <span class="n">SMBProtocolFactory</span>
75
76 <span class="k">class</span> <span class="nc">RetrieveFileFactory</span><span class="p">(</span><span class="n">SMBProtocolFactory</span><span class="p">):</span>
77
78 <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
79 <span class="n">SMBProtocolFactory</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
80
81 <span class="k">def</span> <span class="nf">fileRetrieved</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">write_result</span><span class="p">):</span>
82 <span class="n">file_obj</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">file_size</span> <span class="o">=</span> <span class="n">write_result</span>
83
84 <span class="c1"># Retrieved file contents are inside file_obj</span>
85 <span class="c1"># Do what you need with the file_obj and then close it</span>
86 <span class="c1"># Note that the file obj is positioned at the end-of-file,</span>
87 <span class="c1"># so you might need to perform a file_obj.seek() to if you</span>
88 <span class="c1"># need to read from the beginning</span>
89 <span class="n">file_obj</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
90
91 <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">loseConnection</span><span class="p">()</span>
92
93 <span class="k">def</span> <span class="nf">onAuthOK</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
94 <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">retrieveFile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">service</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">NamedTemporaryFile</span><span class="p">())</span>
95 <span class="n">d</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fileRetrieved</span><span class="p">)</span>
96 <span class="n">d</span><span class="o">.</span><span class="n">addErrback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">)</span>
97
98 <span class="k">def</span> <span class="nf">onAuthFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
99 <span class="nb">print</span> <span class="s1">&#39;Auth failed&#39;</span>
100
101 <span class="c1"># There will be some mechanism to capture userID, password, client_machine_name, server_name and server_ip</span>
102 <span class="c1"># client_machine_name can be an arbitary ASCII string</span>
103 <span class="c1"># server_name should match the remote machine name, or else the connection will be rejected</span>
104 <span class="n">factory</span> <span class="o">=</span> <span class="n">RetrieveFileFactory</span><span class="p">(</span><span class="n">userID</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">client_machine_name</span><span class="p">,</span> <span class="n">server_name</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span>
105 <span class="n">factory</span><span class="o">.</span><span class="n">service</span> <span class="o">=</span> <span class="s1">&#39;smbtest&#39;</span>
106 <span class="n">factory</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="s1">&#39;/rfc1001.txt&#39;</span>
107 <span class="n">reactor</span><span class="o">.</span><span class="n">connectTCP</span><span class="p">(</span><span class="n">server_ip</span><span class="p">,</span> <span class="mi">139</span><span class="p">,</span> <span class="n">factory</span><span class="p">)</span>
108 </pre></div>
109 </div>
110 </section>
111 <section id="smb2-support">
112 <h2>SMB2 Support<a class="headerlink" href="#smb2-support" title="Permalink to this heading">¶</a></h2>
113 <p>Starting from pysmb 1.1.0, pysmb will utilize SMB2 protocol for communication if the remote SMB/CIFS service supports SMB2.
114 Otherwise, it will fallback automatically back to using SMB1 protocol.</p>
115 <p>To disable SMB2 protocol in pysmb, set the <em>SUPPORT_SMB2</em> flag in the <em>smb_structs</em> module to <em>False</em> before creating the <em>SMBProtocolFactory</em> instance.:</p>
116 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">smb</span> <span class="kn">import</span> <span class="n">smb_structs</span>
117 <span class="n">smb_structs</span><span class="o">.</span><span class="n">SUPPORT_SMB2</span> <span class="o">=</span> <span class="kc">False</span>
118 </pre></div>
119 </div>
120 </section>
121 <section id="caveats">
122 <h2>Caveats<a class="headerlink" href="#caveats" title="Permalink to this heading">¶</a></h2>
123 <ul class="simple">
124 <li><p>A new factory instance must be created for each SMB connection to the remote SMB/CIFS service. Avoid reusing the same factory instance for more than one SMB connection.</p></li>
125 <li><p>The remote SMB/CIFS server usually imposes a limit of the number of concurrent file operations for each client. For example, to transfer a thousand files, you may need to setup a queue in your application and call <em>storeFile</em> or <em>retrieveFile</em> in batches.</p></li>
126 <li><p>The <em>timeout</em> parameter in the file operation methods are not precise; it is accurate to within 1 second interval, i.e. with a timeout of 0.5 sec, pysmb might raise
127 <em>SMBTimeout</em> exception after 1.5 sec.</p></li>
128 </ul>
129 </section>
130 </section>
131
132
133 <div class="clearer"></div>
134 </div>
135 </div>
136 </div>
45137 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
46138 <div class="sphinxsidebarwrapper">
47 <h3><a href="../index.html">Table Of Contents</a></h3>
48 <ul>
139 <div>
140 <h3><a href="../index.html">Table of Contents</a></h3>
141 <ul>
49142 <li><a class="reference internal" href="#">SMBProtocolFactory Class</a><ul>
50143 <li><a class="reference internal" href="#example">Example</a></li>
51144 <li><a class="reference internal" href="#smb2-support">SMB2 Support</a></li>
54147 </li>
55148 </ul>
56149
57 <h4>Previous topic</h4>
58 <p class="topless"><a href="smb_SMBHandler.html"
59 title="previous chapter">SMbHandler Class</a></p>
60 <h4>Next topic</h4>
61 <p class="topless"><a href="smb_SharedDevice.html"
62 title="next chapter">SharedDevice Class</a></p>
150 </div>
151 <div>
152 <h4>Previous topic</h4>
153 <p class="topless"><a href="smb_SMBHandler.html"
154 title="previous chapter">SMbHandler Class</a></p>
155 </div>
156 <div>
157 <h4>Next topic</h4>
158 <p class="topless"><a href="smb_SharedDevice.html"
159 title="next chapter">SharedDevice Class</a></p>
160 </div>
63161 <div role="note" aria-label="source link">
64162 <h3>This Page</h3>
65163 <ul class="this-page-menu">
66 <li><a href="../_sources/api/smb_SMBProtocolFactory.txt"
164 <li><a href="../_sources/api/smb_SMBProtocolFactory.rst.txt"
67165 rel="nofollow">Show Source</a></li>
68166 </ul>
69167 </div>
70168 <div id="searchbox" style="display: none" role="search">
71 <h3>Quick search</h3>
169 <h3 id="searchlabel">Quick search</h3>
170 <div class="searchformwrapper">
72171 <form class="search" action="../search.html" method="get">
73 <input type="text" name="q" />
172 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
74173 <input type="submit" value="Go" />
75 <input type="hidden" name="check_keywords" value="yes" />
76 <input type="hidden" name="area" value="default" />
77174 </form>
78 <p class="searchtip" style="font-size: 90%">
79 Enter search terms or a module, class or function name.
80 </p>
175 </div>
81176 </div>
82 <script type="text/javascript">$('#searchbox').show(0);</script>
83 </div>
84 </div>
85
86 <div class="document">
87 <div class="documentwrapper">
88 <div class="bodywrapper">
89 <div class="body" role="main">
90
91 <div class="section" id="smbprotocolfactory-class">
92 <h1>SMBProtocolFactory Class<a class="headerlink" href="#smbprotocolfactory-class" title="Permalink to this headline">¶</a></h1>
93 <p>For those who want to utilize pysmb in Twisted framework, pysmb has a <em>smb.SMBProtocol.SMBProtocol</em> implementation.
94 In most cases, you do not need to touch or import the <em>SMBProtocol</em> directly. All the SMB functionalities are exposed in the <em>SMBProtocolFactory</em>.</p>
95 <dl class="docutils">
96 <dt>In your project,</dt>
97 <dd><ol class="first last arabic simple">
98 <li>Create a new class and subclass <em>SMBProtocolFactory</em>.</li>
99 <li>Override the <em>SMBProtocolFactory.onAuthOK</em> and <em>SMBProtocolFactory.onAuthFailed</em> instance methods to provide your own post-authenthentication handling.
100 Once <em>SMBProtocolFactory.onAuthOK</em> has been called by pymsb internals, your application is ready to communicate with the remote SMB/CIFS service through
101 the <em>SMBProtocolFactory</em> public methods such as <em>SMBProtocolFactory.storeFile</em>, <em>SMBProtocolFactory.retrieveFile</em>, etc.</li>
102 <li>When you want to disconnect from the remote SMB/CIFS server, just call <em>SMBProtocolFactory.closeConnection</em> method.</li>
103 </ol>
104 </dd>
105 </dl>
106 <p>All the <em>SMBProtocolFactory</em> public methods that provide file functionlities will return a <em>twisted.internet.defer.Deferred</em> instance.
107 A <a class="reference internal" href="smb_exceptions.html"><em>NotReadyError</em></a> exception is raised when the underlying SMB is not authenticated.
108 If the underlying SMB connection has been terminated, a <a class="reference internal" href="smb_exceptions.html"><em>NotConnectedError</em></a> exception is raised.</p>
109 <p>All the file operation methods in <em>SMBProtocolFactory</em> class accept a <em>timeout</em> parameter. This parameter specifies the time limit where pysmb will wait for the
110 entire file operation (except <em>storeFile</em> and <em>retrieveFile</em> methods) to complete. If the file operation fails to complete within the timeout period, the returned
111 <em>Deferred</em> instance&#8217;s <em>errback</em> method will be called with a <em>SMBTimeout</em> exception.</p>
112 <p>If you are interested in learning the results of the operation or to know when the operation has completed, you should
113 add a handling method to the returned <em>Deferred</em> instance via <em>Deferred.addCallback</em>. If the file operation fails, the <em>Deferred.errback</em> function will be called
114 with an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a>; on timeout, it will be called with a <a class="reference internal" href="smb_exceptions.html"><em>SMBTimeout</em></a>.</p>
115 <div class="section" id="example">
116 <h2>Example<a class="headerlink" href="#example" title="Permalink to this headline">¶</a></h2>
117 <p>The following illustrates a simple file retrieving implementation.:</p>
118 <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">tempfile</span>
119 <span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
120 <span class="kn">from</span> <span class="nn">smb.SMBProtocol</span> <span class="kn">import</span> <span class="n">SMBProtocolFactory</span>
121
122 <span class="k">class</span> <span class="nc">RetrieveFileFactory</span><span class="p">(</span><span class="n">SMBProtocolFactory</span><span class="p">):</span>
123
124 <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
125 <span class="n">SMBProtocolFactory</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
126
127 <span class="k">def</span> <span class="nf">fileRetrieved</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">write_result</span><span class="p">):</span>
128 <span class="n">file_obj</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">file_size</span> <span class="o">=</span> <span class="n">write_result</span>
129
130 <span class="c1"># Retrieved file contents are inside file_obj</span>
131 <span class="c1"># Do what you need with the file_obj and then close it</span>
132 <span class="c1"># Note that the file obj is positioned at the end-of-file,</span>
133 <span class="c1"># so you might need to perform a file_obj.seek() to if you</span>
134 <span class="c1"># need to read from the beginning</span>
135 <span class="n">file_obj</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
136
137 <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">loseConnection</span><span class="p">()</span>
138
139 <span class="k">def</span> <span class="nf">onAuthOK</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
140 <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">retrieveFile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">service</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">NamedTemporaryFile</span><span class="p">())</span>
141 <span class="n">d</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fileRetrieved</span><span class="p">)</span>
142 <span class="n">d</span><span class="o">.</span><span class="n">addErrback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">)</span>
143
144 <span class="k">def</span> <span class="nf">onAuthFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
145 <span class="k">print</span> <span class="s1">&#39;Auth failed&#39;</span>
146
147 <span class="c1"># There will be some mechanism to capture userID, password, client_machine_name, server_name and server_ip</span>
148 <span class="c1"># client_machine_name can be an arbitary ASCII string</span>
149 <span class="c1"># server_name should match the remote machine name, or else the connection will be rejected</span>
150 <span class="n">factory</span> <span class="o">=</span> <span class="n">RetrieveFileFactory</span><span class="p">(</span><span class="n">userID</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">client_machine_name</span><span class="p">,</span> <span class="n">server_name</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
151 <span class="n">factory</span><span class="o">.</span><span class="n">service</span> <span class="o">=</span> <span class="s1">&#39;smbtest&#39;</span>
152 <span class="n">factory</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="s1">&#39;/rfc1001.txt&#39;</span>
153 <span class="n">reactor</span><span class="o">.</span><span class="n">connectTCP</span><span class="p">(</span><span class="n">server_ip</span><span class="p">,</span> <span class="mi">139</span><span class="p">,</span> <span class="n">factory</span><span class="p">)</span>
154 </pre></div>
155 </div>
156 </div>
157 <div class="section" id="smb2-support">
158 <h2>SMB2 Support<a class="headerlink" href="#smb2-support" title="Permalink to this headline">¶</a></h2>
159 <p>Starting from pysmb 1.1.0, pysmb will utilize SMB2 protocol for communication if the remote SMB/CIFS service supports SMB2.
160 Otherwise, it will fallback automatically back to using SMB1 protocol.</p>
161 <p>To disable SMB2 protocol in pysmb, set the <em>SUPPORT_SMB2</em> flag in the <em>smb_structs</em> module to <em>False</em> before creating the <em>SMBProtocolFactory</em> instance.:</p>
162 <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">smb</span> <span class="kn">import</span> <span class="n">smb_structs</span>
163 <span class="n">smb_structs</span><span class="o">.</span><span class="n">SUPPORT_SMB2</span> <span class="o">=</span> <span class="bp">False</span>
164 </pre></div>
165 </div>
166 </div>
167 <div class="section" id="caveats">
168 <h2>Caveats<a class="headerlink" href="#caveats" title="Permalink to this headline">¶</a></h2>
169 <ul class="simple">
170 <li>A new factory instance must be created for each SMB connection to the remote SMB/CIFS service. Avoid reusing the same factory instance for more than one SMB connection.</li>
171 <li>The remote SMB/CIFS server usually imposes a limit of the number of concurrent file operations for each client. For example, to transfer a thousand files, you may need to setup a queue in your application and call <em>storeFile</em> or <em>retrieveFile</em> in batches.</li>
172 <li>The <em>timeout</em> parameter in the file operation methods are not precise; it is accurate to within 1 second interval, i.e. with a timeout of 0.5 sec, pysmb might raise
173 <em>SMBTimeout</em> exception after 1.5 sec.</li>
174 </ul>
175 <dl class="class">
176 <dt id="smb.SMBProtocol.SMBProtocolFactory">
177 <em class="property">class </em><code class="descclassname">smb.SMBProtocol.</code><code class="descname">SMBProtocolFactory</code><span class="sig-paren">(</span><em>username</em>, <em>password</em>, <em>my_name</em>, <em>remote_name</em>, <em>domain=''</em>, <em>use_ntlm_v2=True</em>, <em>sign_options=2</em>, <em>is_direct_tcp=False</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory" title="Permalink to this definition">¶</a></dt>
178 <dd><dl class="method">
179 <dt id="smb.SMBProtocol.SMBProtocolFactory.__init__">
180 <code class="descname">__init__</code><span class="sig-paren">(</span><em>username</em>, <em>password</em>, <em>my_name</em>, <em>remote_name</em>, <em>domain=''</em>, <em>use_ntlm_v2=True</em>, <em>sign_options=2</em>, <em>is_direct_tcp=False</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.__init__" title="Permalink to this definition">¶</a></dt>
181 <dd><p>Create a new SMBProtocolFactory instance. You will pass this instance to <em>reactor.connectTCP()</em> which will then instantiate the TCP connection to the remote SMB/CIFS server.
182 Note that the default TCP port for most SMB/CIFS servers using NetBIOS over TCP/IP is 139.
183 Some newer server installations might also support Direct hosting of SMB over TCP/IP; for these servers, the default TCP port is 445.</p>
184 <p><em>username</em> and <em>password</em> are the user credentials required to authenticate the underlying SMB connection with the remote server.
185 File operations can only be proceeded after the connection has been authenticated successfully.</p>
186 <table class="docutils field-list" frame="void" rules="none">
187 <col class="field-name" />
188 <col class="field-body" />
189 <tbody valign="top">
190 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
191 <li><strong>my_name</strong> (<em>string</em>) &#8211; The local NetBIOS machine name that will identify where this connection is originating from.
192 You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of <code class="docutils literal"><span class="pre">\/:*?&quot;;|+</span></code>.</li>
193 <li><strong>remote_name</strong> (<em>string</em>) &#8211; The NetBIOS machine name of the remote server.
194 On windows, you can find out the machine name by right-clicking on the &#8220;My Computer&#8221; and selecting &#8220;Properties&#8221;.
195 This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.</li>
196 <li><strong>domain</strong> (<em>string</em>) &#8211; The network domain. On windows, it is known as the workgroup. Usually, it is safe to leave this parameter as an empty string.</li>
197 <li><strong>use_ntlm_v2</strong> (<em>boolean</em>) &#8211; Indicates whether pysmb should be NTLMv1 or NTLMv2 authentication algorithm for authentication.
198 The choice of NTLMv1 and NTLMv2 is configured on the remote server, and there is no mechanism to auto-detect which algorithm has been configured.
199 Hence, we can only &#8220;guess&#8221; or try both algorithms.
200 On Sambda, Windows Vista and Windows 7, NTLMv2 is enabled by default. On Windows XP, we can use NTLMv1 before NTLMv2.</li>
201 <li><strong>sign_options</strong> (<em>int</em>) &#8211; Determines whether SMB messages will be signed. Default is <em>SIGN_WHEN_REQUIRED</em>.
202 If <em>SIGN_WHEN_REQUIRED</em> (value=2), SMB messages will only be signed when remote server requires signing.
203 If <em>SIGN_WHEN_SUPPORTED</em> (value=1), SMB messages will be signed when remote server supports signing but not requires signing.
204 If <em>SIGN_NEVER</em> (value=0), SMB messages will never be signed regardless of remote server&#8217;s configurations; access errors will occur if the remote server requires signing.</li>
205 <li><strong>is_direct_tcp</strong> (<em>boolean</em>) &#8211; Controls whether the NetBIOS over TCP/IP (is_direct_tcp=False) or the newer Direct hosting of SMB over TCP/IP (is_direct_tcp=True) will be used for the communication.
206 The default parameter is False which will use NetBIOS over TCP/IP for wider compatibility (TCP port: 139).</li>
207 </ul>
208 </td>
209 </tr>
210 </tbody>
211 </table>
212 </dd></dl>
213
214 <dl class="method">
215 <dt id="smb.SMBProtocol.SMBProtocolFactory.closeConnection">
216 <code class="descname">closeConnection</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.closeConnection"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.closeConnection" title="Permalink to this definition">¶</a></dt>
217 <dd><p>Disconnect from the remote SMB/CIFS server. The TCP connection will be closed at the earliest opportunity after this method returns.</p>
218 <table class="docutils field-list" frame="void" rules="none">
219 <col class="field-name" />
220 <col class="field-body" />
221 <tbody valign="top">
222 <tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">None</td>
223 </tr>
224 </tbody>
225 </table>
226 </dd></dl>
227
228 <dl class="method">
229 <dt id="smb.SMBProtocol.SMBProtocolFactory.createDirectory">
230 <code class="descname">createDirectory</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.createDirectory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.createDirectory" title="Permalink to this definition">¶</a></dt>
231 <dd><p>Creates a new directory <em>path</em> on the <em>service_name</em>.</p>
232 <table class="docutils field-list" frame="void" rules="none">
233 <col class="field-name" />
234 <col class="field-body" />
235 <tbody valign="top">
236 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
237 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; Contains the name of the shared folder.</li>
238 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; The path of the new folder (relative to) the shared folder.
239 If the path contains non-English characters, an unicode string must be used to pass in the path.</li>
240 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance&#8217;s <em>errback</em> method.</li>
241 </ul>
242 </td>
243 </tr>
244 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with the <em>path</em> parameter.</p>
245 </td>
246 </tr>
247 </tbody>
248 </table>
249 </dd></dl>
250
251 <dl class="method">
252 <dt id="smb.SMBProtocol.SMBProtocolFactory.deleteDirectory">
253 <code class="descname">deleteDirectory</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.deleteDirectory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.deleteDirectory" title="Permalink to this definition">¶</a></dt>
254 <dd><p>Delete the empty folder at <em>path</em> on <em>service_name</em></p>
255 <table class="docutils field-list" frame="void" rules="none">
256 <col class="field-name" />
257 <col class="field-body" />
258 <tbody valign="top">
259 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
260 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; Contains the name of the shared folder.</li>
261 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; The path of the to-be-deleted folder (relative to) the shared folder.
262 If the path contains non-English characters, an unicode string must be used to pass in the path.</li>
263 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance&#8217;s <em>errback</em> method.</li>
264 </ul>
265 </td>
266 </tr>
267 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with the <em>path</em> parameter.</p>
268 </td>
269 </tr>
270 </tbody>
271 </table>
272 </dd></dl>
273
274 <dl class="method">
275 <dt id="smb.SMBProtocol.SMBProtocolFactory.deleteFiles">
276 <code class="descname">deleteFiles</code><span class="sig-paren">(</span><em>service_name</em>, <em>path_file_pattern</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.deleteFiles"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.deleteFiles" title="Permalink to this definition">¶</a></dt>
277 <dd><p>Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.</p>
278 <table class="docutils field-list" frame="void" rules="none">
279 <col class="field-name" />
280 <col class="field-body" />
281 <tbody valign="top">
282 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
283 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; Contains the name of the shared folder.</li>
284 <li><strong>path_file_pattern</strong> (<em>string/unicode</em>) &#8211; The pathname of the file(s) to be deleted, relative to the service_name.
285 Wildcards may be used in th filename component of the path.
286 If your path/filename contains non-English characters, you must pass in an unicode string.</li>
287 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance&#8217;s <em>errback</em> method.</li>
288 </ul>
289 </td>
290 </tr>
291 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with the <em>path_file_pattern</em> parameter.</p>
292 </td>
293 </tr>
294 </tbody>
295 </table>
296 </dd></dl>
297
298 <dl class="method">
299 <dt id="smb.SMBProtocol.SMBProtocolFactory.echo">
300 <code class="descname">echo</code><span class="sig-paren">(</span><em>data</em>, <em>timeout=10</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.echo"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.echo" title="Permalink to this definition">¶</a></dt>
301 <dd><p>Send an echo command containing <em>data</em> to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same <em>data</em>.</p>
302 <table class="docutils field-list" frame="void" rules="none">
303 <col class="field-name" />
304 <col class="field-body" />
305 <tbody valign="top">
306 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
307 <li><strong>data</strong> (<em>string</em>) &#8211; Data to send to the remote server.</li>
308 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance&#8217;s <em>errback</em> method.</li>
309 </ul>
310 </td>
311 </tr>
312 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with the <em>data</em> parameter.</p>
313 </td>
314 </tr>
315 </tbody>
316 </table>
317 </dd></dl>
318
319 <dl class="method">
320 <dt id="smb.SMBProtocol.SMBProtocolFactory.getAttributes">
321 <code class="descname">getAttributes</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.getAttributes"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.getAttributes" title="Permalink to this definition">¶</a></dt>
322 <dd><p>Retrieve information about the file at <em>path</em> on the <em>service_name</em>.</p>
323 <table class="docutils field-list" frame="void" rules="none">
324 <col class="field-name" />
325 <col class="field-body" />
326 <tbody valign="top">
327 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
328 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
329 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be raised.</li>
330 </ul>
331 </td>
332 </tr>
333 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a <a class="reference internal" href="smb_SharedFile.html"><em>smb.base.SharedFile</em></a> instance containing the attributes of the file.</p>
334 </td>
335 </tr>
336 </tbody>
337 </table>
338 </dd></dl>
339
340 <dl class="method">
341 <dt id="smb.SMBProtocol.SMBProtocolFactory.listPath">
342 <code class="descname">listPath</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>search=55</em>, <em>pattern='*'</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.listPath"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.listPath" title="Permalink to this definition">¶</a></dt>
343 <dd><p>Retrieve a directory listing of files/folders at <em>path</em></p>
344 <table class="docutils field-list" frame="void" rules="none">
345 <col class="field-name" />
346 <col class="field-body" />
347 <tbody valign="top">
348 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
349 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
350 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; path relative to the <em>service_name</em> where we are interested to learn about its files/sub-folders.</li>
351 <li><strong>search</strong> (<em>integer</em>) &#8211; integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py).
352 The default <em>search</em> value will query for all read-only, hidden, system, archive files and directories.</li>
353 <li><strong>pattern</strong> (<em>string/unicode</em>) &#8211; the filter to apply to the results before returning to the client.</li>
354 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance&#8217;s <em>errback</em> method.</li>
355 </ul>
356 </td>
357 </tr>
358 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a list of <a class="reference internal" href="smb_SharedFile.html"><em>smb.base.SharedFile</em></a> instances.</p>
359 </td>
360 </tr>
361 </tbody>
362 </table>
363 </dd></dl>
364
365 <dl class="method">
366 <dt id="smb.SMBProtocol.SMBProtocolFactory.listShares">
367 <code class="descname">listShares</code><span class="sig-paren">(</span><em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.listShares"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.listShares" title="Permalink to this definition">¶</a></dt>
368 <dd><p>Retrieve a list of shared resources on remote server.</p>
369 <table class="docutils field-list" frame="void" rules="none">
370 <col class="field-name" />
371 <col class="field-body" />
372 <tbody valign="top">
373 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance&#8217;s <em>errback</em> method.</td>
374 </tr>
375 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a list of <a class="reference internal" href="smb_SharedDevice.html"><em>smb.base.SharedDevice</em></a> instances.</td>
376 </tr>
377 </tbody>
378 </table>
379 </dd></dl>
380
381 <dl class="method">
382 <dt id="smb.SMBProtocol.SMBProtocolFactory.listSnapshots">
383 <code class="descname">listSnapshots</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.listSnapshots"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.listSnapshots" title="Permalink to this definition">¶</a></dt>
384 <dd><p>Retrieve a list of available snapshots (a.k.a. shadow copies) for <em>path</em>.</p>
385 <p>Note that snapshot features are only supported on Windows Vista Business, Enterprise and Ultimate, and on all Windows 7 editions.</p>
386 <table class="docutils field-list" frame="void" rules="none">
387 <col class="field-name" />
388 <col class="field-body" />
389 <tbody valign="top">
390 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
391 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
392 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; path relative to the <em>service_name</em> where we are interested in the list of available snapshots</li>
393 </ul>
394 </td>
395 </tr>
396 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a list of python <em>datetime.DateTime</em>
397 instances in GMT/UTC time zone</p>
398 </td>
399 </tr>
400 </tbody>
401 </table>
402 </dd></dl>
403
404 <dl class="method">
405 <dt id="smb.SMBProtocol.SMBProtocolFactory.onAuthFailed">
406 <code class="descname">onAuthFailed</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.onAuthFailed"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.onAuthFailed" title="Permalink to this definition">¶</a></dt>
407 <dd><p>Override this method in your <em>SMBProtocolFactory</em> subclass to add in post-authentication handling.
408 This method will be called when the server has replied that the SMB connection has been successfully authenticated.</p>
409 <dl class="docutils">
410 <dt>If you want to retry authenticating from this method,</dt>
411 <dd><ol class="first last arabic simple">
412 <li>Disconnect the underlying SMB connection (call <code class="docutils literal"><span class="pre">self.instance.transport.loseConnection()</span></code>)</li>
413 <li>Create a new SMBProtocolFactory subclass instance with different user credientials or different NTLM algorithm flag.</li>
414 <li>Call <code class="docutils literal"><span class="pre">reactor.connectTCP</span></code> with the new instance to re-establish the SMB connection</li>
415 </ol>
416 </dd>
417 </dl>
418 </dd></dl>
419
420 <dl class="method">
421 <dt id="smb.SMBProtocol.SMBProtocolFactory.onAuthOK">
422 <code class="descname">onAuthOK</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.onAuthOK"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.onAuthOK" title="Permalink to this definition">¶</a></dt>
423 <dd><p>Override this method in your <em>SMBProtocolFactory</em> subclass to add in post-authentication handling.
424 This method will be called when the server has replied that the SMB connection has been successfully authenticated.
425 File operations can proceed when this method has been called.</p>
426 </dd></dl>
427
428 <dl class="method">
429 <dt id="smb.SMBProtocol.SMBProtocolFactory.rename">
430 <code class="descname">rename</code><span class="sig-paren">(</span><em>service_name</em>, <em>old_path</em>, <em>new_path</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.rename"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.rename" title="Permalink to this definition">¶</a></dt>
431 <dd><p>Rename a file or folder at <em>old_path</em> to <em>new_path</em> shared at <em>service_name</em>. Note that this method cannot be used to rename file/folder across different shared folders</p>
432 <p><em>old_path</em> and <em>new_path</em> are string/unicode referring to the old and new path of the renamed resources (relative to) the shared folder.
433 If the path contains non-English characters, an unicode string must be used to pass in the path.</p>
434 <table class="docutils field-list" frame="void" rules="none">
435 <col class="field-name" />
436 <col class="field-body" />
437 <tbody valign="top">
438 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
439 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; Contains the name of the shared folder.</li>
440 <li><strong>timeout</strong> (<em>integer/float</em>) &#8211; Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance&#8217;s <em>errback</em> method.</li>
441 </ul>
442 </td>
443 </tr>
444 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a 2-element tuple of ( <em>old_path</em>, <em>new_path</em> ).</p>
445 </td>
446 </tr>
447 </tbody>
448 </table>
449 </dd></dl>
450
451 <dl class="method">
452 <dt id="smb.SMBProtocol.SMBProtocolFactory.retrieveFile">
453 <code class="descname">retrieveFile</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.retrieveFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.retrieveFile" title="Permalink to this definition">¶</a></dt>
454 <dd><p>Retrieve the contents of the file at <em>path</em> on the <em>service_name</em> and write these contents to the provided <em>file_obj</em>.</p>
455 <p>Use <em>retrieveFileFromOffset()</em> method if you need to specify the offset to read from the remote <em>path</em> and/or the maximum number of bytes to write to the <em>file_obj</em>.</p>
456 <p>The meaning of the <em>timeout</em> parameter will be different from other file operation methods. As the downloaded file usually exceeeds the maximum size
457 of each SMB/CIFS data message, it will be packetized into a series of request messages (each message will request about about 60kBytes).
458 The <em>timeout</em> parameter is an integer/float value that specifies the timeout interval for these individual SMB/CIFS message to be transmitted and downloaded from the remote SMB/CIFS server.</p>
459 <table class="docutils field-list" frame="void" rules="none">
460 <col class="field-name" />
461 <col class="field-body" />
462 <tbody valign="top">
463 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
464 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
465 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be called in the returned <em>Deferred</em> errback.</li>
466 <li><strong>file_obj</strong> &#8211; A file-like object that has a <em>write</em> method. Data will be written continuously to <em>file_obj</em> until EOF is received from the remote service.</li>
467 </ul>
468 </td>
469 </tr>
470 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a 3-element tuple of ( <em>file_obj</em>, file attributes of the file on server, number of bytes written to <em>file_obj</em> ).
471 The file attributes is an integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py)</p>
472 </td>
473 </tr>
474 </tbody>
475 </table>
476 </dd></dl>
477
478 <dl class="method">
479 <dt id="smb.SMBProtocol.SMBProtocolFactory.retrieveFileFromOffset">
480 <code class="descname">retrieveFileFromOffset</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>offset=0L</em>, <em>max_length=-1L</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.retrieveFileFromOffset"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.retrieveFileFromOffset" title="Permalink to this definition">¶</a></dt>
481 <dd><p>Retrieve the contents of the file at <em>path</em> on the <em>service_name</em> and write these contents to the provided <em>file_obj</em>.</p>
482 <p>The meaning of the <em>timeout</em> parameter will be different from other file operation methods. As the downloaded file usually exceeeds the maximum size
483 of each SMB/CIFS data message, it will be packetized into a series of request messages (each message will request about about 60kBytes).
484 The <em>timeout</em> parameter is an integer/float value that specifies the timeout interval for these individual SMB/CIFS message to be transmitted and downloaded from the remote SMB/CIFS server.</p>
485 <table class="docutils field-list" frame="void" rules="none">
486 <col class="field-name" />
487 <col class="field-body" />
488 <tbody valign="top">
489 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
490 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
491 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be called in the returned <em>Deferred</em> errback.</li>
492 <li><strong>file_obj</strong> &#8211; A file-like object that has a <em>write</em> method. Data will be written continuously to <em>file_obj</em> until EOF is received from the remote service.</li>
493 <li><strong>offset</strong> (<em>integer/long</em>) &#8211; the offset in the remote <em>path</em> where the first byte will be read and written to <em>file_obj</em>. Must be either zero or a positive integer/long value.</li>
494 <li><strong>max_length</strong> (<em>integer/long</em>) &#8211; maximum number of bytes to read from the remote <em>path</em> and write to the <em>file_obj</em>. Specify a negative value to read from <em>offset</em> to the EOF.
495 If zero, the <em>Deferred</em> callback is invoked immediately after the file is opened successfully for reading.</li>
496 </ul>
497 </td>
498 </tr>
499 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a 3-element tuple of ( <em>file_obj</em>, file attributes of the file on server, number of bytes written to <em>file_obj</em> ).
500 The file attributes is an integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py)</p>
501 </td>
502 </tr>
503 </tbody>
504 </table>
505 </dd></dl>
506
507 <dl class="method">
508 <dt id="smb.SMBProtocol.SMBProtocolFactory.storeFile">
509 <code class="descname">storeFile</code><span class="sig-paren">(</span><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>timeout=30</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.storeFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.storeFile" title="Permalink to this definition">¶</a></dt>
510 <dd><p>Store the contents of the <em>file_obj</em> at <em>path</em> on the <em>service_name</em>.</p>
511 <p>The meaning of the <em>timeout</em> parameter will be different from other file operation methods. As the uploaded file usually exceeeds the maximum size
512 of each SMB/CIFS data message, it will be packetized into a series of messages (usually about 60kBytes).
513 The <em>timeout</em> parameter is an integer/float value that specifies the timeout interval for these individual SMB/CIFS message to be transmitted and acknowledged
514 by the remote SMB/CIFS server.</p>
515 <table class="docutils field-list" frame="void" rules="none">
516 <col class="field-name" />
517 <col class="field-body" />
518 <tbody valign="top">
519 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
520 <li><strong>service_name</strong> (<em>string/unicode</em>) &#8211; the name of the shared folder for the <em>path</em></li>
521 <li><strong>path</strong> (<em>string/unicode</em>) &#8211; Path of the file on the remote server. If the file at <em>path</em> does not exist, it will be created. Otherwise, it will be overwritten.
522 If the <em>path</em> refers to a folder or the file cannot be opened for writing, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be called in the returned <em>Deferred</em> errback.</li>
523 <li><strong>file_obj</strong> &#8211; A file-like object that has a <em>read</em> method. Data will read continuously from <em>file_obj</em> until EOF.</li>
524 </ul>
525 </td>
526 </tr>
527 <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a 2-element tuple of ( <em>file_obj</em>, number of bytes uploaded ).</p>
528 </td>
529 </tr>
530 </tbody>
531 </table>
532 </dd></dl>
533
534 <dl class="attribute">
535 <dt id="smb.SMBProtocol.SMBProtocolFactory.SIGN_NEVER">
536 <code class="descname">SIGN_NEVER</code><em class="property"> = 0</em><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.SIGN_NEVER" title="Permalink to this definition">¶</a></dt>
537 <dd><p>SMB messages will never be signed regardless of remote server&#8217;s configurations; access errors will occur if the remote server requires signing.</p>
538 </dd></dl>
539
540 <dl class="attribute">
541 <dt id="smb.SMBProtocol.SMBProtocolFactory.SIGN_WHEN_REQUIRED">
542 <code class="descname">SIGN_WHEN_REQUIRED</code><em class="property"> = 2</em><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.SIGN_WHEN_REQUIRED" title="Permalink to this definition">¶</a></dt>
543 <dd><p>SMB messages will only be signed when remote server requires signing.</p>
544 </dd></dl>
545
546 <dl class="attribute">
547 <dt id="smb.SMBProtocol.SMBProtocolFactory.SIGN_WHEN_SUPPORTED">
548 <code class="descname">SIGN_WHEN_SUPPORTED</code><em class="property"> = 1</em><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.SIGN_WHEN_SUPPORTED" title="Permalink to this definition">¶</a></dt>
549 <dd><p>SMB messages will be signed when remote server supports signing but not requires signing.</p>
550 </dd></dl>
551
552 <dl class="attribute">
553 <dt id="smb.SMBProtocol.SMBProtocolFactory.instance">
554 <code class="descname">instance</code><em class="property"> = None</em><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.instance" title="Permalink to this definition">¶</a></dt>
555 <dd><p>The single SMBProtocol instance for each SMBProtocolFactory instance. Usually, you should not need to touch this attribute directly.</p>
556 </dd></dl>
557
558 <dl class="attribute">
559 <dt id="smb.SMBProtocol.SMBProtocolFactory.isReady">
560 <code class="descname">isReady</code><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.isReady" title="Permalink to this definition">¶</a></dt>
561 <dd><p>A convenient property to return True if the underlying SMB connection has connected to remote server, has successfully authenticated itself and is ready for file operations.</p>
562 </dd></dl>
563
564 <dl class="attribute">
565 <dt id="smb.SMBProtocol.SMBProtocolFactory.isUsingSMB2">
566 <code class="descname">isUsingSMB2</code><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.isUsingSMB2" title="Permalink to this definition">¶</a></dt>
567 <dd><p>A convenient property to return True if the underlying SMB connection is using SMB2 protocol.</p>
568 </dd></dl>
569
570 </dd></dl>
571
572 </div>
573 </div>
574
575
576 </div>
177 <script>document.getElementById('searchbox').style.display = "block"</script>
577178 </div>
578179 </div>
579180 <div class="clearer"></div>
585186 <a href="../genindex.html" title="General Index"
586187 >index</a></li>
587188 <li class="right" >
189 <a href="../py-modindex.html" title="Python Module Index"
190 >modules</a> |</li>
191 <li class="right" >
588192 <a href="smb_SharedDevice.html" title="SharedDevice Class"
589193 >next</a> |</li>
590194 <li class="right" >
591195 <a href="smb_SMBHandler.html" title="SMbHandler Class"
592196 >previous</a> |</li>
593 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
197 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
198 <li class="nav-item nav-item-this"><a href="">SMBProtocolFactory Class</a></li>
594199 </ul>
595200 </div>
596201 <div class="footer" role="contentinfo">
597 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
598 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
202 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
203 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
599204 </div>
600205 </body>
601206 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
20
1 <!DOCTYPE html>
32
4 <html xmlns="http://www.w3.org/1999/xhtml">
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>SharedDevice Class &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../_static/jquery.js"></script>
23 <script type="text/javascript" src="../_static/underscore.js"></script>
24 <script type="text/javascript" src="../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../index.html" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>SharedDevice Class &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
11 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
12 <script src="../_static/jquery.js"></script>
13 <script src="../_static/underscore.js"></script>
14 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="../_static/doctools.js"></script>
16 <link rel="index" title="Index" href="../genindex.html" />
17 <link rel="search" title="Search" href="../search.html" />
2618 <link rel="next" title="SharedFile Class" href="smb_SharedFile.html" />
2719 <link rel="prev" title="SMBProtocolFactory Class" href="smb_SMBProtocolFactory.html" />
28 </head>
29 <body role="document">
20 </head><body>
3021 <div class="related" role="navigation" aria-label="related navigation">
3122 <h3>Navigation</h3>
3223 <ul>
3425 <a href="../genindex.html" title="General Index"
3526 accesskey="I">index</a></li>
3627 <li class="right" >
28 <a href="../py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
3731 <a href="smb_SharedFile.html" title="SharedFile Class"
3832 accesskey="N">next</a> |</li>
3933 <li class="right" >
4034 <a href="smb_SMBProtocolFactory.html" title="SMBProtocolFactory Class"
4135 accesskey="P">previous</a> |</li>
42 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">SharedDevice Class</a></li>
4338 </ul>
44 </div>
45 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
46 <div class="sphinxsidebarwrapper">
47 <h4>Previous topic</h4>
48 <p class="topless"><a href="smb_SMBProtocolFactory.html"
49 title="previous chapter">SMBProtocolFactory Class</a></p>
50 <h4>Next topic</h4>
51 <p class="topless"><a href="smb_SharedFile.html"
52 title="next chapter">SharedFile Class</a></p>
53 <div role="note" aria-label="source link">
54 <h3>This Page</h3>
55 <ul class="this-page-menu">
56 <li><a href="../_sources/api/smb_SharedDevice.txt"
57 rel="nofollow">Show Source</a></li>
58 </ul>
59 </div>
60 <div id="searchbox" style="display: none" role="search">
61 <h3>Quick search</h3>
62 <form class="search" action="../search.html" method="get">
63 <input type="text" name="q" />
64 <input type="submit" value="Go" />
65 <input type="hidden" name="check_keywords" value="yes" />
66 <input type="hidden" name="area" value="default" />
67 </form>
68 <p class="searchtip" style="font-size: 90%">
69 Enter search terms or a module, class or function name.
70 </p>
71 </div>
72 <script type="text/javascript">$('#searchbox').show(0);</script>
73 </div>
74 </div>
39 </div>
7540
7641 <div class="document">
7742 <div class="documentwrapper">
7843 <div class="bodywrapper">
7944 <div class="body" role="main">
8045
81 <div class="section" id="shareddevice-class">
82 <h1>SharedDevice Class<a class="headerlink" href="#shareddevice-class" title="Permalink to this headline">¶</a></h1>
83 <dl class="class">
84 <dt id="smb.base.SharedDevice">
85 <em class="property">class </em><code class="descclassname">smb.base.</code><code class="descname">SharedDevice</code><span class="sig-paren">(</span><em>type</em>, <em>name</em>, <em>comments</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/base.html#SharedDevice"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SharedDevice" title="Permalink to this definition">¶</a></dt>
46 <section id="shareddevice-class">
47 <h1>SharedDevice Class<a class="headerlink" href="#shareddevice-class" title="Permalink to this heading">¶</a></h1>
48 <dl class="py class">
49 <dt class="sig sig-object py" id="smb.base.SharedDevice">
50 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.base.</span></span><span class="sig-name descname"><span class="pre">SharedDevice</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">type</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comments</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/base.html#SharedDevice"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.base.SharedDevice" title="Permalink to this definition">¶</a></dt>
8651 <dd><p>Contains information about a single shared device on the remote server.</p>
87 <dl class="attribute">
88 <dt id="smb.base.SharedDevice.comments">
89 <code class="descname">comments</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedDevice.comments" title="Permalink to this definition">¶</a></dt>
52 <p>The following attributes are available:</p>
53 <ul class="simple">
54 <li><p>name : An unicode string containing the name of the shared device</p></li>
55 <li><p>comments : An unicode string containing the user description of the shared device</p></li>
56 </ul>
57 <dl class="py attribute">
58 <dt class="sig sig-object py" id="smb.base.SharedDevice.comments">
59 <span class="sig-name descname"><span class="pre">comments</span></span><a class="headerlink" href="#smb.base.SharedDevice.comments" title="Permalink to this definition">¶</a></dt>
9060 <dd><p>An unicode string containing the user description of the shared device</p>
9161 </dd></dl>
9262
93 <dl class="attribute">
94 <dt id="smb.base.SharedDevice.isSpecial">
95 <code class="descname">isSpecial</code><a class="headerlink" href="#smb.base.SharedDevice.isSpecial" title="Permalink to this definition">¶</a></dt>
63 <dl class="py property">
64 <dt class="sig sig-object py" id="smb.base.SharedDevice.isSpecial">
65 <em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">isSpecial</span></span><a class="headerlink" href="#smb.base.SharedDevice.isSpecial" title="Permalink to this definition">¶</a></dt>
9666 <dd><p>Returns True if this shared device is a special share reserved for interprocess communication (IPC$)
9767 or remote administration of the server (ADMIN$). Can also refer to administrative shares such as
9868 C$, D$, E$, and so forth</p>
9969 </dd></dl>
10070
101 <dl class="attribute">
102 <dt id="smb.base.SharedDevice.isTemporary">
103 <code class="descname">isTemporary</code><a class="headerlink" href="#smb.base.SharedDevice.isTemporary" title="Permalink to this definition">¶</a></dt>
71 <dl class="py property">
72 <dt class="sig sig-object py" id="smb.base.SharedDevice.isTemporary">
73 <em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">isTemporary</span></span><a class="headerlink" href="#smb.base.SharedDevice.isTemporary" title="Permalink to this definition">¶</a></dt>
10474 <dd><p>Returns True if this is a temporary share that is not persisted for creation each time the file server initializes.</p>
10575 </dd></dl>
10676
107 <dl class="attribute">
108 <dt id="smb.base.SharedDevice.name">
109 <code class="descname">name</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedDevice.name" title="Permalink to this definition">¶</a></dt>
77 <dl class="py attribute">
78 <dt class="sig sig-object py" id="smb.base.SharedDevice.name">
79 <span class="sig-name descname"><span class="pre">name</span></span><a class="headerlink" href="#smb.base.SharedDevice.name" title="Permalink to this definition">¶</a></dt>
11080 <dd><p>An unicode string containing the name of the shared device</p>
11181 </dd></dl>
11282
113 <dl class="attribute">
114 <dt id="smb.base.SharedDevice.type">
115 <code class="descname">type</code><a class="headerlink" href="#smb.base.SharedDevice.type" title="Permalink to this definition">¶</a></dt>
116 <dd><dl class="docutils">
117 <dt>Returns one of the following integral constants.</dt>
118 <dd><ul class="first last simple">
119 <li>SharedDevice.DISK_TREE</li>
120 <li>SharedDevice.PRINT_QUEUE</li>
121 <li>SharedDevice.COMM_DEVICE</li>
122 <li>SharedDevice.IPC</li>
83 <dl class="py property">
84 <dt class="sig sig-object py" id="smb.base.SharedDevice.type">
85 <em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">type</span></span><a class="headerlink" href="#smb.base.SharedDevice.type" title="Permalink to this definition">¶</a></dt>
86 <dd><dl class="simple">
87 <dt>Returns one of the following integral constants.</dt><dd><ul class="simple">
88 <li><p>SharedDevice.DISK_TREE</p></li>
89 <li><p>SharedDevice.PRINT_QUEUE</p></li>
90 <li><p>SharedDevice.COMM_DEVICE</p></li>
91 <li><p>SharedDevice.IPC</p></li>
12392 </ul>
12493 </dd>
12594 </dl>
12796
12897 </dd></dl>
12998
130 </div>
99 </section>
131100
132101
102 <div class="clearer"></div>
133103 </div>
104 </div>
105 </div>
106 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
107 <div class="sphinxsidebarwrapper">
108 <div>
109 <h4>Previous topic</h4>
110 <p class="topless"><a href="smb_SMBProtocolFactory.html"
111 title="previous chapter">SMBProtocolFactory Class</a></p>
112 </div>
113 <div>
114 <h4>Next topic</h4>
115 <p class="topless"><a href="smb_SharedFile.html"
116 title="next chapter">SharedFile Class</a></p>
117 </div>
118 <div role="note" aria-label="source link">
119 <h3>This Page</h3>
120 <ul class="this-page-menu">
121 <li><a href="../_sources/api/smb_SharedDevice.rst.txt"
122 rel="nofollow">Show Source</a></li>
123 </ul>
124 </div>
125 <div id="searchbox" style="display: none" role="search">
126 <h3 id="searchlabel">Quick search</h3>
127 <div class="searchformwrapper">
128 <form class="search" action="../search.html" method="get">
129 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
130 <input type="submit" value="Go" />
131 </form>
132 </div>
133 </div>
134 <script>document.getElementById('searchbox').style.display = "block"</script>
134135 </div>
135136 </div>
136137 <div class="clearer"></div>
142143 <a href="../genindex.html" title="General Index"
143144 >index</a></li>
144145 <li class="right" >
146 <a href="../py-modindex.html" title="Python Module Index"
147 >modules</a> |</li>
148 <li class="right" >
145149 <a href="smb_SharedFile.html" title="SharedFile Class"
146150 >next</a> |</li>
147151 <li class="right" >
148152 <a href="smb_SMBProtocolFactory.html" title="SMBProtocolFactory Class"
149153 >previous</a> |</li>
150 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
154 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
155 <li class="nav-item nav-item-this"><a href="">SharedDevice Class</a></li>
151156 </ul>
152157 </div>
153158 <div class="footer" role="contentinfo">
154 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
155 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
159 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
160 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
156161 </div>
157162 </body>
158163 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>SharedFile Class &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../_static/jquery.js"></script>
23 <script type="text/javascript" src="../_static/underscore.js"></script>
24 <script type="text/javascript" src="../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../index.html" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>SharedFile Class &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
11 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
12 <script src="../_static/jquery.js"></script>
13 <script src="../_static/underscore.js"></script>
14 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="../_static/doctools.js"></script>
16 <link rel="index" title="Index" href="../genindex.html" />
17 <link rel="search" title="Search" href="../search.html" />
2618 <link rel="next" title="SMB Exceptions" href="smb_exceptions.html" />
2719 <link rel="prev" title="SharedDevice Class" href="smb_SharedDevice.html" />
28 </head>
29 <body role="document">
20 </head><body>
3021 <div class="related" role="navigation" aria-label="related navigation">
3122 <h3>Navigation</h3>
3223 <ul>
3425 <a href="../genindex.html" title="General Index"
3526 accesskey="I">index</a></li>
3627 <li class="right" >
28 <a href="../py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
3731 <a href="smb_exceptions.html" title="SMB Exceptions"
3832 accesskey="N">next</a> |</li>
3933 <li class="right" >
4034 <a href="smb_SharedDevice.html" title="SharedDevice Class"
4135 accesskey="P">previous</a> |</li>
42 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">SharedFile Class</a></li>
4338 </ul>
44 </div>
45 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
46 <div class="sphinxsidebarwrapper">
47 <h4>Previous topic</h4>
48 <p class="topless"><a href="smb_SharedDevice.html"
49 title="previous chapter">SharedDevice Class</a></p>
50 <h4>Next topic</h4>
51 <p class="topless"><a href="smb_exceptions.html"
52 title="next chapter">SMB Exceptions</a></p>
53 <div role="note" aria-label="source link">
54 <h3>This Page</h3>
55 <ul class="this-page-menu">
56 <li><a href="../_sources/api/smb_SharedFile.txt"
57 rel="nofollow">Show Source</a></li>
58 </ul>
59 </div>
60 <div id="searchbox" style="display: none" role="search">
61 <h3>Quick search</h3>
62 <form class="search" action="../search.html" method="get">
63 <input type="text" name="q" />
64 <input type="submit" value="Go" />
65 <input type="hidden" name="check_keywords" value="yes" />
66 <input type="hidden" name="area" value="default" />
67 </form>
68 <p class="searchtip" style="font-size: 90%">
69 Enter search terms or a module, class or function name.
70 </p>
71 </div>
72 <script type="text/javascript">$('#searchbox').show(0);</script>
73 </div>
74 </div>
39 </div>
7540
7641 <div class="document">
7742 <div class="documentwrapper">
7843 <div class="bodywrapper">
7944 <div class="body" role="main">
8045
81 <div class="section" id="sharedfile-class">
82 <h1>SharedFile Class<a class="headerlink" href="#sharedfile-class" title="Permalink to this headline">¶</a></h1>
83 <dl class="class">
84 <dt id="smb.base.SharedFile">
85 <em class="property">class </em><code class="descclassname">smb.base.</code><code class="descname">SharedFile</code><span class="sig-paren">(</span><em>create_time</em>, <em>last_access_time</em>, <em>last_write_time</em>, <em>last_attr_change_time</em>, <em>file_size</em>, <em>alloc_size</em>, <em>file_attributes</em>, <em>short_name</em>, <em>filename</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/base.html#SharedFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SharedFile" title="Permalink to this definition">¶</a></dt>
46 <section id="sharedfile-class">
47 <h1>SharedFile Class<a class="headerlink" href="#sharedfile-class" title="Permalink to this heading">¶</a></h1>
48 <dl class="py class">
49 <dt class="sig sig-object py" id="smb.base.SharedFile">
50 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.base.</span></span><span class="sig-name descname"><span class="pre">SharedFile</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">create_time</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">last_access_time</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">last_write_time</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">last_attr_change_time</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">file_size</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">alloc_size</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">file_attributes</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">short_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">filename</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">file_id</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/base.html#SharedFile"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.base.SharedFile" title="Permalink to this definition">¶</a></dt>
8651 <dd><p>Contain information about a file/folder entry that is shared on the shared device.</p>
8752 <p>As an application developer, you should not need to instantiate a <em>SharedFile</em> instance directly in your application.
88 These <em>SharedFile</em> instances are usually returned via a call to <em>listPath</em> method in <a class="reference internal" href="smb_SMBProtocolFactory.html"><em>smb.SMBProtocol.SMBProtocolFactory</em></a>.</p>
53 These <em>SharedFile</em> instances are usually returned via a call to <em>listPath</em> method in <a class="reference internal" href="smb_SMBProtocolFactory.html"><span class="doc">smb.SMBProtocol.SMBProtocolFactory</span></a>.</p>
8954 <p>If you encounter <em>SharedFile</em> instance where its short_name attribute is empty but the filename attribute contains a short name which does not correspond
9055 to any files/folders on your remote shared device, it could be that the original filename on the file/folder entry on the shared device contains
91 one of these prohibited characters: &#8220;/[]:+|&lt;&gt;=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).</p>
92 <dl class="attribute">
93 <dt id="smb.base.SharedFile.alloc_size">
94 <code class="descname">alloc_size</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.alloc_size" title="Permalink to this definition">¶</a></dt>
56 one of these prohibited characters: “/[]:+|&lt;&gt;=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).</p>
57 <p>The following attributes are available:</p>
58 <ul class="simple">
59 <li><p>create_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server</p></li>
60 <li><p>last_access_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server</p></li>
61 <li><p>last_write_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server</p></li>
62 <li><p>last_attr_change_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server</p></li>
63 <li><p>file_size : File size in number of bytes</p></li>
64 <li><p>alloc_size : Total number of bytes allocated to store this file</p></li>
65 <li><p>file_attributes : A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3. You can perform bit-wise tests to determine the status of the file using the ATTR_xxx constants in smb_constants.py.</p></li>
66 <li><p>short_name : Unicode string containing the short name of this file (usually in 8.3 notation)</p></li>
67 <li><p>filename : Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.</p></li>
68 <li><p>file_id : Long value representing the file reference number for the file. If the remote system does not support this field, this field will be None or 0. See [MS-FSCC]: 2.4.17</p></li>
69 </ul>
70 <dl class="py attribute">
71 <dt class="sig sig-object py" id="smb.base.SharedFile.alloc_size">
72 <span class="sig-name descname"><span class="pre">alloc_size</span></span><a class="headerlink" href="#smb.base.SharedFile.alloc_size" title="Permalink to this definition">¶</a></dt>
9573 <dd><p>Total number of bytes allocated to store this file</p>
9674 </dd></dl>
9775
98 <dl class="attribute">
99 <dt id="smb.base.SharedFile.create_time">
100 <code class="descname">create_time</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.create_time" title="Permalink to this definition">¶</a></dt>
76 <dl class="py attribute">
77 <dt class="sig sig-object py" id="smb.base.SharedFile.create_time">
78 <span class="sig-name descname"><span class="pre">create_time</span></span><a class="headerlink" href="#smb.base.SharedFile.create_time" title="Permalink to this definition">¶</a></dt>
10179 <dd><p>Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server</p>
10280 </dd></dl>
10381
104 <dl class="attribute">
105 <dt id="smb.base.SharedFile.file_attributes">
106 <code class="descname">file_attributes</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.file_attributes" title="Permalink to this definition">¶</a></dt>
107 <dd><p>A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3</p>
108 </dd></dl>
109
110 <dl class="attribute">
111 <dt id="smb.base.SharedFile.file_size">
112 <code class="descname">file_size</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.file_size" title="Permalink to this definition">¶</a></dt>
82 <dl class="py attribute">
83 <dt class="sig sig-object py" id="smb.base.SharedFile.file_attributes">
84 <span class="sig-name descname"><span class="pre">file_attributes</span></span><a class="headerlink" href="#smb.base.SharedFile.file_attributes" title="Permalink to this definition">¶</a></dt>
85 <dd><p>A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3. You can perform bit-wise tests to determine the status of the file using the ATTR_xxx constants in smb_constants.py.</p>
86 </dd></dl>
87
88 <dl class="py attribute">
89 <dt class="sig sig-object py" id="smb.base.SharedFile.file_id">
90 <span class="sig-name descname"><span class="pre">file_id</span></span><a class="headerlink" href="#smb.base.SharedFile.file_id" title="Permalink to this definition">¶</a></dt>
91 <dd><p>Long value representing the file reference number for the file. If the remote system does not support this field, this field will be None or 0. See [MS-FSCC]: 2.4.17</p>
92 </dd></dl>
93
94 <dl class="py attribute">
95 <dt class="sig sig-object py" id="smb.base.SharedFile.file_size">
96 <span class="sig-name descname"><span class="pre">file_size</span></span><a class="headerlink" href="#smb.base.SharedFile.file_size" title="Permalink to this definition">¶</a></dt>
11397 <dd><p>File size in number of bytes</p>
11498 </dd></dl>
11599
116 <dl class="attribute">
117 <dt id="smb.base.SharedFile.filename">
118 <code class="descname">filename</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.filename" title="Permalink to this definition">¶</a></dt>
100 <dl class="py attribute">
101 <dt class="sig sig-object py" id="smb.base.SharedFile.filename">
102 <span class="sig-name descname"><span class="pre">filename</span></span><a class="headerlink" href="#smb.base.SharedFile.filename" title="Permalink to this definition">¶</a></dt>
119103 <dd><p>Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.</p>
120104 </dd></dl>
121105
122 <dl class="attribute">
123 <dt id="smb.base.SharedFile.isDirectory">
124 <code class="descname">isDirectory</code><a class="headerlink" href="#smb.base.SharedFile.isDirectory" title="Permalink to this definition">¶</a></dt>
125 <dd><p>A convenient property to return True if this file resource is a directory on the remote server</p>
126 </dd></dl>
127
128 <dl class="attribute">
129 <dt id="smb.base.SharedFile.isReadOnly">
130 <code class="descname">isReadOnly</code><a class="headerlink" href="#smb.base.SharedFile.isReadOnly" title="Permalink to this definition">¶</a></dt>
106 <dl class="py property">
107 <dt class="sig sig-object py" id="smb.base.SharedFile.isDirectory">
108 <em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">isDirectory</span></span><a class="headerlink" href="#smb.base.SharedFile.isDirectory" title="Permalink to this definition">¶</a></dt>
109 <dd><p>A convenience property to return True if this file resource is a directory on the remote server</p>
110 </dd></dl>
111
112 <dl class="py property">
113 <dt class="sig sig-object py" id="smb.base.SharedFile.isNormal">
114 <em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">isNormal</span></span><a class="headerlink" href="#smb.base.SharedFile.isNormal" title="Permalink to this definition">¶</a></dt>
115 <dd><p>A convenient property to return True if this is a normal file.</p>
116 <p>Note that pysmb defines a normal file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.
117 It ignores other attributes like compression, indexed, sparse, temporary and encryption.</p>
118 </dd></dl>
119
120 <dl class="py property">
121 <dt class="sig sig-object py" id="smb.base.SharedFile.isReadOnly">
122 <em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">isReadOnly</span></span><a class="headerlink" href="#smb.base.SharedFile.isReadOnly" title="Permalink to this definition">¶</a></dt>
131123 <dd><p>A convenient property to return True if this file resource is read-only on the remote server</p>
132124 </dd></dl>
133125
134 <dl class="attribute">
135 <dt id="smb.base.SharedFile.last_access_time">
136 <code class="descname">last_access_time</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.last_access_time" title="Permalink to this definition">¶</a></dt>
126 <dl class="py attribute">
127 <dt class="sig sig-object py" id="smb.base.SharedFile.last_access_time">
128 <span class="sig-name descname"><span class="pre">last_access_time</span></span><a class="headerlink" href="#smb.base.SharedFile.last_access_time" title="Permalink to this definition">¶</a></dt>
137129 <dd><p>Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server</p>
138130 </dd></dl>
139131
140 <dl class="attribute">
141 <dt id="smb.base.SharedFile.last_attr_change_time">
142 <code class="descname">last_attr_change_time</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.last_attr_change_time" title="Permalink to this definition">¶</a></dt>
132 <dl class="py attribute">
133 <dt class="sig sig-object py" id="smb.base.SharedFile.last_attr_change_time">
134 <span class="sig-name descname"><span class="pre">last_attr_change_time</span></span><a class="headerlink" href="#smb.base.SharedFile.last_attr_change_time" title="Permalink to this definition">¶</a></dt>
143135 <dd><p>Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server</p>
144136 </dd></dl>
145137
146 <dl class="attribute">
147 <dt id="smb.base.SharedFile.last_write_time">
148 <code class="descname">last_write_time</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.last_write_time" title="Permalink to this definition">¶</a></dt>
138 <dl class="py attribute">
139 <dt class="sig sig-object py" id="smb.base.SharedFile.last_write_time">
140 <span class="sig-name descname"><span class="pre">last_write_time</span></span><a class="headerlink" href="#smb.base.SharedFile.last_write_time" title="Permalink to this definition">¶</a></dt>
149141 <dd><p>Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server</p>
150142 </dd></dl>
151143
152 <dl class="attribute">
153 <dt id="smb.base.SharedFile.short_name">
154 <code class="descname">short_name</code><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.short_name" title="Permalink to this definition">¶</a></dt>
144 <dl class="py attribute">
145 <dt class="sig sig-object py" id="smb.base.SharedFile.short_name">
146 <span class="sig-name descname"><span class="pre">short_name</span></span><a class="headerlink" href="#smb.base.SharedFile.short_name" title="Permalink to this definition">¶</a></dt>
155147 <dd><p>Unicode string containing the short name of this file (usually in 8.3 notation)</p>
156148 </dd></dl>
157149
158150 </dd></dl>
159151
152 </section>
153
154
155 <div class="clearer"></div>
156 </div>
157 </div>
158 </div>
159 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
160 <div class="sphinxsidebarwrapper">
161 <div>
162 <h4>Previous topic</h4>
163 <p class="topless"><a href="smb_SharedDevice.html"
164 title="previous chapter">SharedDevice Class</a></p>
165 </div>
166 <div>
167 <h4>Next topic</h4>
168 <p class="topless"><a href="smb_exceptions.html"
169 title="next chapter">SMB Exceptions</a></p>
170 </div>
171 <div role="note" aria-label="source link">
172 <h3>This Page</h3>
173 <ul class="this-page-menu">
174 <li><a href="../_sources/api/smb_SharedFile.rst.txt"
175 rel="nofollow">Show Source</a></li>
176 </ul>
177 </div>
178 <div id="searchbox" style="display: none" role="search">
179 <h3 id="searchlabel">Quick search</h3>
180 <div class="searchformwrapper">
181 <form class="search" action="../search.html" method="get">
182 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
183 <input type="submit" value="Go" />
184 </form>
185 </div>
160186 </div>
161
162
163 </div>
187 <script>document.getElementById('searchbox').style.display = "block"</script>
164188 </div>
165189 </div>
166190 <div class="clearer"></div>
172196 <a href="../genindex.html" title="General Index"
173197 >index</a></li>
174198 <li class="right" >
199 <a href="../py-modindex.html" title="Python Module Index"
200 >modules</a> |</li>
201 <li class="right" >
175202 <a href="smb_exceptions.html" title="SMB Exceptions"
176203 >next</a> |</li>
177204 <li class="right" >
178205 <a href="smb_SharedDevice.html" title="SharedDevice Class"
179206 >previous</a> |</li>
180 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
207 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
208 <li class="nav-item nav-item-this"><a href="">SharedFile Class</a></li>
181209 </ul>
182210 </div>
183211 <div class="footer" role="contentinfo">
184 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
185 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
212 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
213 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
186214 </div>
187215 </body>
188216 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
20
1 <!DOCTYPE html>
32
4 <html xmlns="http://www.w3.org/1999/xhtml">
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>SMB Exceptions &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: '../',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="../_static/jquery.js"></script>
23 <script type="text/javascript" src="../_static/underscore.js"></script>
24 <script type="text/javascript" src="../_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="../index.html" />
26 <link rel="next" title="Extending pysmb For Other Frameworks" href="../extending.html" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>SMB Exceptions &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
11 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
12 <script src="../_static/jquery.js"></script>
13 <script src="../_static/underscore.js"></script>
14 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="../_static/doctools.js"></script>
16 <link rel="index" title="Index" href="../genindex.html" />
17 <link rel="search" title="Search" href="../search.html" />
18 <link rel="next" title="Security Descriptors" href="smb_security_descriptors.html" />
2719 <link rel="prev" title="SharedFile Class" href="smb_SharedFile.html" />
28 </head>
29 <body role="document">
20 </head><body>
3021 <div class="related" role="navigation" aria-label="related navigation">
3122 <h3>Navigation</h3>
3223 <ul>
3425 <a href="../genindex.html" title="General Index"
3526 accesskey="I">index</a></li>
3627 <li class="right" >
37 <a href="../extending.html" title="Extending pysmb For Other Frameworks"
28 <a href="../py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
31 <a href="smb_security_descriptors.html" title="Security Descriptors"
3832 accesskey="N">next</a> |</li>
3933 <li class="right" >
4034 <a href="smb_SharedFile.html" title="SharedFile Class"
4135 accesskey="P">previous</a> |</li>
42 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">SMB Exceptions</a></li>
4338 </ul>
44 </div>
45 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
46 <div class="sphinxsidebarwrapper">
47 <h4>Previous topic</h4>
48 <p class="topless"><a href="smb_SharedFile.html"
49 title="previous chapter">SharedFile Class</a></p>
50 <h4>Next topic</h4>
51 <p class="topless"><a href="../extending.html"
52 title="next chapter">Extending pysmb For Other Frameworks</a></p>
53 <div role="note" aria-label="source link">
54 <h3>This Page</h3>
55 <ul class="this-page-menu">
56 <li><a href="../_sources/api/smb_exceptions.txt"
57 rel="nofollow">Show Source</a></li>
58 </ul>
59 </div>
60 <div id="searchbox" style="display: none" role="search">
61 <h3>Quick search</h3>
62 <form class="search" action="../search.html" method="get">
63 <input type="text" name="q" />
64 <input type="submit" value="Go" />
65 <input type="hidden" name="check_keywords" value="yes" />
66 <input type="hidden" name="area" value="default" />
67 </form>
68 <p class="searchtip" style="font-size: 90%">
69 Enter search terms or a module, class or function name.
70 </p>
71 </div>
72 <script type="text/javascript">$('#searchbox').show(0);</script>
73 </div>
74 </div>
39 </div>
7540
7641 <div class="document">
7742 <div class="documentwrapper">
7843 <div class="bodywrapper">
7944 <div class="body" role="main">
8045
81 <div class="section" id="smb-exceptions">
82 <h1>SMB Exceptions<a class="headerlink" href="#smb-exceptions" title="Permalink to this headline">¶</a></h1>
83 <dl class="class">
84 <dt id="smb.base.SMBTimeout">
85 <em class="property">class </em><code class="descclassname">smb.base.</code><code class="descname">SMBTimeout</code><a class="reference internal" href="../_modules/smb/base.html#SMBTimeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SMBTimeout" title="Permalink to this definition">¶</a></dt>
46 <section id="smb-exceptions">
47 <h1>SMB Exceptions<a class="headerlink" href="#smb-exceptions" title="Permalink to this heading">¶</a></h1>
48 <dl class="py class">
49 <dt class="sig sig-object py" id="smb.base.SMBTimeout">
50 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.base.</span></span><span class="sig-name descname"><span class="pre">SMBTimeout</span></span><a class="reference internal" href="../_modules/smb/base.html#SMBTimeout"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.base.SMBTimeout" title="Permalink to this definition">¶</a></dt>
8651 <dd><p>Raised when a timeout has occurred while waiting for a response or for a SMB/CIFS operation to complete.</p>
8752 </dd></dl>
8853
89 <dl class="class">
90 <dt id="smb.base.NotReadyError">
91 <em class="property">class </em><code class="descclassname">smb.base.</code><code class="descname">NotReadyError</code><a class="reference internal" href="../_modules/smb/base.html#NotReadyError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.NotReadyError" title="Permalink to this definition">¶</a></dt>
54 <dl class="py class">
55 <dt class="sig sig-object py" id="smb.base.NotReadyError">
56 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.base.</span></span><span class="sig-name descname"><span class="pre">NotReadyError</span></span><a class="reference internal" href="../_modules/smb/base.html#NotReadyError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.base.NotReadyError" title="Permalink to this definition">¶</a></dt>
9257 <dd><p>Raised when SMB connection is not ready (i.e. not authenticated or authentication failed)</p>
9358 </dd></dl>
9459
95 <dl class="class">
96 <dt id="smb.base.NotConnectedError">
97 <em class="property">class </em><code class="descclassname">smb.base.</code><code class="descname">NotConnectedError</code><a class="reference internal" href="../_modules/smb/base.html#NotConnectedError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.NotConnectedError" title="Permalink to this definition">¶</a></dt>
60 <dl class="py class">
61 <dt class="sig sig-object py" id="smb.base.NotConnectedError">
62 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.base.</span></span><span class="sig-name descname"><span class="pre">NotConnectedError</span></span><a class="reference internal" href="../_modules/smb/base.html#NotConnectedError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.base.NotConnectedError" title="Permalink to this definition">¶</a></dt>
9863 <dd><p>Raised when underlying SMB connection has been disconnected or not connected yet</p>
9964 </dd></dl>
10065
101 <dl class="class">
102 <dt id="smb.smb_structs.UnsupportedFeature">
103 <em class="property">class </em><code class="descclassname">smb.smb_structs.</code><code class="descname">UnsupportedFeature</code><a class="reference internal" href="../_modules/smb/smb_structs.html#UnsupportedFeature"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.smb_structs.UnsupportedFeature" title="Permalink to this definition">¶</a></dt>
66 <dl class="py class">
67 <dt class="sig sig-object py" id="smb.smb_structs.UnsupportedFeature">
68 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.smb_structs.</span></span><span class="sig-name descname"><span class="pre">UnsupportedFeature</span></span><a class="reference internal" href="../_modules/smb/smb_structs.html#UnsupportedFeature"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.smb_structs.UnsupportedFeature" title="Permalink to this definition">¶</a></dt>
10469 <dd><p>Raised when an supported feature is present/required in the protocol but is not
10570 currently supported by pysmb</p>
10671 </dd></dl>
10772
108 <dl class="class">
109 <dt id="smb.smb_structs.ProtocolError">
110 <em class="property">class </em><code class="descclassname">smb.smb_structs.</code><code class="descname">ProtocolError</code><span class="sig-paren">(</span><em>message</em>, <em>data_buf=None</em>, <em>smb_message=None</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/smb_structs.html#ProtocolError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.smb_structs.ProtocolError" title="Permalink to this definition">¶</a></dt>
73 <dl class="py class">
74 <dt class="sig sig-object py" id="smb.smb_structs.ProtocolError">
75 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.smb_structs.</span></span><span class="sig-name descname"><span class="pre">ProtocolError</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">message</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">data_buf</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">smb_message</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/smb_structs.html#ProtocolError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.smb_structs.ProtocolError" title="Permalink to this definition">¶</a></dt>
11176 <dd></dd></dl>
11277
113 <dl class="class">
114 <dt id="smb.smb_structs.OperationFailure">
115 <em class="property">class </em><code class="descclassname">smb.smb_structs.</code><code class="descname">OperationFailure</code><span class="sig-paren">(</span><em>message</em>, <em>smb_messages</em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/smb_structs.html#OperationFailure"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.smb_structs.OperationFailure" title="Permalink to this definition">¶</a></dt>
78 <dl class="py class">
79 <dt class="sig sig-object py" id="smb.smb_structs.OperationFailure">
80 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.smb_structs.</span></span><span class="sig-name descname"><span class="pre">OperationFailure</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">message</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">smb_messages</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/smb_structs.html#OperationFailure"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.smb_structs.OperationFailure" title="Permalink to this definition">¶</a></dt>
11681 <dd></dd></dl>
11782
118 </div>
83 </section>
11984
12085
86 <div class="clearer"></div>
12187 </div>
88 </div>
89 </div>
90 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
91 <div class="sphinxsidebarwrapper">
92 <div>
93 <h4>Previous topic</h4>
94 <p class="topless"><a href="smb_SharedFile.html"
95 title="previous chapter">SharedFile Class</a></p>
96 </div>
97 <div>
98 <h4>Next topic</h4>
99 <p class="topless"><a href="smb_security_descriptors.html"
100 title="next chapter">Security Descriptors</a></p>
101 </div>
102 <div role="note" aria-label="source link">
103 <h3>This Page</h3>
104 <ul class="this-page-menu">
105 <li><a href="../_sources/api/smb_exceptions.rst.txt"
106 rel="nofollow">Show Source</a></li>
107 </ul>
108 </div>
109 <div id="searchbox" style="display: none" role="search">
110 <h3 id="searchlabel">Quick search</h3>
111 <div class="searchformwrapper">
112 <form class="search" action="../search.html" method="get">
113 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
114 <input type="submit" value="Go" />
115 </form>
116 </div>
117 </div>
118 <script>document.getElementById('searchbox').style.display = "block"</script>
122119 </div>
123120 </div>
124121 <div class="clearer"></div>
130127 <a href="../genindex.html" title="General Index"
131128 >index</a></li>
132129 <li class="right" >
133 <a href="../extending.html" title="Extending pysmb For Other Frameworks"
130 <a href="../py-modindex.html" title="Python Module Index"
131 >modules</a> |</li>
132 <li class="right" >
133 <a href="smb_security_descriptors.html" title="Security Descriptors"
134134 >next</a> |</li>
135135 <li class="right" >
136136 <a href="smb_SharedFile.html" title="SharedFile Class"
137137 >previous</a> |</li>
138 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
138 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
139 <li class="nav-item nav-item-this"><a href="">SMB Exceptions</a></li>
139140 </ul>
140141 </div>
141142 <div class="footer" role="contentinfo">
142 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
143 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
143 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
144 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
144145 </div>
145146 </body>
146147 </html>
0
1 <!DOCTYPE html>
2
3 <html lang="en">
4 <head>
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>Security Descriptors &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="../_static/sphinxdoc.css" />
11 <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
12 <script src="../_static/jquery.js"></script>
13 <script src="../_static/underscore.js"></script>
14 <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="../_static/doctools.js"></script>
16 <link rel="index" title="Index" href="../genindex.html" />
17 <link rel="search" title="Search" href="../search.html" />
18 <link rel="next" title="Extending pysmb For Other Frameworks" href="../extending.html" />
19 <link rel="prev" title="SMB Exceptions" href="smb_exceptions.html" />
20 </head><body>
21 <div class="related" role="navigation" aria-label="related navigation">
22 <h3>Navigation</h3>
23 <ul>
24 <li class="right" style="margin-right: 10px">
25 <a href="../genindex.html" title="General Index"
26 accesskey="I">index</a></li>
27 <li class="right" >
28 <a href="../py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
31 <a href="../extending.html" title="Extending pysmb For Other Frameworks"
32 accesskey="N">next</a> |</li>
33 <li class="right" >
34 <a href="smb_exceptions.html" title="SMB Exceptions"
35 accesskey="P">previous</a> |</li>
36 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">Security Descriptors</a></li>
38 </ul>
39 </div>
40
41 <div class="document">
42 <div class="documentwrapper">
43 <div class="bodywrapper">
44 <div class="body" role="main">
45
46 <section id="module-smb.security_descriptors">
47 <span id="security-descriptors"></span><h1>Security Descriptors<a class="headerlink" href="#module-smb.security_descriptors" title="Permalink to this heading">¶</a></h1>
48 <p>This module implements security descriptors, and associated data
49 structures, as specified in <a class="reference external" href="https://msdn.microsoft.com/en-us/library/cc230273.aspx">[MS-DTYP]</a>.</p>
50 <dl class="py class">
51 <dt class="sig sig-object py" id="smb.security_descriptors.SID">
52 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.security_descriptors.</span></span><span class="sig-name descname"><span class="pre">SID</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">revision</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">identifier_authority</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">subauthorities</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/security_descriptors.html#SID"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.security_descriptors.SID" title="Permalink to this definition">¶</a></dt>
53 <dd><p>A Windows security identifier. Represents a single principal, such a
54 user or a group, as a sequence of numbers consisting of the revision,
55 identifier authority, and a variable-length list of subauthorities.</p>
56 <p>See [MS-DTYP]: 2.4.2</p>
57 <dl class="py attribute">
58 <dt class="sig sig-object py" id="smb.security_descriptors.SID.identifier_authority">
59 <span class="sig-name descname"><span class="pre">identifier_authority</span></span><a class="headerlink" href="#smb.security_descriptors.SID.identifier_authority" title="Permalink to this definition">¶</a></dt>
60 <dd><p>An integer representing the identifier authority.</p>
61 </dd></dl>
62
63 <dl class="py attribute">
64 <dt class="sig sig-object py" id="smb.security_descriptors.SID.revision">
65 <span class="sig-name descname"><span class="pre">revision</span></span><a class="headerlink" href="#smb.security_descriptors.SID.revision" title="Permalink to this definition">¶</a></dt>
66 <dd><p>Revision, should always be 1.</p>
67 </dd></dl>
68
69 <dl class="py attribute">
70 <dt class="sig sig-object py" id="smb.security_descriptors.SID.subauthorities">
71 <span class="sig-name descname"><span class="pre">subauthorities</span></span><a class="headerlink" href="#smb.security_descriptors.SID.subauthorities" title="Permalink to this definition">¶</a></dt>
72 <dd><p>A list of integers representing all subauthorities.</p>
73 </dd></dl>
74
75 </dd></dl>
76
77 <dl class="py class">
78 <dt class="sig sig-object py" id="smb.security_descriptors.ACE">
79 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.security_descriptors.</span></span><span class="sig-name descname"><span class="pre">ACE</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">type_</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">flags</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">mask</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sid</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">additional_data</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/security_descriptors.html#ACE"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.security_descriptors.ACE" title="Permalink to this definition">¶</a></dt>
80 <dd><p>Represents a single access control entry.</p>
81 <p>See [MS-DTYP]: 2.4.4</p>
82 <dl class="py attribute">
83 <dt class="sig sig-object py" id="smb.security_descriptors.ACE.additional_data">
84 <span class="sig-name descname"><span class="pre">additional_data</span></span><a class="headerlink" href="#smb.security_descriptors.ACE.additional_data" title="Permalink to this definition">¶</a></dt>
85 <dd><p>A dictionary of additional fields present in the ACE, depending
86 on the type. The following fields can be present:</p>
87 <ul class="simple">
88 <li><p><code class="docutils literal notranslate"><span class="pre">flags</span></code></p></li>
89 <li><p><code class="docutils literal notranslate"><span class="pre">object_type</span></code></p></li>
90 <li><p><code class="docutils literal notranslate"><span class="pre">inherited_object_type</span></code></p></li>
91 <li><p><code class="docutils literal notranslate"><span class="pre">application_data</span></code></p></li>
92 <li><p><code class="docutils literal notranslate"><span class="pre">attribute_data</span></code></p></li>
93 </ul>
94 </dd></dl>
95
96 <dl class="py attribute">
97 <dt class="sig sig-object py" id="smb.security_descriptors.ACE.flags">
98 <span class="sig-name descname"><span class="pre">flags</span></span><a class="headerlink" href="#smb.security_descriptors.ACE.flags" title="Permalink to this definition">¶</a></dt>
99 <dd><p>An integer bitmask with ACE flags, corresponds to the
100 <code class="docutils literal notranslate"><span class="pre">AceFlags</span></code> field.</p>
101 </dd></dl>
102
103 <dl class="py property">
104 <dt class="sig sig-object py" id="smb.security_descriptors.ACE.isInheritOnly">
105 <em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">isInheritOnly</span></span><a class="headerlink" href="#smb.security_descriptors.ACE.isInheritOnly" title="Permalink to this definition">¶</a></dt>
106 <dd><p>Convenience property which indicates if this ACE is inherit
107 only, meaning that it doesn’t apply to the object itself.</p>
108 </dd></dl>
109
110 <dl class="py attribute">
111 <dt class="sig sig-object py" id="smb.security_descriptors.ACE.mask">
112 <span class="sig-name descname"><span class="pre">mask</span></span><a class="headerlink" href="#smb.security_descriptors.ACE.mask" title="Permalink to this definition">¶</a></dt>
113 <dd><p>An integer representing the <code class="docutils literal notranslate"><span class="pre">ACCESS_MASK</span></code> as specified in
114 [MS-DTYP] 2.4.3.</p>
115 </dd></dl>
116
117 <dl class="py attribute">
118 <dt class="sig sig-object py" id="smb.security_descriptors.ACE.sid">
119 <span class="sig-name descname"><span class="pre">sid</span></span><a class="headerlink" href="#smb.security_descriptors.ACE.sid" title="Permalink to this definition">¶</a></dt>
120 <dd><p>The <a class="reference internal" href="#smb.security_descriptors.SID" title="smb.security_descriptors.SID"><code class="xref py py-class docutils literal notranslate"><span class="pre">SID</span></code></a> of a trustee.</p>
121 </dd></dl>
122
123 <dl class="py attribute">
124 <dt class="sig sig-object py" id="smb.security_descriptors.ACE.type">
125 <span class="sig-name descname"><span class="pre">type</span></span><a class="headerlink" href="#smb.security_descriptors.ACE.type" title="Permalink to this definition">¶</a></dt>
126 <dd><p>An integer representing the type of the ACE. One of the
127 <code class="docutils literal notranslate"><span class="pre">ACE_TYPE_*</span></code> constants. Corresponds to the <code class="docutils literal notranslate"><span class="pre">AceType</span></code> field
128 from [MS-DTYP] 2.4.4.1.</p>
129 </dd></dl>
130
131 </dd></dl>
132
133 <dl class="py class">
134 <dt class="sig sig-object py" id="smb.security_descriptors.ACL">
135 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.security_descriptors.</span></span><span class="sig-name descname"><span class="pre">ACL</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">revision</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">aces</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/security_descriptors.html#ACL"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.security_descriptors.ACL" title="Permalink to this definition">¶</a></dt>
136 <dd><p>Access control list, encapsulating a sequence of access control
137 entries.</p>
138 <p>See [MS-DTYP]: 2.4.5</p>
139 <dl class="py attribute">
140 <dt class="sig sig-object py" id="smb.security_descriptors.ACL.aces">
141 <span class="sig-name descname"><span class="pre">aces</span></span><a class="headerlink" href="#smb.security_descriptors.ACL.aces" title="Permalink to this definition">¶</a></dt>
142 <dd><p>List of <a class="reference internal" href="#smb.security_descriptors.ACE" title="smb.security_descriptors.ACE"><code class="xref py py-class docutils literal notranslate"><span class="pre">ACE</span></code></a> instances.</p>
143 </dd></dl>
144
145 <dl class="py attribute">
146 <dt class="sig sig-object py" id="smb.security_descriptors.ACL.revision">
147 <span class="sig-name descname"><span class="pre">revision</span></span><a class="headerlink" href="#smb.security_descriptors.ACL.revision" title="Permalink to this definition">¶</a></dt>
148 <dd><p>Integer value of the revision.</p>
149 </dd></dl>
150
151 </dd></dl>
152
153 <dl class="py class">
154 <dt class="sig sig-object py" id="smb.security_descriptors.SecurityDescriptor">
155 <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">smb.security_descriptors.</span></span><span class="sig-name descname"><span class="pre">SecurityDescriptor</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">flags</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">owner</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">group</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">dacl</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sacl</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/smb/security_descriptors.html#SecurityDescriptor"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#smb.security_descriptors.SecurityDescriptor" title="Permalink to this definition">¶</a></dt>
156 <dd><p>Represents a security descriptor.</p>
157 <p>See [MS-DTYP]: 2.4.6</p>
158 <dl class="py attribute">
159 <dt class="sig sig-object py" id="smb.security_descriptors.SecurityDescriptor.dacl">
160 <span class="sig-name descname"><span class="pre">dacl</span></span><a class="headerlink" href="#smb.security_descriptors.SecurityDescriptor.dacl" title="Permalink to this definition">¶</a></dt>
161 <dd><p>Instance of <a class="reference internal" href="#smb.security_descriptors.ACL" title="smb.security_descriptors.ACL"><code class="xref py py-class docutils literal notranslate"><span class="pre">ACL</span></code></a> representing the discretionary access
162 control list, which specifies access restrictions of an object.</p>
163 </dd></dl>
164
165 <dl class="py attribute">
166 <dt class="sig sig-object py" id="smb.security_descriptors.SecurityDescriptor.flags">
167 <span class="sig-name descname"><span class="pre">flags</span></span><a class="headerlink" href="#smb.security_descriptors.SecurityDescriptor.flags" title="Permalink to this definition">¶</a></dt>
168 <dd><p>Integer bitmask of control flags. Corresponds to the
169 <code class="docutils literal notranslate"><span class="pre">Control</span></code> field in [MS-DTYP] 2.4.6.</p>
170 </dd></dl>
171
172 <dl class="py attribute">
173 <dt class="sig sig-object py" id="smb.security_descriptors.SecurityDescriptor.group">
174 <span class="sig-name descname"><span class="pre">group</span></span><a class="headerlink" href="#smb.security_descriptors.SecurityDescriptor.group" title="Permalink to this definition">¶</a></dt>
175 <dd><p>Instance of <a class="reference internal" href="#smb.security_descriptors.SID" title="smb.security_descriptors.SID"><code class="xref py py-class docutils literal notranslate"><span class="pre">SID</span></code></a> representing the owner group.</p>
176 </dd></dl>
177
178 <dl class="py attribute">
179 <dt class="sig sig-object py" id="smb.security_descriptors.SecurityDescriptor.owner">
180 <span class="sig-name descname"><span class="pre">owner</span></span><a class="headerlink" href="#smb.security_descriptors.SecurityDescriptor.owner" title="Permalink to this definition">¶</a></dt>
181 <dd><p>Instance of <a class="reference internal" href="#smb.security_descriptors.SID" title="smb.security_descriptors.SID"><code class="xref py py-class docutils literal notranslate"><span class="pre">SID</span></code></a> representing the owner user.</p>
182 </dd></dl>
183
184 <dl class="py attribute">
185 <dt class="sig sig-object py" id="smb.security_descriptors.SecurityDescriptor.sacl">
186 <span class="sig-name descname"><span class="pre">sacl</span></span><a class="headerlink" href="#smb.security_descriptors.SecurityDescriptor.sacl" title="Permalink to this definition">¶</a></dt>
187 <dd><p>Instance of <a class="reference internal" href="#smb.security_descriptors.ACL" title="smb.security_descriptors.ACL"><code class="xref py py-class docutils literal notranslate"><span class="pre">ACL</span></code></a> representing the system access control
188 list, which specifies audit logging of an object.</p>
189 </dd></dl>
190
191 </dd></dl>
192
193 </section>
194
195
196 <div class="clearer"></div>
197 </div>
198 </div>
199 </div>
200 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
201 <div class="sphinxsidebarwrapper">
202 <div>
203 <h4>Previous topic</h4>
204 <p class="topless"><a href="smb_exceptions.html"
205 title="previous chapter">SMB Exceptions</a></p>
206 </div>
207 <div>
208 <h4>Next topic</h4>
209 <p class="topless"><a href="../extending.html"
210 title="next chapter">Extending pysmb For Other Frameworks</a></p>
211 </div>
212 <div role="note" aria-label="source link">
213 <h3>This Page</h3>
214 <ul class="this-page-menu">
215 <li><a href="../_sources/api/smb_security_descriptors.rst.txt"
216 rel="nofollow">Show Source</a></li>
217 </ul>
218 </div>
219 <div id="searchbox" style="display: none" role="search">
220 <h3 id="searchlabel">Quick search</h3>
221 <div class="searchformwrapper">
222 <form class="search" action="../search.html" method="get">
223 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
224 <input type="submit" value="Go" />
225 </form>
226 </div>
227 </div>
228 <script>document.getElementById('searchbox').style.display = "block"</script>
229 </div>
230 </div>
231 <div class="clearer"></div>
232 </div>
233 <div class="related" role="navigation" aria-label="related navigation">
234 <h3>Navigation</h3>
235 <ul>
236 <li class="right" style="margin-right: 10px">
237 <a href="../genindex.html" title="General Index"
238 >index</a></li>
239 <li class="right" >
240 <a href="../py-modindex.html" title="Python Module Index"
241 >modules</a> |</li>
242 <li class="right" >
243 <a href="../extending.html" title="Extending pysmb For Other Frameworks"
244 >next</a> |</li>
245 <li class="right" >
246 <a href="smb_exceptions.html" title="SMB Exceptions"
247 >previous</a> |</li>
248 <li class="nav-item nav-item-0"><a href="../index.html">pysmb 1.2.8 documentation</a> &#187;</li>
249 <li class="nav-item nav-item-this"><a href="">Security Descriptors</a></li>
250 </ul>
251 </div>
252 <div class="footer" role="contentinfo">
253 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
254 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
255 </div>
256 </body>
257 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
20
1 <!DOCTYPE html>
32
4 <html xmlns="http://www.w3.org/1999/xhtml">
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>Extending pysmb For Other Frameworks &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: './',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="_static/jquery.js"></script>
23 <script type="text/javascript" src="_static/underscore.js"></script>
24 <script type="text/javascript" src="_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="index.html" />
26 <link rel="prev" title="SMB Exceptions" href="api/smb_exceptions.html" />
27 </head>
28 <body role="document">
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>Extending pysmb For Other Frameworks &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="_static/sphinxdoc.css" />
11 <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
12 <script src="_static/jquery.js"></script>
13 <script src="_static/underscore.js"></script>
14 <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="_static/doctools.js"></script>
16 <link rel="index" title="Index" href="genindex.html" />
17 <link rel="search" title="Search" href="search.html" />
18 <link rel="next" title="Upgrading from older pysmb versions" href="upgrading.html" />
19 <link rel="prev" title="Security Descriptors" href="api/smb_security_descriptors.html" />
20 </head><body>
2921 <div class="related" role="navigation" aria-label="related navigation">
3022 <h3>Navigation</h3>
3123 <ul>
3325 <a href="genindex.html" title="General Index"
3426 accesskey="I">index</a></li>
3527 <li class="right" >
36 <a href="api/smb_exceptions.html" title="SMB Exceptions"
28 <a href="py-modindex.html" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="right" >
31 <a href="upgrading.html" title="Upgrading from older pysmb versions"
32 accesskey="N">next</a> |</li>
33 <li class="right" >
34 <a href="api/smb_security_descriptors.html" title="Security Descriptors"
3735 accesskey="P">previous</a> |</li>
38 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
36 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
37 <li class="nav-item nav-item-this"><a href="">Extending pysmb For Other Frameworks</a></li>
3938 </ul>
40 </div>
41 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
42 <div class="sphinxsidebarwrapper">
43 <h4>Previous topic</h4>
44 <p class="topless"><a href="api/smb_exceptions.html"
45 title="previous chapter">SMB Exceptions</a></p>
46 <div role="note" aria-label="source link">
47 <h3>This Page</h3>
48 <ul class="this-page-menu">
49 <li><a href="_sources/extending.txt"
50 rel="nofollow">Show Source</a></li>
51 </ul>
52 </div>
53 <div id="searchbox" style="display: none" role="search">
54 <h3>Quick search</h3>
55 <form class="search" action="search.html" method="get">
56 <input type="text" name="q" />
57 <input type="submit" value="Go" />
58 <input type="hidden" name="check_keywords" value="yes" />
59 <input type="hidden" name="area" value="default" />
60 </form>
61 <p class="searchtip" style="font-size: 90%">
62 Enter search terms or a module, class or function name.
63 </p>
64 </div>
65 <script type="text/javascript">$('#searchbox').show(0);</script>
66 </div>
67 </div>
39 </div>
6840
6941 <div class="document">
7042 <div class="documentwrapper">
7143 <div class="bodywrapper">
7244 <div class="body" role="main">
7345
74 <div class="section" id="extending-pysmb-for-other-frameworks">
75 <h1>Extending pysmb For Other Frameworks<a class="headerlink" href="#extending-pysmb-for-other-frameworks" title="Permalink to this headline">¶</a></h1>
46 <section id="extending-pysmb-for-other-frameworks">
47 <h1>Extending pysmb For Other Frameworks<a class="headerlink" href="#extending-pysmb-for-other-frameworks" title="Permalink to this heading">¶</a></h1>
7648 <p>This page briefly describes the steps involved in extending pysmb for other frameworks.</p>
7749 <p>In general, you need to take care of the SMB TCP connection setup, i.e. finding the IP address of the remote server and connect to the SMB/CIFS service.
7850 Then you need to read/write synchronously or asynchronously from and to the SMB socket. And you need to handle post-authentication callback methods, and from these methods,
7951 initiate file operations with the remote SMB/CIFS server.</p>
80 <dl class="docutils">
81 <dt>Now the above steps in more technical details:</dt>
82 <dd><ol class="first arabic simple">
83 <li>Create a new class which subclasses the <em>smb.base.SMB</em> class. Most often, the connection setup will be part of the <em>__init__</em> method.</li>
84 <li>Override the <em>write(self, data)</em> method to provide an implementation which will write <em>data</em> to the socket.</li>
85 <li>Write your own loop handling method to read data from the socket. Once data have been read, call <em>feedData</em> method with the parameter.
86 The <em>feedData</em> method has its own internal buffer, so it can accept incomplete NetBIOS session packet data.</li>
87 <li>Override</li>
52 <dl>
53 <dt>Now the above steps in more technical details:</dt><dd><ol class="arabic simple">
54 <li><p>Create a new class which subclasses the <em>smb.base.SMB</em> class. Most often, the connection setup will be part of the <em>__init__</em> method.</p></li>
55 <li><p>Override the <em>write(self, data)</em> method to provide an implementation which will write <em>data</em> to the socket.</p></li>
56 <li><p>Write your own loop handling method to read data from the socket. Once data have been read, call <em>feedData</em> method with the parameter.
57 The <em>feedData</em> method has its own internal buffer, so it can accept incomplete NetBIOS session packet data.</p></li>
58 <li><p>Override</p></li>
8859 </ol>
89 <blockquote class="last">
60 <blockquote>
9061 <div><ul class="simple">
91 <li><em>onAuthOK</em> method to include your own operations to perform when authentication is successful. You can initiate file operations in this method.</li>
92 <li><em>onAuthFailed</em> method to include your own processing on what to do when authentication fails. You can report this as an error, or to try a different NTLM authentication algorithm (<em>use_ntlm_v2</em> parameter in the constructor).</li>
93 <li><em>onNMBSessionFailed</em> method to include your own processing on what to do when pysmb fails to setup the NetBIOS session with the remote server. Usually, this is due to a wrong <em>remote_name</em> parameter in the constructor.</li>
62 <li><p><em>onAuthOK</em> method to include your own operations to perform when authentication is successful. You can initiate file operations in this method.</p></li>
63 <li><p><em>onAuthFailed</em> method to include your own processing on what to do when authentication fails. You can report this as an error, or to try a different NTLM authentication algorithm (<em>use_ntlm_v2</em> parameter in the constructor).</p></li>
64 <li><p><em>onNMBSessionFailed</em> method to include your own processing on what to do when pysmb fails to setup the NetBIOS session with the remote server. Usually, this is due to a wrong <em>remote_name</em> parameter in the constructor.</p></li>
9465 </ul>
9566 </div></blockquote>
9667 </dd>
9768 </dl>
98 </div>
69 </section>
9970
10071
72 <div class="clearer"></div>
10173 </div>
74 </div>
75 </div>
76 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
77 <div class="sphinxsidebarwrapper">
78 <div>
79 <h4>Previous topic</h4>
80 <p class="topless"><a href="api/smb_security_descriptors.html"
81 title="previous chapter">Security Descriptors</a></p>
82 </div>
83 <div>
84 <h4>Next topic</h4>
85 <p class="topless"><a href="upgrading.html"
86 title="next chapter">Upgrading from older pysmb versions</a></p>
87 </div>
88 <div role="note" aria-label="source link">
89 <h3>This Page</h3>
90 <ul class="this-page-menu">
91 <li><a href="_sources/extending.rst.txt"
92 rel="nofollow">Show Source</a></li>
93 </ul>
94 </div>
95 <div id="searchbox" style="display: none" role="search">
96 <h3 id="searchlabel">Quick search</h3>
97 <div class="searchformwrapper">
98 <form class="search" action="search.html" method="get">
99 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
100 <input type="submit" value="Go" />
101 </form>
102 </div>
103 </div>
104 <script>document.getElementById('searchbox').style.display = "block"</script>
102105 </div>
103106 </div>
104107 <div class="clearer"></div>
110113 <a href="genindex.html" title="General Index"
111114 >index</a></li>
112115 <li class="right" >
113 <a href="api/smb_exceptions.html" title="SMB Exceptions"
116 <a href="py-modindex.html" title="Python Module Index"
117 >modules</a> |</li>
118 <li class="right" >
119 <a href="upgrading.html" title="Upgrading from older pysmb versions"
120 >next</a> |</li>
121 <li class="right" >
122 <a href="api/smb_security_descriptors.html" title="Security Descriptors"
114123 >previous</a> |</li>
115 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
124 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
125 <li class="nav-item nav-item-this"><a href="">Extending pysmb For Other Frameworks</a></li>
116126 </ul>
117127 </div>
118128 <div class="footer" role="contentinfo">
119 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
120 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
129 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
130 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
121131 </div>
122132 </body>
123133 </html>
00
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
4
5 <html xmlns="http://www.w3.org/1999/xhtml">
1 <!DOCTYPE html>
2
3 <html lang="en">
64 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
9 <title>Index &mdash; pysmb 1.1.18 documentation</title>
10
11 <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
12 <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
13
14 <script type="text/javascript">
15 var DOCUMENTATION_OPTIONS = {
16 URL_ROOT: './',
17 VERSION: '1.1.18',
18 COLLAPSE_INDEX: false,
19 FILE_SUFFIX: '.html',
20 HAS_SOURCE: true
21 };
22 </script>
23 <script type="text/javascript" src="_static/jquery.js"></script>
24 <script type="text/javascript" src="_static/underscore.js"></script>
25 <script type="text/javascript" src="_static/doctools.js"></script>
26 <link rel="top" title="pysmb 1.1.18 documentation" href="index.html" />
27 </head>
28 <body role="document">
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>Index &#8212; pysmb 1.2.8 documentation</title>
8 <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
9 <link rel="stylesheet" type="text/css" href="_static/sphinxdoc.css" />
10 <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
11 <script src="_static/jquery.js"></script>
12 <script src="_static/underscore.js"></script>
13 <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
14 <script src="_static/doctools.js"></script>
15 <link rel="index" title="Index" href="#" />
16 <link rel="search" title="Search" href="search.html" />
17 </head><body>
2918 <div class="related" role="navigation" aria-label="related navigation">
3019 <h3>Navigation</h3>
3120 <ul>
3221 <li class="right" style="margin-right: 10px">
3322 <a href="#" title="General Index"
3423 accesskey="I">index</a></li>
35 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
24 <li class="right" >
25 <a href="py-modindex.html" title="Python Module Index"
26 >modules</a> |</li>
27 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
28 <li class="nav-item nav-item-this"><a href="">Index</a></li>
3629 </ul>
37 </div>
38 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
39 <div class="sphinxsidebarwrapper">
40
41
42
43 <div id="searchbox" style="display: none" role="search">
44 <h3>Quick search</h3>
45 <form class="search" action="search.html" method="get">
46 <input type="text" name="q" />
47 <input type="submit" value="Go" />
48 <input type="hidden" name="check_keywords" value="yes" />
49 <input type="hidden" name="area" value="default" />
50 </form>
51 <p class="searchtip" style="font-size: 90%">
52 Enter search terms or a module, class or function name.
53 </p>
54 </div>
55 <script type="text/javascript">$('#searchbox').show(0);</script>
56 </div>
57 </div>
30 </div>
5831
5932 <div class="document">
6033 <div class="documentwrapper">
7447 | <a href="#G"><strong>G</strong></a>
7548 | <a href="#I"><strong>I</strong></a>
7649 | <a href="#L"><strong>L</strong></a>
50 | <a href="#M"><strong>M</strong></a>
7751 | <a href="#N"><strong>N</strong></a>
7852 | <a href="#O"><strong>O</strong></a>
7953 | <a href="#P"><strong>P</strong></a>
8660 </div>
8761 <h2 id="_">_</h2>
8862 <table style="width: 100%" class="indextable genindextable"><tr>
89 <td style="width: 33%" valign="top"><dl>
90
91 <dt><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.__init__">__init__() (nmb.NetBIOS.NetBIOS method)</a>
92 </dt>
93
94 <dd><dl>
95
96 <dt><a href="api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.__init__">(nmb.NetBIOSProtocol.NBNSProtocol method)</a>
97 </dt>
98
99
100 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.__init__">(smb.SMBConnection.SMBConnection method)</a>
101 </dt>
102
103
104 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.__init__">(smb.SMBProtocol.SMBProtocolFactory method)</a>
105 </dt>
106
107 </dl></dd>
108 </dl></td>
63 <td style="width: 33%; vertical-align: top;"><ul>
64 <li><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.__init__">__init__() (nmb.NetBIOS.NetBIOS method)</a>
65
66 <ul>
67 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.__init__">(smb.SMBConnection.SMBConnection method)</a>
68 </li>
69 </ul></li>
70 </ul></td>
10971 </tr></table>
11072
11173 <h2 id="A">A</h2>
11274 <table style="width: 100%" class="indextable genindextable"><tr>
113 <td style="width: 33%" valign="top"><dl>
114
115 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.alloc_size">alloc_size (smb.base.SharedFile attribute)</a>
116 </dt>
117
118 </dl></td>
75 <td style="width: 33%; vertical-align: top;"><ul>
76 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACE">ACE (class in smb.security_descriptors)</a>
77 </li>
78 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACL.aces">aces (smb.security_descriptors.ACL attribute)</a>
79 </li>
80 </ul></td>
81 <td style="width: 33%; vertical-align: top;"><ul>
82 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACL">ACL (class in smb.security_descriptors)</a>
83 </li>
84 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACE.additional_data">additional_data (smb.security_descriptors.ACE attribute)</a>
85 </li>
86 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.alloc_size">alloc_size (smb.base.SharedFile attribute)</a>
87 </li>
88 </ul></td>
11989 </tr></table>
12090
12191 <h2 id="C">C</h2>
12292 <table style="width: 100%" class="indextable genindextable"><tr>
123 <td style="width: 33%" valign="top"><dl>
124
125 <dt><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.close">close() (nmb.NetBIOS.NetBIOS method)</a>
126 </dt>
127
128 <dd><dl>
129
130 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.close">(smb.SMBConnection.SMBConnection method)</a>
131 </dt>
132
133 </dl></dd>
134
135 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.closeConnection">closeConnection() (smb.SMBProtocol.SMBProtocolFactory method)</a>
136 </dt>
137
138
139 <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.comments">comments (smb.base.SharedDevice attribute)</a>
140 </dt>
141
142 </dl></td>
143 <td style="width: 33%" valign="top"><dl>
144
145 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.connect">connect() (smb.SMBConnection.SMBConnection method)</a>
146 </dt>
147
148
149 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.create_time">create_time (smb.base.SharedFile attribute)</a>
150 </dt>
151
152
153 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.createDirectory">createDirectory() (smb.SMBConnection.SMBConnection method)</a>
154 </dt>
155
156 <dd><dl>
157
158 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.createDirectory">(smb.SMBProtocol.SMBProtocolFactory method)</a>
159 </dt>
160
161 </dl></dd>
162 </dl></td>
93 <td style="width: 33%; vertical-align: top;"><ul>
94 <li><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.close">close() (nmb.NetBIOS.NetBIOS method)</a>
95
96 <ul>
97 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.close">(smb.SMBConnection.SMBConnection method)</a>
98 </li>
99 </ul></li>
100 <li><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.comments">comments (smb.base.SharedDevice attribute)</a>
101 </li>
102 </ul></td>
103 <td style="width: 33%; vertical-align: top;"><ul>
104 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.connect">connect() (smb.SMBConnection.SMBConnection method)</a>
105 </li>
106 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.create_time">create_time (smb.base.SharedFile attribute)</a>
107 </li>
108 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.createDirectory">createDirectory() (smb.SMBConnection.SMBConnection method)</a>
109 </li>
110 </ul></td>
163111 </tr></table>
164112
165113 <h2 id="D">D</h2>
166114 <table style="width: 100%" class="indextable genindextable"><tr>
167 <td style="width: 33%" valign="top"><dl>
168
169 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteDirectory">deleteDirectory() (smb.SMBConnection.SMBConnection method)</a>
170 </dt>
171
172 <dd><dl>
173
174 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.deleteDirectory">(smb.SMBProtocol.SMBProtocolFactory method)</a>
175 </dt>
176
177 </dl></dd>
178 </dl></td>
179 <td style="width: 33%" valign="top"><dl>
180
181 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteFiles">deleteFiles() (smb.SMBConnection.SMBConnection method)</a>
182 </dt>
183
184 <dd><dl>
185
186 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.deleteFiles">(smb.SMBProtocol.SMBProtocolFactory method)</a>
187 </dt>
188
189 </dl></dd>
190 </dl></td>
115 <td style="width: 33%; vertical-align: top;"><ul>
116 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SecurityDescriptor.dacl">dacl (smb.security_descriptors.SecurityDescriptor attribute)</a>
117 </li>
118 </ul></td>
119 <td style="width: 33%; vertical-align: top;"><ul>
120 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteDirectory">deleteDirectory() (smb.SMBConnection.SMBConnection method)</a>
121 </li>
122 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteFiles">deleteFiles() (smb.SMBConnection.SMBConnection method)</a>
123 </li>
124 </ul></td>
191125 </tr></table>
192126
193127 <h2 id="E">E</h2>
194128 <table style="width: 100%" class="indextable genindextable"><tr>
195 <td style="width: 33%" valign="top"><dl>
196
197 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.echo">echo() (smb.SMBConnection.SMBConnection method)</a>
198 </dt>
199
200 <dd><dl>
201
202 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.echo">(smb.SMBProtocol.SMBProtocolFactory method)</a>
203 </dt>
204
205 </dl></dd>
206 </dl></td>
129 <td style="width: 33%; vertical-align: top;"><ul>
130 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.echo">echo() (smb.SMBConnection.SMBConnection method)</a>
131 </li>
132 </ul></td>
207133 </tr></table>
208134
209135 <h2 id="F">F</h2>
210136 <table style="width: 100%" class="indextable genindextable"><tr>
211 <td style="width: 33%" valign="top"><dl>
212
213 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.file_attributes">file_attributes (smb.base.SharedFile attribute)</a>
214 </dt>
215
216
217 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.file_size">file_size (smb.base.SharedFile attribute)</a>
218 </dt>
219
220 </dl></td>
221 <td style="width: 33%" valign="top"><dl>
222
223 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.filename">filename (smb.base.SharedFile attribute)</a>
224 </dt>
225
226 </dl></td>
137 <td style="width: 33%; vertical-align: top;"><ul>
138 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.file_attributes">file_attributes (smb.base.SharedFile attribute)</a>
139 </li>
140 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.file_id">file_id (smb.base.SharedFile attribute)</a>
141 </li>
142 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.file_size">file_size (smb.base.SharedFile attribute)</a>
143 </li>
144 </ul></td>
145 <td style="width: 33%; vertical-align: top;"><ul>
146 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.filename">filename (smb.base.SharedFile attribute)</a>
147 </li>
148 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACE.flags">flags (smb.security_descriptors.ACE attribute)</a>
149
150 <ul>
151 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SecurityDescriptor.flags">(smb.security_descriptors.SecurityDescriptor attribute)</a>
152 </li>
153 </ul></li>
154 </ul></td>
227155 </tr></table>
228156
229157 <h2 id="G">G</h2>
230158 <table style="width: 100%" class="indextable genindextable"><tr>
231 <td style="width: 33%" valign="top"><dl>
232
233 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.getAttributes">getAttributes() (smb.SMBConnection.SMBConnection method)</a>
234 </dt>
235
236 <dd><dl>
237
238 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.getAttributes">(smb.SMBProtocol.SMBProtocolFactory method)</a>
239 </dt>
240
241 </dl></dd>
242 </dl></td>
159 <td style="width: 33%; vertical-align: top;"><ul>
160 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.getAttributes">getAttributes() (smb.SMBConnection.SMBConnection method)</a>
161 </li>
162 </ul></td>
163 <td style="width: 33%; vertical-align: top;"><ul>
164 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.getSecurity">getSecurity() (smb.SMBConnection.SMBConnection method)</a>
165 </li>
166 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SecurityDescriptor.group">group (smb.security_descriptors.SecurityDescriptor attribute)</a>
167 </li>
168 </ul></td>
243169 </tr></table>
244170
245171 <h2 id="I">I</h2>
246172 <table style="width: 100%" class="indextable genindextable"><tr>
247 <td style="width: 33%" valign="top"><dl>
248
249 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.instance">instance (smb.SMBProtocol.SMBProtocolFactory attribute)</a>
250 </dt>
251
252
253 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.isDirectory">isDirectory (smb.base.SharedFile attribute)</a>
254 </dt>
255
256
257 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.isReadOnly">isReadOnly (smb.base.SharedFile attribute)</a>
258 </dt>
259
260
261 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.isReady">isReady (smb.SMBProtocol.SMBProtocolFactory attribute)</a>
262 </dt>
263
264 </dl></td>
265 <td style="width: 33%" valign="top"><dl>
266
267 <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.isSpecial">isSpecial (smb.base.SharedDevice attribute)</a>
268 </dt>
269
270
271 <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.isTemporary">isTemporary (smb.base.SharedDevice attribute)</a>
272 </dt>
273
274
275 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.isUsingSMB2">isUsingSMB2 (smb.SMBConnection.SMBConnection attribute)</a>
276 </dt>
277
278 <dd><dl>
279
280 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.isUsingSMB2">(smb.SMBProtocol.SMBProtocolFactory attribute)</a>
281 </dt>
282
283 </dl></dd>
284 </dl></td>
173 <td style="width: 33%; vertical-align: top;"><ul>
174 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SID.identifier_authority">identifier_authority (smb.security_descriptors.SID attribute)</a>
175 </li>
176 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.isDirectory">isDirectory (smb.base.SharedFile property)</a>
177 </li>
178 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACE.isInheritOnly">isInheritOnly (smb.security_descriptors.ACE property)</a>
179 </li>
180 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.isNormal">isNormal (smb.base.SharedFile property)</a>
181 </li>
182 </ul></td>
183 <td style="width: 33%; vertical-align: top;"><ul>
184 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.isReadOnly">isReadOnly (smb.base.SharedFile property)</a>
185 </li>
186 <li><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.isSpecial">isSpecial (smb.base.SharedDevice property)</a>
187 </li>
188 <li><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.isTemporary">isTemporary (smb.base.SharedDevice property)</a>
189 </li>
190 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.isUsingSMB2">isUsingSMB2 (smb.SMBConnection.SMBConnection property)</a>
191 </li>
192 </ul></td>
285193 </tr></table>
286194
287195 <h2 id="L">L</h2>
288196 <table style="width: 100%" class="indextable genindextable"><tr>
289 <td style="width: 33%" valign="top"><dl>
290
291 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.last_access_time">last_access_time (smb.base.SharedFile attribute)</a>
292 </dt>
293
294
295 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.last_attr_change_time">last_attr_change_time (smb.base.SharedFile attribute)</a>
296 </dt>
297
298
299 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.last_write_time">last_write_time (smb.base.SharedFile attribute)</a>
300 </dt>
301
302 </dl></td>
303 <td style="width: 33%" valign="top"><dl>
304
305 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listPath">listPath() (smb.SMBConnection.SMBConnection method)</a>
306 </dt>
307
308 <dd><dl>
309
310 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.listPath">(smb.SMBProtocol.SMBProtocolFactory method)</a>
311 </dt>
312
313 </dl></dd>
314
315 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listShares">listShares() (smb.SMBConnection.SMBConnection method)</a>
316 </dt>
317
318 <dd><dl>
319
320 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.listShares">(smb.SMBProtocol.SMBProtocolFactory method)</a>
321 </dt>
322
323 </dl></dd>
324
325 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listSnapshots">listSnapshots() (smb.SMBConnection.SMBConnection method)</a>
326 </dt>
327
328 <dd><dl>
329
330 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.listSnapshots">(smb.SMBProtocol.SMBProtocolFactory method)</a>
331 </dt>
332
333 </dl></dd>
334 </dl></td>
197 <td style="width: 33%; vertical-align: top;"><ul>
198 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.last_access_time">last_access_time (smb.base.SharedFile attribute)</a>
199 </li>
200 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.last_attr_change_time">last_attr_change_time (smb.base.SharedFile attribute)</a>
201 </li>
202 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.last_write_time">last_write_time (smb.base.SharedFile attribute)</a>
203 </li>
204 </ul></td>
205 <td style="width: 33%; vertical-align: top;"><ul>
206 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listPath">listPath() (smb.SMBConnection.SMBConnection method)</a>
207 </li>
208 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listShares">listShares() (smb.SMBConnection.SMBConnection method)</a>
209 </li>
210 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listSnapshots">listSnapshots() (smb.SMBConnection.SMBConnection method)</a>
211 </li>
212 </ul></td>
213 </tr></table>
214
215 <h2 id="M">M</h2>
216 <table style="width: 100%" class="indextable genindextable"><tr>
217 <td style="width: 33%; vertical-align: top;"><ul>
218 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACE.mask">mask (smb.security_descriptors.ACE attribute)</a>
219 </li>
220 </ul></td>
221 <td style="width: 33%; vertical-align: top;"><ul>
222 <li>
223 module
224
225 <ul>
226 <li><a href="api/smb_security_descriptors.html#module-smb.security_descriptors">smb.security_descriptors</a>
227 </li>
228 </ul></li>
229 </ul></td>
335230 </tr></table>
336231
337232 <h2 id="N">N</h2>
338233 <table style="width: 100%" class="indextable genindextable"><tr>
339 <td style="width: 33%" valign="top"><dl>
340
341 <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.name">name (smb.base.SharedDevice attribute)</a>
342 </dt>
343
344
345 <dt><a href="api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol">NBNSProtocol (class in nmb.NetBIOSProtocol)</a>
346 </dt>
347
348
349 <dt><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS">NetBIOS (class in nmb.NetBIOS)</a>
350 </dt>
351
352 </dl></td>
353 <td style="width: 33%" valign="top"><dl>
354
355 <dt><a href="api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NetBIOSTimeout">NetBIOSTimeout (class in nmb.NetBIOSProtocol)</a>
356 </dt>
357
358
359 <dt><a href="api/smb_exceptions.html#smb.base.NotConnectedError">NotConnectedError (class in smb.base)</a>
360 </dt>
361
362
363 <dt><a href="api/smb_exceptions.html#smb.base.NotReadyError">NotReadyError (class in smb.base)</a>
364 </dt>
365
366 </dl></td>
234 <td style="width: 33%; vertical-align: top;"><ul>
235 <li><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.name">name (smb.base.SharedDevice attribute)</a>
236 </li>
237 <li><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS">NetBIOS (class in nmb.NetBIOS)</a>
238 </li>
239 </ul></td>
240 <td style="width: 33%; vertical-align: top;"><ul>
241 <li><a href="api/smb_exceptions.html#smb.base.NotConnectedError">NotConnectedError (class in smb.base)</a>
242 </li>
243 <li><a href="api/smb_exceptions.html#smb.base.NotReadyError">NotReadyError (class in smb.base)</a>
244 </li>
245 </ul></td>
367246 </tr></table>
368247
369248 <h2 id="O">O</h2>
370249 <table style="width: 100%" class="indextable genindextable"><tr>
371 <td style="width: 33%" valign="top"><dl>
372
373 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.onAuthFailed">onAuthFailed() (smb.SMBProtocol.SMBProtocolFactory method)</a>
374 </dt>
375
376
377 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.onAuthOK">onAuthOK() (smb.SMBProtocol.SMBProtocolFactory method)</a>
378 </dt>
379
380 </dl></td>
381 <td style="width: 33%" valign="top"><dl>
382
383 <dt><a href="api/smb_exceptions.html#smb.smb_structs.OperationFailure">OperationFailure (class in smb.smb_structs)</a>
384 </dt>
385
386 </dl></td>
250 <td style="width: 33%; vertical-align: top;"><ul>
251 <li><a href="api/smb_exceptions.html#smb.smb_structs.OperationFailure">OperationFailure (class in smb.smb_structs)</a>
252 </li>
253 </ul></td>
254 <td style="width: 33%; vertical-align: top;"><ul>
255 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SecurityDescriptor.owner">owner (smb.security_descriptors.SecurityDescriptor attribute)</a>
256 </li>
257 </ul></td>
387258 </tr></table>
388259
389260 <h2 id="P">P</h2>
390261 <table style="width: 100%" class="indextable genindextable"><tr>
391 <td style="width: 33%" valign="top"><dl>
392
393 <dt><a href="api/smb_exceptions.html#smb.smb_structs.ProtocolError">ProtocolError (class in smb.smb_structs)</a>
394 </dt>
395
396 </dl></td>
262 <td style="width: 33%; vertical-align: top;"><ul>
263 <li><a href="api/smb_exceptions.html#smb.smb_structs.ProtocolError">ProtocolError (class in smb.smb_structs)</a>
264 </li>
265 </ul></td>
397266 </tr></table>
398267
399268 <h2 id="Q">Q</h2>
400269 <table style="width: 100%" class="indextable genindextable"><tr>
401 <td style="width: 33%" valign="top"><dl>
402
403 <dt><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.queryIPForName">queryIPForName() (nmb.NetBIOS.NetBIOS method)</a>
404 </dt>
405
406 <dd><dl>
407
408 <dt><a href="api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.queryIPForName">(nmb.NetBIOSProtocol.NBNSProtocol method)</a>
409 </dt>
410
411 </dl></dd>
412 </dl></td>
413 <td style="width: 33%" valign="top"><dl>
414
415 <dt><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.queryName">queryName() (nmb.NetBIOS.NetBIOS method)</a>
416 </dt>
417
418 <dd><dl>
419
420 <dt><a href="api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.queryName">(nmb.NetBIOSProtocol.NBNSProtocol method)</a>
421 </dt>
422
423 </dl></dd>
424 </dl></td>
270 <td style="width: 33%; vertical-align: top;"><ul>
271 <li><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.queryIPForName">queryIPForName() (nmb.NetBIOS.NetBIOS method)</a>
272 </li>
273 </ul></td>
274 <td style="width: 33%; vertical-align: top;"><ul>
275 <li><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.queryName">queryName() (nmb.NetBIOS.NetBIOS method)</a>
276 </li>
277 </ul></td>
425278 </tr></table>
426279
427280 <h2 id="R">R</h2>
428281 <table style="width: 100%" class="indextable genindextable"><tr>
429 <td style="width: 33%" valign="top"><dl>
430
431 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.rename">rename() (smb.SMBConnection.SMBConnection method)</a>
432 </dt>
433
434 <dd><dl>
435
436 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.rename">(smb.SMBProtocol.SMBProtocolFactory method)</a>
437 </dt>
438
439 </dl></dd>
440
441 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.resetFileAttributes">resetFileAttributes() (smb.SMBConnection.SMBConnection method)</a>
442 </dt>
443
444 </dl></td>
445 <td style="width: 33%" valign="top"><dl>
446
447 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFile">retrieveFile() (smb.SMBConnection.SMBConnection method)</a>
448 </dt>
449
450 <dd><dl>
451
452 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.retrieveFile">(smb.SMBProtocol.SMBProtocolFactory method)</a>
453 </dt>
454
455 </dl></dd>
456
457 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFileFromOffset">retrieveFileFromOffset() (smb.SMBConnection.SMBConnection method)</a>
458 </dt>
459
460 <dd><dl>
461
462 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.retrieveFileFromOffset">(smb.SMBProtocol.SMBProtocolFactory method)</a>
463 </dt>
464
465 </dl></dd>
466 </dl></td>
282 <td style="width: 33%; vertical-align: top;"><ul>
283 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.rename">rename() (smb.SMBConnection.SMBConnection method)</a>
284 </li>
285 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.resetFileAttributes">resetFileAttributes() (smb.SMBConnection.SMBConnection method)</a>
286 </li>
287 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFile">retrieveFile() (smb.SMBConnection.SMBConnection method)</a>
288 </li>
289 </ul></td>
290 <td style="width: 33%; vertical-align: top;"><ul>
291 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFileFromOffset">retrieveFileFromOffset() (smb.SMBConnection.SMBConnection method)</a>
292 </li>
293 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACL.revision">revision (smb.security_descriptors.ACL attribute)</a>
294
295 <ul>
296 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SID.revision">(smb.security_descriptors.SID attribute)</a>
297 </li>
298 </ul></li>
299 </ul></td>
467300 </tr></table>
468301
469302 <h2 id="S">S</h2>
470303 <table style="width: 100%" class="indextable genindextable"><tr>
471 <td style="width: 33%" valign="top"><dl>
472
473 <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice">SharedDevice (class in smb.base)</a>
474 </dt>
475
476
477 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile">SharedFile (class in smb.base)</a>
478 </dt>
479
480
481 <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.short_name">short_name (smb.base.SharedFile attribute)</a>
482 </dt>
483
484
485 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.SIGN_NEVER">SIGN_NEVER (smb.SMBConnection.SMBConnection attribute)</a>
486 </dt>
487
488 <dd><dl>
489
490 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.SIGN_NEVER">(smb.SMBProtocol.SMBProtocolFactory attribute)</a>
491 </dt>
492
493 </dl></dd>
494
495 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.SIGN_WHEN_REQUIRED">SIGN_WHEN_REQUIRED (smb.SMBConnection.SMBConnection attribute)</a>
496 </dt>
497
498 <dd><dl>
499
500 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.SIGN_WHEN_REQUIRED">(smb.SMBProtocol.SMBProtocolFactory attribute)</a>
501 </dt>
502
503 </dl></dd>
504
505 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.SIGN_WHEN_SUPPORTED">SIGN_WHEN_SUPPORTED (smb.SMBConnection.SMBConnection attribute)</a>
506 </dt>
507
508 <dd><dl>
509
510 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.SIGN_WHEN_SUPPORTED">(smb.SMBProtocol.SMBProtocolFactory attribute)</a>
511 </dt>
512
513 </dl></dd>
514 </dl></td>
515 <td style="width: 33%" valign="top"><dl>
516
517 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection">SMBConnection (class in smb.SMBConnection)</a>
518 </dt>
519
520
521 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory">SMBProtocolFactory (class in smb.SMBProtocol)</a>
522 </dt>
523
524
525 <dt><a href="api/smb_exceptions.html#smb.base.SMBTimeout">SMBTimeout (class in smb.base)</a>
526 </dt>
527
528
529 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.storeFile">storeFile() (smb.SMBConnection.SMBConnection method)</a>
530 </dt>
531
532 <dd><dl>
533
534 <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.storeFile">(smb.SMBProtocol.SMBProtocolFactory method)</a>
535 </dt>
536
537 </dl></dd>
538
539 <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.storeFileFromOffset">storeFileFromOffset() (smb.SMBConnection.SMBConnection method)</a>
540 </dt>
541
542 </dl></td>
304 <td style="width: 33%; vertical-align: top;"><ul>
305 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SecurityDescriptor.sacl">sacl (smb.security_descriptors.SecurityDescriptor attribute)</a>
306 </li>
307 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SecurityDescriptor">SecurityDescriptor (class in smb.security_descriptors)</a>
308 </li>
309 <li><a href="api/smb_SharedDevice.html#smb.base.SharedDevice">SharedDevice (class in smb.base)</a>
310 </li>
311 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile">SharedFile (class in smb.base)</a>
312 </li>
313 <li><a href="api/smb_SharedFile.html#smb.base.SharedFile.short_name">short_name (smb.base.SharedFile attribute)</a>
314 </li>
315 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SID">SID (class in smb.security_descriptors)</a>
316 </li>
317 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACE.sid">sid (smb.security_descriptors.ACE attribute)</a>
318 </li>
319 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.SIGN_NEVER">SIGN_NEVER (smb.SMBConnection.SMBConnection attribute)</a>
320 </li>
321 </ul></td>
322 <td style="width: 33%; vertical-align: top;"><ul>
323 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.SIGN_WHEN_REQUIRED">SIGN_WHEN_REQUIRED (smb.SMBConnection.SMBConnection attribute)</a>
324 </li>
325 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.SIGN_WHEN_SUPPORTED">SIGN_WHEN_SUPPORTED (smb.SMBConnection.SMBConnection attribute)</a>
326 </li>
327 <li>
328 smb.security_descriptors
329
330 <ul>
331 <li><a href="api/smb_security_descriptors.html#module-smb.security_descriptors">module</a>
332 </li>
333 </ul></li>
334 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection">SMBConnection (class in smb.SMBConnection)</a>
335 </li>
336 <li><a href="api/smb_exceptions.html#smb.base.SMBTimeout">SMBTimeout (class in smb.base)</a>
337 </li>
338 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.storeFile">storeFile() (smb.SMBConnection.SMBConnection method)</a>
339 </li>
340 <li><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.storeFileFromOffset">storeFileFromOffset() (smb.SMBConnection.SMBConnection method)</a>
341 </li>
342 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.SID.subauthorities">subauthorities (smb.security_descriptors.SID attribute)</a>
343 </li>
344 </ul></td>
543345 </tr></table>
544346
545347 <h2 id="T">T</h2>
546348 <table style="width: 100%" class="indextable genindextable"><tr>
547 <td style="width: 33%" valign="top"><dl>
548
549 <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.type">type (smb.base.SharedDevice attribute)</a>
550 </dt>
551
552 </dl></td>
349 <td style="width: 33%; vertical-align: top;"><ul>
350 <li><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.type">type (smb.base.SharedDevice property)</a>
351
352 <ul>
353 <li><a href="api/smb_security_descriptors.html#smb.security_descriptors.ACE.type">(smb.security_descriptors.ACE attribute)</a>
354 </li>
355 </ul></li>
356 </ul></td>
553357 </tr></table>
554358
555359 <h2 id="U">U</h2>
556360 <table style="width: 100%" class="indextable genindextable"><tr>
557 <td style="width: 33%" valign="top"><dl>
558
559 <dt><a href="api/smb_exceptions.html#smb.smb_structs.UnsupportedFeature">UnsupportedFeature (class in smb.smb_structs)</a>
560 </dt>
561
562 </dl></td>
563 </tr></table>
564
565
566
361 <td style="width: 33%; vertical-align: top;"><ul>
362 <li><a href="api/smb_exceptions.html#smb.smb_structs.UnsupportedFeature">UnsupportedFeature (class in smb.smb_structs)</a>
363 </li>
364 </ul></td>
365 </tr></table>
366
367
368
369 <div class="clearer"></div>
567370 </div>
371 </div>
372 </div>
373 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
374 <div class="sphinxsidebarwrapper">
375 <div id="searchbox" style="display: none" role="search">
376 <h3 id="searchlabel">Quick search</h3>
377 <div class="searchformwrapper">
378 <form class="search" action="search.html" method="get">
379 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
380 <input type="submit" value="Go" />
381 </form>
382 </div>
383 </div>
384 <script>document.getElementById('searchbox').style.display = "block"</script>
568385 </div>
569386 </div>
570387 <div class="clearer"></div>
575392 <li class="right" style="margin-right: 10px">
576393 <a href="#" title="General Index"
577394 >index</a></li>
578 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
395 <li class="right" >
396 <a href="py-modindex.html" title="Python Module Index"
397 >modules</a> |</li>
398 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
399 <li class="nav-item nav-item-this"><a href="">Index</a></li>
579400 </ul>
580401 </div>
581402 <div class="footer" role="contentinfo">
582 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
583 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
403 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
404 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
584405 </div>
585406 </body>
586407 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
0
1 <!DOCTYPE html>
2
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
8 <title>Welcome to pysmb’s documentation! &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: './',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="_static/jquery.js"></script>
23 <script type="text/javascript" src="_static/underscore.js"></script>
24 <script type="text/javascript" src="_static/doctools.js"></script>
25 <link rel="top" title="pysmb 1.1.18 documentation" href="#" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>Welcome to pysmb’s documentation! &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="_static/sphinxdoc.css" />
11 <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
12 <script src="_static/jquery.js"></script>
13 <script src="_static/underscore.js"></script>
14 <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="_static/doctools.js"></script>
16 <link rel="index" title="Index" href="genindex.html" />
17 <link rel="search" title="Search" href="search.html" />
2618 <link rel="next" title="NBNSProtocol Class" href="api/nmb_NBNSProtocol.html" />
27 </head>
28 <body role="document">
19 </head><body>
2920 <div class="related" role="navigation" aria-label="related navigation">
3021 <h3>Navigation</h3>
3122 <ul>
3324 <a href="genindex.html" title="General Index"
3425 accesskey="I">index</a></li>
3526 <li class="right" >
27 <a href="py-modindex.html" title="Python Module Index"
28 >modules</a> |</li>
29 <li class="right" >
3630 <a href="api/nmb_NBNSProtocol.html" title="NBNSProtocol Class"
3731 accesskey="N">next</a> |</li>
38 <li class="nav-item nav-item-0"><a href="#">pysmb 1.1.18 documentation</a> &raquo;</li>
32 <li class="nav-item nav-item-0"><a href="#">pysmb 1.2.8 documentation</a> &#187;</li>
33 <li class="nav-item nav-item-this"><a href="">Welcome to pysmb’s documentation!</a></li>
3934 </ul>
40 </div>
41 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
42 <div class="sphinxsidebarwrapper">
43 <h3><a href="#">Table Of Contents</a></h3>
44 <ul>
45 <li><a class="reference internal" href="#">Welcome to pysmb&#8217;s documentation!</a><ul>
46 <li><a class="reference internal" href="#license">License</a></li>
47 <li><a class="reference internal" href="#credits">Credits</a></li>
48 </ul>
49 </li>
50 <li><a class="reference internal" href="#package-contents-and-description">Package Contents and Description</a></li>
51 <li><a class="reference internal" href="#using-pysmb">Using pysmb</a></li>
52 <li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
53 </ul>
54
55 <h4>Next topic</h4>
56 <p class="topless"><a href="api/nmb_NBNSProtocol.html"
57 title="next chapter">NBNSProtocol Class</a></p>
58 <div role="note" aria-label="source link">
59 <h3>This Page</h3>
60 <ul class="this-page-menu">
61 <li><a href="_sources/index.txt"
62 rel="nofollow">Show Source</a></li>
63 </ul>
64 </div>
65 <div id="searchbox" style="display: none" role="search">
66 <h3>Quick search</h3>
67 <form class="search" action="search.html" method="get">
68 <input type="text" name="q" />
69 <input type="submit" value="Go" />
70 <input type="hidden" name="check_keywords" value="yes" />
71 <input type="hidden" name="area" value="default" />
72 </form>
73 <p class="searchtip" style="font-size: 90%">
74 Enter search terms or a module, class or function name.
75 </p>
76 </div>
77 <script type="text/javascript">$('#searchbox').show(0);</script>
78 </div>
79 </div>
35 </div>
8036
8137 <div class="document">
8238 <div class="documentwrapper">
8339 <div class="bodywrapper">
8440 <div class="body" role="main">
8541
86 <div class="section" id="welcome-to-pysmb-s-documentation">
87 <h1>Welcome to pysmb&#8217;s documentation!<a class="headerlink" href="#welcome-to-pysmb-s-documentation" title="Permalink to this headline">¶</a></h1>
42 <section id="welcome-to-pysmb-s-documentation">
43 <h1>Welcome to pysmb’s documentation!<a class="headerlink" href="#welcome-to-pysmb-s-documentation" title="Permalink to this heading">¶</a></h1>
8844 <p>pysmb is a pure Python implementation of the client-side SMB/CIFS protocol (SMB1 and SMB2) which is the underlying protocol
8945 that facilitates file sharing and printing between Windows machines, as well as with Linux machines via the Samba server application.
90 pysmb is developed in Python 2.4.6, Python 2.7.1 and Python 3.2.3 and has been tested against shared folders on Windows XP SP3, Windows Vista, Windows 7 and Samba 3.x.</p>
91 <p>The latest version of pysmb is always available at the pysmb project page at <a class="reference external" href="http://miketeo.net/wp/index.php/projects/pysmb">miketeo.net</a>.</p>
92 <div class="section" id="license">
93 <h2>License<a class="headerlink" href="#license" title="Permalink to this headline">¶</a></h2>
46 pysmb is developed in Python 2.7.x and Python 3.8.x and has been tested against shared folders on Windows 7, Windows 10 and Samba 4.x.</p>
47 <p>The latest version of pysmb is always available at the pysmb project page at <a class="reference external" href="http://miketeo.net/projects/pysmb">miketeo.net</a>.</p>
48 <section id="license">
49 <h2>License<a class="headerlink" href="#license" title="Permalink to this heading">¶</a></h2>
9450 <p>pysmb itself is licensed under an opensource license.
9551 You are free to use pysmb in any applications, including for commercial purposes.
9652 For more details on the terms of use, please read the LICENSE file that comes with your pysmb source.</p>
9753 <p>pysmb depends on other 3rd-party modules whose terms of use are not covered by pysmb.
9854 Use of these modules could possibly conflict with your licensing needs. Please exercise your own discretion to determine their suitabilities.
9955 I have listed these modules in the following section.</p>
100 </div>
101 <div class="section" id="credits">
102 <h2>Credits<a class="headerlink" href="#credits" title="Permalink to this headline">¶</a></h2>
56 </section>
57 <section id="credits">
58 <h2>Credits<a class="headerlink" href="#credits" title="Permalink to this heading">¶</a></h2>
10359 <p>pysmb is not alone. It is made possible with support from other modules.</p>
10460 <ul class="simple">
105 <li><strong>pyasn1</strong> : Pure Python implementation of ASN.1 parsing and encoding (not included together with pysmb; needs to be installed separately)</li>
106 <li><strong>md4</strong> and <strong>U32</strong> : Pure Python implementation of MD4 hashing algorithm and 32-bit unsigned integer by Dmitry Rozmanov. Licensed under LGPL and included together with pysmb.</li>
107 <li><strong>pyDes</strong> : Pure Python implementation of the DES encryption algorithm by Todd Whiteman. Free domain and included together with pysmb.</li>
108 <li><strong>sha256</strong> : Pure Python implementation of SHA-256 message digest by Thomas Dixon. Licensed under MIT and included together with pysmb. This module is imported only when
109 the Python standard library (usually Python 2.4) does not provide the SHA-256 hash algorithm.</li>
61 <li><p><strong>pyasn1</strong> : Pure Python implementation of ASN.1 parsing and encoding (not included together with pysmb; needs to be installed separately)</p></li>
62 <li><p><strong>md4</strong> and <strong>U32</strong> : Pure Python implementation of MD4 hashing algorithm and 32-bit unsigned integer by Dmitry Rozmanov. Licensed under LGPL and included together with pysmb.</p></li>
63 <li><p><strong>pyDes</strong> : Pure Python implementation of the DES encryption algorithm by Todd Whiteman. Free domain and included together with pysmb.</p></li>
64 <li><p><strong>sha256</strong> : Pure Python implementation of SHA-256 message digest by Thomas Dixon. Licensed under MIT and included together with pysmb. This module is imported only when
65 the Python standard library (usually Python 2.4) does not provide the SHA-256 hash algorithm.</p></li>
11066 </ul>
11167 <p>In various places, there are references to different specifications. Most of these referenced specifications
112 can be downloaded from Microsoft web site under Microsoft&#8217;s &#8220;Open Specification Promise&#8221;. If you need to download
113 a copy of these specifications, please google for it. For example, google for &#8220;MS-CIFS&#8221; to download the CIFS specification for NT LM dialect.</p>
114 </div>
115 </div>
116 <div class="section" id="package-contents-and-description">
117 <h1>Package Contents and Description<a class="headerlink" href="#package-contents-and-description" title="Permalink to this headline">¶</a></h1>
68 can be downloaded from Microsoft web site under Microsoft’s “Open Specification Promise”. If you need to download
69 a copy of these specifications, please google for it. For example, google for “MS-CIFS” to download the CIFS specification for NT LM dialect.</p>
70 </section>
71 </section>
72 <section id="package-contents-and-description">
73 <h1>Package Contents and Description<a class="headerlink" href="#package-contents-and-description" title="Permalink to this heading">¶</a></h1>
11874 <p>pysmb is organized into 2 main packages: smb and nmb.
11975 The smb package contains all the functionalities related to Server Message Block (SMB) implementation.
12076 As an application developer, you will be importing this module into your application.
12177 Hence, please take some time to familiarize yourself with the smb package contents.</p>
12278 <ul class="simple">
123 <li><strong>nmb/base.py</strong> :
79 <li><p><strong>nmb/base.py</strong> :
12480 Contains the NetBIOSSession and NBNS abstract class which implements NetBIOS session and NetBIOS Name Service communication
125 without any network transport specifics.</li>
126 <li><strong>nmb/NetBIOS.py</strong>:
127 Provides a NBNS implementation to query IP addresses for machine names. All operations are blocking I/O.</li>
128 <li><strong>nmb/NetBIOSProtocol.py</strong> :
129 Provides the NBNS protocol implementation for use in Twisted framework.</li>
130 <li><strong>smb/base.py</strong> :
131 Contains the SMB abstract class which implements the SMB communication without any network transport specifics.</li>
132 <li><strong>smb/ntlm.py</strong> :
133 Contains the NTLMv1 and NTLMv2 authentication routines and the decoding/encoding of NTLM authentication messages within SMB messages.</li>
134 <li><strong>smb/securityblob.py</strong> :
135 Provides routines to encode/decode the NTLMSSP security blob in the SMB messages.</li>
136 <li><strong>smb/smb_constants.py</strong> :
137 All the constants used in the smb package for SMB1 protocol</li>
138 <li><strong>smb/smb_structs.py</strong> :
139 Contains the internal classes used in the SMB package for SMB1 protocol. These classes are usually used to encode/decode the parameter and data blocks of specific SMB1 message.</li>
140 <li><strong>smb/smb2_constants.py</strong> :
141 All the constants used in the smb package for SMB2 protocol</li>
142 <li><strong>smb/smb2_structs.py</strong> :
143 Contains the internal classes used in the SMB package for SMB2 protocol. These classes are usually used to encode/decode the parameter and data blocks of specific SMB2 message.</li>
144 <li><strong>smb/SMBConnection.py</strong> :
145 Contains a SMB protocol implementation. All operations are blocking I/O.</li>
146 <li><strong>smb/SMBProtocol.py</strong> :
147 Contains the SMB protocol implementation for use in the Twisted framework.</li>
148 <li><strong>smb/SMBHandler.py</strong> :
149 Provides support for &#8220;<a class="reference external" href="smb://">smb://</a>&#8221; URL in the urllib2 python package.</li>
150 </ul>
151 </div>
152 <div class="section" id="using-pysmb">
153 <h1>Using pysmb<a class="headerlink" href="#using-pysmb" title="Permalink to this headline">¶</a></h1>
154 <dl class="docutils">
155 <dt>As an application developer who is looking to use pysmb to translate NetBIOS names to IP addresses,</dt>
156 <dd><ul class="first last simple">
157 <li>To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read
158 <a class="reference internal" href="api/nmb_NetBIOS.html"><em>nmb.NetBIOS.NetBIOS</em></a> documentation.</li>
159 <li>To use pysmb in Twisted, please read <a class="reference internal" href="api/nmb_NBNSProtocol.html"><em>nmb.NetBIOSProtocol.NBNSProtocol</em></a> documentation.</li>
160 </ul>
161 </dd>
162 <dt>As an application developer who is looking to use pysmb to implement file transfer or authentication over SMB:</dt>
163 <dd><ul class="first last simple">
164 <li>To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read
165 <a class="reference internal" href="api/smb_SMBConnection.html"><em>smb.SMBConnection.SMBConnection</em></a> documentation.</li>
166 <li>To use pysmb in Twisted, please read <a class="reference internal" href="api/smb_SMBProtocolFactory.html"><em>smb.SMBProtocol.SMBProtocolFactory</em></a> documentation.</li>
167 <li>To support &#8220;<a class="reference external" href="smb://">smb://</a>&#8221; URL in urllib2 python package, read <a class="reference internal" href="api/smb_SMBHandler.html"><em>smb.SMBHandler.SMBHandler</em></a> documentation.</li>
168 </ul>
169 </dd>
170 <dt>As a software developer who is looking to modify pysmb so that you can integrate it to other network frameworks:</dt>
171 <dd><ul class="first last simple">
172 <li>Read <a class="reference internal" href="extending.html"><em>Extending pysmb For Other Frameworks</em></a></li>
81 without any network transport specifics.</p></li>
82 <li><p><strong>nmb/NetBIOS.py</strong>:
83 Provides a NBNS implementation to query IP addresses for machine names. All operations are blocking I/O.</p></li>
84 <li><p><strong>nmb/NetBIOSProtocol.py</strong> :
85 Provides the NBNS protocol implementation for use in Twisted framework.</p></li>
86 <li><p><strong>smb/base.py</strong> :
87 Contains the SMB abstract class which implements the SMB communication without any network transport specifics.</p></li>
88 <li><p><strong>smb/ntlm.py</strong> :
89 Contains the NTLMv1 and NTLMv2 authentication routines and the decoding/encoding of NTLM authentication messages within SMB messages.</p></li>
90 <li><p><strong>smb/securityblob.py</strong> :
91 Provides routines to encode/decode the NTLMSSP security blob in the SMB messages.</p></li>
92 <li><p><strong>smb/smb_constants.py</strong> :
93 All the constants used in the smb package for SMB1 protocol</p></li>
94 <li><p><strong>smb/smb_structs.py</strong> :
95 Contains the internal classes used in the SMB package for SMB1 protocol. These classes are usually used to encode/decode the parameter and data blocks of specific SMB1 message.</p></li>
96 <li><p><strong>smb/smb2_constants.py</strong> :
97 All the constants used in the smb package for SMB2 protocol</p></li>
98 <li><p><strong>smb/smb2_structs.py</strong> :
99 Contains the internal classes used in the SMB package for SMB2 protocol. These classes are usually used to encode/decode the parameter and data blocks of specific SMB2 message.</p></li>
100 <li><p><strong>smb/SMBConnection.py</strong> :
101 Contains a SMB protocol implementation. All operations are blocking I/O.</p></li>
102 <li><p><strong>smb/SMBProtocol.py</strong> :
103 Contains the SMB protocol implementation for use in the Twisted framework.</p></li>
104 <li><p><strong>smb/SMBHandler.py</strong> :
105 Provides support for “<a class="reference external" href="smb://">smb://</a>” URL in the urllib2 python package.</p></li>
106 </ul>
107 </section>
108 <section id="using-pysmb">
109 <h1>Using pysmb<a class="headerlink" href="#using-pysmb" title="Permalink to this heading">¶</a></h1>
110 <dl class="simple">
111 <dt>As an application developer who is looking to use pysmb to translate NetBIOS names to IP addresses,</dt><dd><ul class="simple">
112 <li><p>To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read
113 <a class="reference internal" href="api/nmb_NetBIOS.html"><span class="doc">nmb.NetBIOS.NetBIOS</span></a> documentation.</p></li>
114 <li><p>To use pysmb in Twisted, please read <a class="reference internal" href="api/nmb_NBNSProtocol.html"><span class="doc">nmb.NetBIOSProtocol.NBNSProtocol</span></a> documentation.</p></li>
115 </ul>
116 </dd>
117 <dt>As an application developer who is looking to use pysmb to implement file transfer or authentication over SMB:</dt><dd><ul class="simple">
118 <li><p>To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read
119 <a class="reference internal" href="api/smb_SMBConnection.html"><span class="doc">smb.SMBConnection.SMBConnection</span></a> documentation.</p></li>
120 <li><p>To use pysmb in Twisted, please read <a class="reference internal" href="api/smb_SMBProtocolFactory.html"><span class="doc">smb.SMBProtocol.SMBProtocolFactory</span></a> documentation.</p></li>
121 <li><p>To support “<a class="reference external" href="smb://">smb://</a>” URL in urllib2 python package, read <a class="reference internal" href="api/smb_SMBHandler.html"><span class="doc">smb.SMBHandler.SMBHandler</span></a> documentation.</p></li>
122 </ul>
123 </dd>
124 <dt>As a software developer who is looking to modify pysmb so that you can integrate it to other network frameworks:</dt><dd><ul class="simple">
125 <li><p>Read <a class="reference internal" href="extending.html"><span class="doc">Extending pysmb For Other Frameworks</span></a></p></li>
126 </ul>
127 </dd>
128 <dt>If you are upgrading from older pysmb versions:</dt><dd><ul class="simple">
129 <li><p>Read <a class="reference internal" href="upgrading.html"><span class="doc">Upgrading from older pysmb versions</span></a></p></li>
173130 </ul>
174131 </dd>
175132 </dl>
176 </div>
177 <div class="section" id="indices-and-tables">
178 <h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1>
133 </section>
134 <section id="indices-and-tables">
135 <h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this heading">¶</a></h1>
179136 <div class="toctree-wrapper compound">
180137 <ul>
181138 <li class="toctree-l1"><a class="reference internal" href="api/nmb_NBNSProtocol.html">NBNSProtocol Class</a></li>
186143 <li class="toctree-l1"><a class="reference internal" href="api/smb_SharedDevice.html">SharedDevice Class</a></li>
187144 <li class="toctree-l1"><a class="reference internal" href="api/smb_SharedFile.html">SharedFile Class</a></li>
188145 <li class="toctree-l1"><a class="reference internal" href="api/smb_exceptions.html">SMB Exceptions</a></li>
146 <li class="toctree-l1"><a class="reference internal" href="api/smb_security_descriptors.html">Security Descriptors</a></li>
189147 <li class="toctree-l1"><a class="reference internal" href="extending.html">Extending pysmb For Other Frameworks</a></li>
148 <li class="toctree-l1"><a class="reference internal" href="upgrading.html">Upgrading from older pysmb versions</a></li>
190149 </ul>
191150 </div>
192151 <ul class="simple">
193 <li><a class="reference internal" href="genindex.html"><span>Index</span></a></li>
194 <li><a class="reference internal" href="search.html"><span>Search Page</span></a></li>
195 </ul>
152 <li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li>
153 <li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li>
154 </ul>
155 </section>
156
157
158 <div class="clearer"></div>
159 </div>
160 </div>
161 </div>
162 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
163 <div class="sphinxsidebarwrapper">
164 <div>
165 <h3><a href="#">Table of Contents</a></h3>
166 <ul>
167 <li><a class="reference internal" href="#">Welcome to pysmb’s documentation!</a><ul>
168 <li><a class="reference internal" href="#license">License</a></li>
169 <li><a class="reference internal" href="#credits">Credits</a></li>
170 </ul>
171 </li>
172 <li><a class="reference internal" href="#package-contents-and-description">Package Contents and Description</a></li>
173 <li><a class="reference internal" href="#using-pysmb">Using pysmb</a></li>
174 <li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
175 </ul>
176
177 </div>
178 <div>
179 <h4>Next topic</h4>
180 <p class="topless"><a href="api/nmb_NBNSProtocol.html"
181 title="next chapter">NBNSProtocol Class</a></p>
182 </div>
183 <div role="note" aria-label="source link">
184 <h3>This Page</h3>
185 <ul class="this-page-menu">
186 <li><a href="_sources/index.rst.txt"
187 rel="nofollow">Show Source</a></li>
188 </ul>
189 </div>
190 <div id="searchbox" style="display: none" role="search">
191 <h3 id="searchlabel">Quick search</h3>
192 <div class="searchformwrapper">
193 <form class="search" action="search.html" method="get">
194 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
195 <input type="submit" value="Go" />
196 </form>
197 </div>
196198 </div>
197
198
199 </div>
199 <script>document.getElementById('searchbox').style.display = "block"</script>
200200 </div>
201201 </div>
202202 <div class="clearer"></div>
208208 <a href="genindex.html" title="General Index"
209209 >index</a></li>
210210 <li class="right" >
211 <a href="py-modindex.html" title="Python Module Index"
212 >modules</a> |</li>
213 <li class="right" >
211214 <a href="api/nmb_NBNSProtocol.html" title="NBNSProtocol Class"
212215 >next</a> |</li>
213 <li class="nav-item nav-item-0"><a href="#">pysmb 1.1.18 documentation</a> &raquo;</li>
216 <li class="nav-item nav-item-0"><a href="#">pysmb 1.2.8 documentation</a> &#187;</li>
217 <li class="nav-item nav-item-this"><a href="">Welcome to pysmb’s documentation!</a></li>
214218 </ul>
215219 </div>
216220 <div class="footer" role="contentinfo">
217 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
218 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
221 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
222 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
219223 </div>
220224 </body>
221225 </html>
Binary diff not shown
0
1 <!DOCTYPE html>
2
3 <html lang="en">
4 <head>
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>Python Module Index &#8212; pysmb 1.2.8 documentation</title>
8 <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
9 <link rel="stylesheet" type="text/css" href="_static/sphinxdoc.css" />
10 <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
11 <script src="_static/jquery.js"></script>
12 <script src="_static/underscore.js"></script>
13 <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
14 <script src="_static/doctools.js"></script>
15 <link rel="index" title="Index" href="genindex.html" />
16 <link rel="search" title="Search" href="search.html" />
17
18
19
20 </head><body>
21 <div class="related" role="navigation" aria-label="related navigation">
22 <h3>Navigation</h3>
23 <ul>
24 <li class="right" style="margin-right: 10px">
25 <a href="genindex.html" title="General Index"
26 accesskey="I">index</a></li>
27 <li class="right" >
28 <a href="#" title="Python Module Index"
29 >modules</a> |</li>
30 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
31 <li class="nav-item nav-item-this"><a href="">Python Module Index</a></li>
32 </ul>
33 </div>
34
35 <div class="document">
36 <div class="documentwrapper">
37 <div class="bodywrapper">
38 <div class="body" role="main">
39
40
41 <h1>Python Module Index</h1>
42
43 <div class="modindex-jumpbox">
44 <a href="#cap-s"><strong>s</strong></a>
45 </div>
46
47 <table class="indextable modindextable">
48 <tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
49 <tr class="cap" id="cap-s"><td></td><td>
50 <strong>s</strong></td><td></td></tr>
51 <tr>
52 <td><img src="_static/minus.png" class="toggler"
53 id="toggle-1" style="display: none" alt="-" /></td>
54 <td>
55 <code class="xref">smb</code></td><td>
56 <em></em></td></tr>
57 <tr class="cg-1">
58 <td></td>
59 <td>&#160;&#160;&#160;
60 <a href="api/smb_security_descriptors.html#module-smb.security_descriptors"><code class="xref">smb.security_descriptors</code></a></td><td>
61 <em>Data structures used in Windows security descriptors.</em></td></tr>
62 </table>
63
64
65 <div class="clearer"></div>
66 </div>
67 </div>
68 </div>
69 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
70 <div class="sphinxsidebarwrapper">
71 <div id="searchbox" style="display: none" role="search">
72 <h3 id="searchlabel">Quick search</h3>
73 <div class="searchformwrapper">
74 <form class="search" action="search.html" method="get">
75 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
76 <input type="submit" value="Go" />
77 </form>
78 </div>
79 </div>
80 <script>document.getElementById('searchbox').style.display = "block"</script>
81 </div>
82 </div>
83 <div class="clearer"></div>
84 </div>
85 <div class="related" role="navigation" aria-label="related navigation">
86 <h3>Navigation</h3>
87 <ul>
88 <li class="right" style="margin-right: 10px">
89 <a href="genindex.html" title="General Index"
90 >index</a></li>
91 <li class="right" >
92 <a href="#" title="Python Module Index"
93 >modules</a> |</li>
94 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
95 <li class="nav-item nav-item-this"><a href="">Python Module Index</a></li>
96 </ul>
97 </div>
98 <div class="footer" role="contentinfo">
99 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
100 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
101 </div>
102 </body>
103 </html>
0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
20
1 <!DOCTYPE html>
32
4 <html xmlns="http://www.w3.org/1999/xhtml">
3 <html lang="en">
54 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>Search &#8212; pysmb 1.2.8 documentation</title>
8 <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
9 <link rel="stylesheet" type="text/css" href="_static/sphinxdoc.css" />
710
8 <title>Search &mdash; pysmb 1.1.18 documentation</title>
9
10 <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
11 <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
12
13 <script type="text/javascript">
14 var DOCUMENTATION_OPTIONS = {
15 URL_ROOT: './',
16 VERSION: '1.1.18',
17 COLLAPSE_INDEX: false,
18 FILE_SUFFIX: '.html',
19 HAS_SOURCE: true
20 };
21 </script>
22 <script type="text/javascript" src="_static/jquery.js"></script>
23 <script type="text/javascript" src="_static/underscore.js"></script>
24 <script type="text/javascript" src="_static/doctools.js"></script>
25 <script type="text/javascript" src="_static/searchtools.js"></script>
26 <link rel="top" title="pysmb 1.1.18 documentation" href="index.html" />
27 <script type="text/javascript">
28 jQuery(function() { Search.loadIndex("searchindex.js"); });
29 </script>
30
31 <script type="text/javascript" id="searchindexloader"></script>
11 <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
12 <script src="_static/jquery.js"></script>
13 <script src="_static/underscore.js"></script>
14 <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="_static/doctools.js"></script>
16 <script src="_static/searchtools.js"></script>
17 <script src="_static/language_data.js"></script>
18 <link rel="index" title="Index" href="genindex.html" />
19 <link rel="search" title="Search" href="#" />
20 <script src="searchindex.js" defer></script>
3221
3322
34 </head>
35 <body role="document">
23 </head><body>
3624 <div class="related" role="navigation" aria-label="related navigation">
3725 <h3>Navigation</h3>
3826 <ul>
3927 <li class="right" style="margin-right: 10px">
4028 <a href="genindex.html" title="General Index"
4129 accesskey="I">index</a></li>
42 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
30 <li class="right" >
31 <a href="py-modindex.html" title="Python Module Index"
32 >modules</a> |</li>
33 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
34 <li class="nav-item nav-item-this"><a href="">Search</a></li>
4335 </ul>
44 </div>
45 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
46 <div class="sphinxsidebarwrapper">
47 </div>
48 </div>
36 </div>
4937
5038 <div class="document">
5139 <div class="documentwrapper">
5341 <div class="body" role="main">
5442
5543 <h1 id="search-documentation">Search</h1>
56 <div id="fallback" class="admonition warning">
57 <script type="text/javascript">$('#fallback').hide();</script>
44
45 <noscript>
46 <div class="admonition warning">
5847 <p>
5948 Please activate JavaScript to enable the search
6049 functionality.
6150 </p>
6251 </div>
52 </noscript>
53
54
6355 <p>
64 From here you can search these documents. Enter your search
65 words into the box below and click "search". Note that the search
66 function will automatically search for all of the words. Pages
67 containing fewer words won't appear in the result list.
56 Searching for multiple words only shows matches that contain
57 all words.
6858 </p>
59
60
6961 <form action="" method="get">
70 <input type="text" name="q" value="" />
62 <input type="text" name="q" aria-labelledby="search-documentation" value="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
7163 <input type="submit" value="search" />
7264 <span id="search-progress" style="padding-left: 10px"></span>
7365 </form>
7466
67
68
7569 <div id="search-results">
7670
7771 </div>
72
7873
74 <div class="clearer"></div>
7975 </div>
76 </div>
77 </div>
78 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
79 <div class="sphinxsidebarwrapper">
8080 </div>
8181 </div>
8282 <div class="clearer"></div>
8787 <li class="right" style="margin-right: 10px">
8888 <a href="genindex.html" title="General Index"
8989 >index</a></li>
90 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.1.18 documentation</a> &raquo;</li>
90 <li class="right" >
91 <a href="py-modindex.html" title="Python Module Index"
92 >modules</a> |</li>
93 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
94 <li class="nav-item nav-item-this"><a href="">Search</a></li>
9195 </ul>
9296 </div>
9397 <div class="footer" role="contentinfo">
94 &copy; Copyright 2001-2015, Michael Teo http://miketeo.net/.
95 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
98 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
99 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
96100 </div>
97101 </body>
98102 </html>
0 Search.setIndex({envversion:46,filenames:["api/nmb_NBNSProtocol","api/nmb_NetBIOS","api/smb_SMBConnection","api/smb_SMBHandler","api/smb_SMBProtocolFactory","api/smb_SharedDevice","api/smb_SharedFile","api/smb_exceptions","extending","index"],objects:{"nmb.NetBIOS":{NetBIOS:[1,0,1,""]},"nmb.NetBIOS.NetBIOS":{"__init__":[1,1,1,""],close:[1,1,1,""],queryIPForName:[1,1,1,""],queryName:[1,1,1,""]},"nmb.NetBIOSProtocol":{NBNSProtocol:[0,0,1,""],NetBIOSTimeout:[0,0,1,""]},"nmb.NetBIOSProtocol.NBNSProtocol":{"__init__":[0,1,1,""],queryIPForName:[0,1,1,""],queryName:[0,1,1,""]},"smb.SMBConnection":{SMBConnection:[2,0,1,""]},"smb.SMBConnection.SMBConnection":{"__init__":[2,1,1,""],SIGN_NEVER:[2,2,1,""],SIGN_WHEN_REQUIRED:[2,2,1,""],SIGN_WHEN_SUPPORTED:[2,2,1,""],close:[2,1,1,""],connect:[2,1,1,""],createDirectory:[2,1,1,""],deleteDirectory:[2,1,1,""],deleteFiles:[2,1,1,""],echo:[2,1,1,""],getAttributes:[2,1,1,""],isUsingSMB2:[2,2,1,""],listPath:[2,1,1,""],listShares:[2,1,1,""],listSnapshots:[2,1,1,""],rename:[2,1,1,""],resetFileAttributes:[2,1,1,""],retrieveFile:[2,1,1,""],retrieveFileFromOffset:[2,1,1,""],storeFile:[2,1,1,""],storeFileFromOffset:[2,1,1,""]},"smb.SMBProtocol":{SMBProtocolFactory:[4,0,1,""]},"smb.SMBProtocol.SMBProtocolFactory":{"__init__":[4,1,1,""],SIGN_NEVER:[4,2,1,""],SIGN_WHEN_REQUIRED:[4,2,1,""],SIGN_WHEN_SUPPORTED:[4,2,1,""],closeConnection:[4,1,1,""],createDirectory:[4,1,1,""],deleteDirectory:[4,1,1,""],deleteFiles:[4,1,1,""],echo:[4,1,1,""],getAttributes:[4,1,1,""],instance:[4,2,1,""],isReady:[4,2,1,""],isUsingSMB2:[4,2,1,""],listPath:[4,1,1,""],listShares:[4,1,1,""],listSnapshots:[4,1,1,""],onAuthFailed:[4,1,1,""],onAuthOK:[4,1,1,""],rename:[4,1,1,""],retrieveFile:[4,1,1,""],retrieveFileFromOffset:[4,1,1,""],storeFile:[4,1,1,""]},"smb.base":{NotConnectedError:[7,0,1,""],NotReadyError:[7,0,1,""],SMBTimeout:[7,0,1,""],SharedDevice:[5,0,1,""],SharedFile:[6,0,1,""]},"smb.base.SharedDevice":{comments:[5,2,1,""],isSpecial:[5,2,1,""],isTemporary:[5,2,1,""],name:[5,2,1,""],type:[5,2,1,""]},"smb.base.SharedFile":{alloc_size:[6,2,1,""],create_time:[6,2,1,""],file_attributes:[6,2,1,""],file_size:[6,2,1,""],filename:[6,2,1,""],isDirectory:[6,2,1,""],isReadOnly:[6,2,1,""],last_access_time:[6,2,1,""],last_attr_change_time:[6,2,1,""],last_write_time:[6,2,1,""],short_name:[6,2,1,""]},"smb.smb_structs":{OperationFailure:[7,0,1,""],ProtocolError:[7,0,1,""],UnsupportedFeature:[7,0,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute"},terms:{"3rd":9,"60kbyte":4,"\u5783\u573e\u6587\u4ef6":3,"\u6d4b\u8bd5\u6587\u4ef6\u5939":3,"__init__":[0,1,2,4,8],"abstract":9,"boolean":[0,1,2,4],"byte":[2,4,6],"case":4,"default":[2,4],"float":[0,1,4,6],"function":[0,1,2,4,9],"import":[2,3,4,9],"int":[2,4],"long":[2,4,6],"new":[1,2,4,8],"public":4,"return":[0,1,2,3,4,5,6,9],"short":6,"true":[0,1,2,4,5,6],"try":[2,4,8],"while":7,aaa:[0,1],about:[2,4,5,6],abov:8,accept:[4,8],access:[2,4,6],accur:4,acknowledg:4,across:[2,4],actual:2,add:[0,4],addcallback:[0,4],adderrback:4,address:[0,1,3,8,9],admin:5,administr:5,after:[0,1,2,4,9],again:0,against:9,algorithm:[2,4,8,9],all:[2,4,9],alloc:6,alloc_s:6,allow:[0,2,4],alon:9,alphanumer:[2,4],alreadi:2,also:[2,4,5],alwai:9,anderson:[0,1],ani:[1,2,4,6,9],appli:[2,4],applic:[0,1,4,6,9],appropri:[0,1],arbitari:[2,4],archiv:[2,4],arg:4,around:0,ascii:[2,4],asn:9,aspx:2,assert:2,asynchron:[0,2,8],attempt:2,attribut:[2,4,6],atttempt:2,auth:4,authent:[2,4,7,8,9],authenthent:4,auto:[2,4],automat:[0,1,2,4],avail:[2,4,9],avoid:4,back:[0,1,2,4],base:[2,4,5,6,7,8,9],batch:4,bbb:[0,1],been:[2,4,7,8,9],befor:[2,4],begin:[2,4],between:9,bind:[0,1],bit:[2,4,9],bitwis:[2,4],blob:9,block:[0,1,2,9],both:[2,4],briefli:8,broadcast:[0,1],buffer:8,build_open:3,busi:[2,4],call:[0,1,2,4,6,8],callback:[0,4,8],can:[0,1,2,3,4,5,8,9],cannot:[2,3,4],captur:[2,4],care:8,cc232110:2,ccc:[0,1],chang:6,charact:[2,3,4,6],choic:[2,4],choos:[2,4],cif:[1,2,4,6,7,8,9],clear:2,click:[2,4],client:[2,4,9],client_machine_nam:[2,4],close:[1,2,3,4],closeconnect:4,code:3,com:2,come:9,comm_devic:5,command:[2,4],comment:5,commerci:9,commun:[2,4,5,9],compat:[2,4],complet:[2,4,7,9],compon:[2,3,4],comput:[2,4],concurr:[2,4],configur:[2,4],conflict:9,conn:2,connect:[2,4,7,8],connecttcp:4,constant:[5,9],constructor:8,contain:[1,2,4,5,6,9],content:[2,4],continu:[2,4],contribut:[0,1],control:[2,4],conveni:[2,4,6],copi:[2,4,9],correspond:6,could:[6,9],cover:9,creat:[0,1,2,3,4,8],create_tim:6,createdirectori:[2,4],creation:[5,6],credenti:[2,4],credienti:4,current:[2,7],dat:3,data:[2,3,4,8,9],data_buf:7,datetim:[2,4],ddd:[0,1],decod:9,def:4,defer:[0,4],defin:[0,1],delet:[2,3,4],deletedirectori:[2,4],deletefil:[2,4],depend:9,describ:[2,8],descript:5,detail:[6,8,9],detect:[2,4],determin:[0,1,2,4,9],develop:[2,6,9],devic:[5,6],dialect:9,differ:[2,4,8,9],digest:9,direct:[2,4],directli:[4,6],director:3,directori:[2,3,4,6],disabl:[2,4],disconnect:[2,4,7],discret:9,disk_tre:5,dixon:9,dmitri:9,doe:[2,4,6,9],domain:[2,4,9],done:[0,1],dot:[0,1],download:[4,9],due:8,each:[1,2,4,5,6],earliest:4,echo:[2,4],edit:[2,4],either:[2,4],element:[2,4],els:[2,4],empti:[0,1,2,3,4,6],enabl:[2,4],encod:9,encount:[2,6],encrypt:9,end:[2,4],english:[2,4],enterpris:[2,4],entir:4,entri:6,eof:[2,4],errback:[0,4],error:[2,4,8],establish:[2,4],etc:4,excee:4,except:[0,4],exercis:9,exist:[2,3,4],expos:4,facilit:9,factori:4,fail:[2,4,7,8],failur:0,fallback:[2,4],fals:[0,1,2,4],familiar:9,featur:[2,4,7],feeddata:8,fh2:3,file:[2,3,4,5,6,8,9],file_attribut:[2,4,6],file_attribute_norm:2,file_fh:3,file_obj:[2,4],file_s:[4,6],filenam:[2,4,6],fileretriev:4,files:2,filter:[2,4],find:[2,4,8],first:[2,3,4],flag:[0,1,2,4],folder:[2,3,4,6,9],follow:[2,3,4,5,9],forth:5,framework:[0,4],free:[0,1,9],freeli:[2,4],from:[0,1,2,3,4,8,9],functionl:4,further:2,gener:8,getattribut:[2,4],gmt:[2,4],googl:9,guess:[2,4],handl:[4,8],hash:9,have:[0,2,8,9],held:2,help:2,henc:[2,4,9],hidden:[2,4],hope:[0,1],host:[2,3,4],hostnam:3,http:2,iana:[0,1],identifi:[2,4],idl:2,illustr:[2,3,4],immedi:[2,4],implement:[0,1,2,4,8,9],impos:[2,4],includ:[8,9],incom:0,incomplet:8,index:9,indic:[0,1,2,4],individu:4,inform:[2,4,5,6],initi:[5,8],insid:[2,4],instal:[2,4,9],instanc:[0,1,2,4,6],instanti:[0,1,4,6],instiant:[0,1],integ:[0,1,2,4,6,9],integr:[5,9],interest:[2,4],intern:[4,8,9],internet:[0,4],interprocess:5,interv:4,invok:[2,4],involv:8,ipc:5,ipv4:1,is_direct_tcp:[2,4],isdirectori:6,isreadi:4,isreadonli:6,isspeci:5,istemporari:5,isusingsmb2:[2,4],itself:[4,9],jason:[0,1],just:[0,4],keep:2,keepal:2,know:[0,1,4],known:[2,4],kwarg:4,last:6,last_access_tim:6,last_attr_change_tim:6,last_write_tim:6,latest:9,learn:[2,4],least:2,leav:[0,1,2,4],length:6,lgpl:9,librari:[2,9],like:[2,3,4],limit:[2,4,6],linux:9,list:[0,1,2,4,9],listen:[0,1],listen_port:[0,1],listenudp:0,listpath:[2,4,6],listshar:[2,4],listsnapshot:[2,4],local:[2,4],local_fil:3,look:9,loop:8,loseconnect:4,machin:[0,1,2,3,4,9],made:[2,4,9],mai:[2,4],main:9,match:[0,1,2,4],max_length:[2,4],maximum:[2,4],md4:9,mean:4,meant:2,mechan:[2,4],messag:[2,4,7,9],method:[0,1,2,3,4,6,8],microsoft:[2,9],might:[2,4],miketeo:9,mit:9,mode:[0,1],modif:6,modifi:9,modul:[2,4,9],more:[2,4,6,8,9],most:[2,4,8,9],msdn:2,multipl:[2,4],must:[0,2,4],my_nam:[2,4],mypassword:3,myuserid:3,name:[0,1,2,3,4,5,6,9],namedtemporaryfil:[2,4],nbn:[1,9],need:[2,3,4,6,8,9],neg:[2,4],net:9,netbio:0,netbiosprotocol:[0,9],netbiossess:9,netbiostimeout:0,network:[0,1,2,4,9],never:[2,4],new_path:[2,4],newer:[2,4],next:2,nmb:[0,1,9],non:[2,4],none:[0,1,2,4,5,6,7],notat:[0,1,6],notconnectederror:[4,7],note:2,notreadyerror:[4,7],now:8,ntlm:[4,8,9],ntlmssp:9,ntlmv1:[2,4,9],ntlmv2:[2,4,9],number:[0,1,2,4,6],obj:[2,4],object:[2,3,4],occur:[2,4,7],offset:[2,4],often:8,old:[2,4],old_path:[2,4],onauthfail:[4,8],onauthok:[4,8],onc:[4,8],onli:[2,3,4,6,9],onnmbsessionfail:8,open:[2,3,4,9],opensourc:9,oper:[1,2,4,7,8,9],operationfailur:[2,4,7],opportun:4,organ:9,origin:[2,4,6],other:[2,4],otherwis:[2,4],out:[2,4],over:[2,4,9],overrid:[4,8],overwritten:[2,4],own:[4,8,9],packag:3,packet:[0,1,4,8],page:[8,9],paramet:[0,1,2,3,4,8,9],parent:3,pars:9,part:8,parti:9,pass:[2,3,4],password:[2,4],path:[2,3,4],path_file_pattern:[2,4],pathnam:[2,4],pattern:[2,4],perform:[0,1,2,4,8],period:4,persist:5,place:9,pleas:9,point:3,port:[0,1,2,4],posit:[2,4],possibl:9,post:[4,8],precis:4,present:7,print:[4,9],print_queu:5,proce:4,proceed:[2,4],process:[3,8],prohibit:6,project:[0,4,9],promis:9,properti:[2,4,6],protocol:[2,4,7,9],protocolerror:7,provid:[0,1,2,3,4,8,9],pure:9,purpos:9,pyasn1:9,pyde:9,pymsb:4,pysmb:[0,2,4,7],python:[2,3,4,9],queri:[0,1,2,4,9],queryipfornam:[0,1],querynam:[0,1],queue:4,rais:[0,2,3,4,7],reactor:[0,4],read:[2,3,4,6,8,9],readi:[4,7],receiv:[0,1,2,4],refer:[2,4,5,9],referenc:9,regardless:[2,4],regular:[2,4],reject:[2,4],rel:[2,4],relat:9,releas:[1,2],remot:[1,2,4,5,6,8],remote_nam:[2,4,8],remov:0,renam:[2,4],repli:[0,1,2,4],report:8,request:[2,4],requir:[2,4,7],reserv:5,reset:2,resetfileattribut:2,resourc:[1,2,4,6],respond:2,respons:7,result:[0,2,4],retri:4,retriev:[2,3,4],retrievefil:[2,4],retrievefilefactori:4,retrievefilefromoffset:[2,4],reus:4,rfc1001:[2,3,4],right:[2,4],routin:9,rozmanov:9,safe:[2,4],samba:9,sambda:[2,4],same:[2,4],search:[2,4,9],sec:4,second:[0,1,4,6],section:9,secur:9,securityblob:9,see:[2,4,6],seek:[2,4],select:[0,1,2,4],self:[4,8],send:[0,1,2,4],separ:9,sequenti:2,seri:4,server:[2,4,5,6,8,9],server_ip:[2,4],server_nam:[2,4],servic:[1,2,4,8,9],service_nam:[2,4],session:[8,9],set:[2,4],setup:[0,1,4,8],sha256:9,sha:9,shadow:[2,4],share:[2,3,4,5,6,9],shareddevic:[2,4],sharedfil:[2,4],sharedfold:3,short_nam:6,should:[0,1,2,4,6],side:9,sign:[2,4],sign_nev:[2,4],sign_opt:[2,4],sign_when_requir:[2,4],sign_when_support:[2,4],simpl:[2,4],simpli:3,sinc:6,singl:[2,4,5],site:9,size:[4,6],smb1:[2,4,9],smb2_constant:9,smb2_struct:9,smb:[1,2,3,4,5,6],smb_constant:[2,4,9],smb_ext_file_attr:6,smb_file_attribute_xxx:[2,4],smb_messag:7,smb_struct:[2,4,7,9],smbprotocol:[4,6,9],smbtest:[2,4],smbtimeout:[4,7],snapshot:[2,4],snippet:3,sock_famili:2,socket:[1,2,8],softwar:9,some:[2,4,9],sort:2,sourc:[0,1,2,4,5,6,7,9],sp3:9,space:[2,4],special:5,specif:9,specifi:[0,1,2,4],standard:[0,1,9],start:[0,2,4],step:8,stoplisten:0,store:[2,4,6],storefil:[2,4],storefilefromoffset:2,string:[0,1,2,3,4,5,6],style:9,sub:[2,4],subclass:[4,8],subsequ:3,success:[2,8],successfulli:[2,4],suitabl:[2,9],support_smb2:[2,4],synchron:[8,9],system:[2,4],take:[8,9],target:[0,1],tcp:[2,4,8],technic:[2,8],tempfil:[2,4],temporari:5,term:9,termin:[2,4],test:9,than:[2,4],thei:9,therefor:2,thi:[0,1,2,4,5,6,8,9],thoma:9,those:4,thousand:4,through:4,time:[2,4,5,6,9],timeout:[0,1,2,4,7],todd:9,togeth:9,too:2,total:6,touch:[0,1,4],transfer:[4,9],translat:9,transmit:4,transport:[0,4,9],truncat:2,tupl:[2,4],twist:[0,4,9],txt:[2,3,4],type:5,u32:9,udp:[0,1],ultim:[2,4],under:9,underli:[1,2,4,7,9],unicod:[2,3,4,5,6],unless:[0,1],unlock:2,unsign:9,unsupportedfeatur:7,until:[1,2,4],upload:[2,3,4],upload_fil:3,url:[3,9],urlerror:3,urllib2:[3,9],use_ntlm_v2:[2,4,8],user:[2,4,5],userid:[2,4],usernam:[2,4],usual:[2,4,6,8,9],utc:[2,4],utf:3,util:[2,4],valid:3,valu:[2,4,6],variou:9,veri:2,version:9,via:[0,4,6,9],vista:[2,4,9],wait:[0,1,4,7],want:[4,9],web:9,well:9,what:[0,1,2,4,8],when:[0,1,2,4,7,8,9],where:[2,4,6,9],whether:[2,4],which:[0,1,2,4,6,8,9],whiteman:9,who:[2,4,9],whose:9,wider:[2,4],wildcard:[2,4],window:[2,3,4,6,9],wish:[1,2],within:[2,4,9],without:[0,9],workgroup:[2,4],wrap:0,write:[2,4,8],write_result:4,written:[2,4],wrong:8,yet:7,you:[0,1,2,3,4,6,8,9],your:[0,1,2,4,6,8,9],yourself:9,zero:[0,1,2,4],zone:[2,4]},titles:["NBNSProtocol Class","NetBIOS class","SMBConnection Class","SMbHandler Class","SMBProtocolFactory Class","SharedDevice Class","SharedFile Class","SMB Exceptions","Extending pysmb For Other Frameworks","Welcome to pysmb&#8217;s documentation!"],titleterms:{"class":[0,1,2,3,4,5,6],caveat:[2,4],content:9,credit:9,descript:9,document:9,exampl:[2,3,4],except:7,extend:8,framework:8,indic:9,licens:9,nbnsprotocol:0,netbio:1,note:3,other:8,packag:9,pysmb:[8,9],shareddevic:5,sharedfil:6,smb2:[2,4],smb:7,smbconnect:2,smbhandler:3,smbprotocolfactori:4,support:[2,4],tabl:9,welcom:9}})
0 Search.setIndex({"docnames": ["api/nmb_NBNSProtocol", "api/nmb_NetBIOS", "api/smb_SMBConnection", "api/smb_SMBHandler", "api/smb_SMBProtocolFactory", "api/smb_SharedDevice", "api/smb_SharedFile", "api/smb_exceptions", "api/smb_security_descriptors", "extending", "index", "upgrading"], "filenames": ["api/nmb_NBNSProtocol.rst", "api/nmb_NetBIOS.rst", "api/smb_SMBConnection.rst", "api/smb_SMBHandler.rst", "api/smb_SMBProtocolFactory.rst", "api/smb_SharedDevice.rst", "api/smb_SharedFile.rst", "api/smb_exceptions.rst", "api/smb_security_descriptors.rst", "extending.rst", "index.rst", "upgrading.rst"], "titles": ["NBNSProtocol Class", "NetBIOS class", "SMBConnection Class", "SMbHandler Class", "SMBProtocolFactory Class", "SharedDevice Class", "SharedFile Class", "SMB Exceptions", "Security Descriptors", "Extending pysmb For Other Frameworks", "Welcome to pysmb\u2019s documentation!", "Upgrading from older pysmb versions"], "terms": {"pysmb": [0, 2, 4, 6, 7], "ha": [0, 2, 4, 6, 7, 9, 10, 11], "implement": [0, 1, 2, 4, 8, 9, 10], "twist": [0, 4, 10], "framework": [0, 4, 10], "thi": [0, 1, 2, 4, 5, 6, 8, 9, 10, 11], "allow": [0, 2], "you": [0, 1, 2, 3, 4, 6, 9, 10, 11], "perform": [0, 1, 2, 4, 6, 9], "name": [0, 1, 2, 3, 4, 5, 6, 10, 11], "queri": [0, 1, 2, 10, 11], "asynchron": [0, 2, 9], "without": [0, 2, 10], "have": [0, 2, 9, 10, 11], "your": [0, 1, 2, 3, 4, 6, 9, 10, 11], "applic": [0, 1, 4, 6, 10, 11], "block": [0, 1, 2, 10], "wait": [0, 1, 4, 7], "result": [0, 2, 4], "In": [0, 2, 3, 4, 9, 10], "project": [0, 4, 10], "creat": [0, 1, 2, 3, 4, 9], "instanc": [0, 1, 2, 4, 6, 8, 11], "just": [0, 4], "call": [0, 1, 2, 4, 6, 9], "querynam": [0, 1], "method": [0, 1, 2, 3, 4, 6, 9, 11], "which": [0, 1, 2, 6, 8, 9, 10, 11], "return": [0, 1, 2, 3, 4, 5, 6, 10, 11], "defer": [0, 4], "add": [0, 4, 11], "callback": [0, 9], "function": [0, 1, 2, 4, 10], "via": [0, 4, 6, 10], "addcallback": [0, 4], "receiv": [0, 1, 2], "when": [0, 1, 2, 4, 7, 9, 10], "ar": [0, 1, 2, 4, 5, 6, 10, 11], "done": [0, 1], "its": [0, 1, 2, 6, 9], "transport": [0, 4, 10], "stoplisten": 0, "remov": 0, "from": [0, 1, 2, 3, 4, 8, 9, 10], "reactor": [0, 4], "To": [1, 2, 4, 10], "us": [1, 2, 4, 6, 11], "new": [1, 2, 4, 9, 11], "each": [1, 2, 4, 5, 6], "wish": [1, 2], "The": [1, 2, 3, 4, 5, 6, 8, 9, 10], "until": [1, 2], "repli": [1, 2], "remot": [1, 2, 3, 4, 5, 6, 9, 11], "smb": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11], "cif": [1, 2, 4, 6, 7, 9, 10], "servic": [1, 2, 3, 4, 9, 10], "timeout": [1, 2, 4, 7, 11], "close": [1, 2, 3, 4], "releas": [1, 2, 11], "underli": [1, 2, 4, 7, 10], "resourc": [1, 2, 6], "nmb": [1, 10, 11], "broadcast": 1, "true": [1, 2, 4, 5, 6, 11], "listen_port": 1, "0": [1, 2, 4, 6], "sourc": [1, 2, 5, 6, 7, 8, 10], "__init__": [1, 2, 4, 9], "instanti": [1, 6], "ipv4": 1, "udp": 1, "socket": [1, 2, 9], "listen": 1, "send": [1, 2], "nbn": [1, 10], "packet": [1, 9], "paramet": [1, 2, 3, 4, 9, 10, 11], "boolean": [1, 2], "A": [1, 2, 3, 4, 6, 8, 11], "flag": [1, 2, 4, 8], "indic": [1, 2, 8, 11], "we": [1, 2], "should": [1, 2, 4, 6, 8], "setup": [1, 4, 9], "port": [1, 2], "mode": [1, 2], "integ": [1, 2, 6, 8, 10], "specifi": [1, 2, 4, 8, 11], "number": [1, 2, 4, 6, 8, 11], "bind": 1, "If": [1, 2, 4, 6, 10, 11], "zero": [1, 2], "os": [1, 6], "automat": [1, 2, 4], "select": [1, 2], "free": [1, 10], "ani": [1, 2, 6, 10], "oper": [1, 2, 4, 7, 9, 10, 11], "after": [1, 2, 4, 10], "none": [1, 2, 6, 7], "queryipfornam": [1, 11], "ip": [1, 2, 3, 9, 10, 11], "137": 1, "30": [1, 2], "machin": [1, 2, 3, 4, 10, 11], "hope": 1, "back": [1, 2, 4], "contribut": 1, "jason": 1, "anderson": 1, "string": [1, 2, 3, 4, 5, 6], "nbnsprotocol": [1, 10, 11], "wa": [1, 11], "instiant": 1, "can": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11], "an": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "empti": [1, 2, 3, 6], "leav": [1, 2], "determin": [1, 2, 6, 10], "appropri": 1, "address": [1, 3, 9, 10, 11], "fals": [1, 2, 4], "provid": [1, 2, 3, 4, 9, 10], "target": 1, "ns": 1, "iana": 1, "standard": [1, 10], "defin": [1, 2, 6, 11], "touch": [1, 4], "unless": 1, "know": [1, 4], "what": [1, 2, 4, 9], "do": [1, 2, 3, 4, 9, 11], "float": [1, 6], "second": [1, 4, 6], "list": [1, 2, 8, 10], "contain": [1, 2, 5, 6, 10], "On": [1, 2, 6], "network": [1, 2, 10], "match": [1, 2, 4], "dot": 1, "notat": [1, 6], "aaa": 1, "bbb": 1, "ccc": 1, "ddd": 1, "suitabl": [2, 10], "develop": [2, 6, 10], "who": [2, 4, 10], "file": [2, 3, 4, 5, 6, 9, 10, 11], "server": [2, 4, 5, 6, 9, 10, 11], "sequenti": 2, "invok": 2, "complet": [2, 4, 7, 10, 11], "encount": [2, 6], "error": [2, 9], "follow": [2, 3, 4, 5, 6, 8, 10], "illustr": [2, 3, 4], "simpl": [2, 4], "retriev": [2, 3, 4, 11], "import": [2, 3, 4, 10], "tempfil": [2, 4], "There": [2, 4], "some": [2, 4, 10], "mechan": [2, 4], "captur": [2, 4], "userid": [2, 4], "password": [2, 4], "client_machine_nam": [2, 4], "server_nam": [2, 4], "server_ip": [2, 4], "arbitari": [2, 4], "ascii": [2, 4], "els": [2, 4], "connect": [2, 4, 7, 9], "reject": [2, 4], "conn": 2, "use_ntlm_v2": [2, 4, 9], "assert": 2, "139": [2, 4], "file_obj": [2, 4], "namedtemporaryfil": [2, 4], "file_attribut": [2, 4, 6], "files": 2, "retrievefil": [2, 4], "smbtest": [2, 4], "rfc1001": [2, 3, 4], "txt": [2, 3, 4], "content": [2, 4], "insid": [2, 4], "need": [2, 3, 4, 6, 9, 10], "note": [2, 4, 6], "obj": [2, 4], "posit": [2, 4], "end": [2, 4], "so": [2, 4, 5, 9, 10], "might": [2, 4], "seek": [2, 4], "read": [2, 3, 4, 6, 9, 10, 11], "begin": [2, 4], "start": [2, 4], "1": [2, 3, 4, 6, 8, 10], "util": [2, 4], "protocol": [2, 4, 7, 10], "commun": [2, 4, 5, 10], "otherwis": [2, 4], "fallback": [2, 4], "smb1": [2, 4, 10], "disabl": [2, 4], "set": [2, 4], "support_smb2": [2, 4], "smb_struct": [2, 4, 7, 10], "modul": [2, 4, 8, 10], "befor": [2, 4, 11], "It": [2, 6, 10], "meant": 2, "singl": [2, 5, 8], "more": [2, 4, 6, 9, 10], "than": [2, 4], "one": [2, 3, 4, 5, 6], "concurr": [2, 4], "same": [2, 4], "time": [2, 4, 5, 6, 10], "keep": 2, "idl": 2, "too": 2, "long": [2, 6], "i": [2, 4, 7, 9, 10], "e": [2, 4, 5, 7, 9], "most": [2, 4, 9, 10, 11], "sort": 2, "keepal": 2, "impos": [2, 4], "limit": [2, 4, 6], "client": [2, 4, 10], "fail": [2, 4, 7, 9], "respond": 2, "within": [2, 4, 10], "mai": [2, 4], "disconnect": [2, 4, 7], "usernam": 2, "my_nam": 2, "remote_nam": [2, 9], "domain": [2, 10], "sign_opt": 2, "2": [2, 3, 6, 8, 10], "is_direct_tcp": 2, "user": [2, 5, 8], "credenti": 2, "requir": [2, 7], "authent": [2, 4, 7, 9, 10], "callabl": 2, "onli": [2, 3, 6, 8, 10, 11], "proceed": 2, "been": [2, 4, 7, 9, 10], "successfulli": 2, "actual": 2, "establish": 2, "default": [2, 11], "tcp": [2, 9], "netbio": [2, 3, 9, 10, 11], "over": [2, 10], "newer": 2, "instal": [2, 10], "also": [2, 5], "direct": 2, "host": [2, 3], "445": 2, "local": [2, 3], "identifi": [2, 8], "where": [2, 3, 4, 6, 10], "origin": [2, 6], "freeli": 2, "choos": 2, "maximum": 2, "15": 2, "alphanumer": 2, "charact": [2, 3, 6], "doe": [2, 6, 10], "space": 2, "window": [2, 3, 6, 8, 10], "find": [2, 9], "out": 2, "right": 2, "click": 2, "my": 2, "comput": 2, "properti": [2, 5, 6, 8, 11], "must": [2, 3, 4], "configur": 2, "known": 2, "workgroup": [2, 11], "usual": [2, 4, 6, 9, 10], "safe": 2, "whether": 2, "ntlmv1": [2, 10], "ntlmv2": [2, 10], "algorithm": [2, 9, 10], "choic": 2, "auto": 2, "detect": 2, "henc": [2, 10], "guess": 2, "try": [2, 9], "both": 2, "sambda": 2, "vista": 2, "7": [2, 10], "enabl": 2, "xp": 2, "int": 2, "messag": [2, 7, 10], "sign": 2, "sign_when_requir": 2, "valu": [2, 6, 8], "sign_when_support": 2, "sign_nev": 2, "never": 2, "regardless": 2, "s": [2, 3, 4, 11], "access": [2, 6, 8], "occur": [2, 7], "control": [2, 8, 11], "wider": 2, "compat": 2, "termin": [2, 4], "held": 2, "sock_famili": 2, "60": 2, "attempt": 2, "least": 2, "python": [2, 3, 10], "3": [2, 3, 6, 8, 10], "x": [2, 10, 11], "infer": 2, "famili": 2, "either": 2, "af_inet": 2, "af_inet6": 2, "atttempt": 2, "success": [2, 9], "createdirectori": 2, "service_nam": 2, "path": [2, 3, 4], "directori": [2, 3, 6, 11], "unicod": [2, 3, 5, 6], "share": [2, 3, 5, 6, 10], "folder": [2, 3, 6, 10, 11], "rel": 2, "non": 2, "english": 2, "pass": [2, 3, 11], "deletedirectori": 2, "delet": [2, 3, 11], "deletefil": [2, 11], "path_file_pattern": 2, "delete_matching_fold": [2, 11], "regular": 2, "wildcard": 2, "multipl": 2, "request": [2, 3], "immedi": 2, "sub": [2, 11], "recurs": 2, "pathnam": 2, "th": 2, "filenam": [2, 6], "compon": [2, 3], "echo": 2, "data": [2, 3, 8, 9, 10], "10": [2, 10], "command": 2, "byte": [2, 6], "object": [2, 3, 8], "getattribut": [2, 11], "inform": [2, 5, 6], "about": [2, 5, 6], "cannot": [2, 3], "open": [2, 3, 10], "operationfailur": [2, 4, 7], "rais": [2, 3, 4, 7], "base": [2, 5, 6, 7, 9, 10], "sharedfil": [2, 10, 11], "attribut": [2, 5, 6, 11], "getsecur": [2, 11], "secur": [2, 10], "descriptor": [2, 10], "security_descriptor": [2, 8], "securitydescriptor": [2, 8], "listpath": [2, 6, 11], "search": [2, 10, 11], "65591": 2, "pattern": 2, "For": [2, 3, 4, 10], "simplic": 2, "normal": [2, 6, 11], "entri": [2, 6, 8, 11], "hidden": [2, 6, 11], "system": [2, 6, 8, 11], "archiv": [2, 6, 11], "ignor": [2, 6, 11], "other": [2, 6, 10, 11], "like": [2, 3, 6, 11], "compress": [2, 6, 11], "index": [2, 6, 10, 11], "spars": [2, 6, 11], "temporari": [2, 5, 6, 11], "encrypt": [2, 6, 10, 11], "all": [2, 4, 8, 10], "smb_file_attribute_readonli": 2, "smb_file_attribute_hidden": 2, "smb_file_attribute_system": 2, "smb_file_attribute_arch": 2, "smb_file_attribute_incl_norm": 2, "smb_file_attribute_directori": 2, "includ": [2, 9, 10, 11], "own": [2, 4, 9, 10], "constant": [2, 5, 6, 8, 10], "smb_file_attribute_norm": 2, "itself": [2, 8, 10], "bit": [2, 6, 10], "interest": [2, 4], "learn": [2, 4], "made": [2, 10], "up": 2, "bitwis": 2, "OR": 2, "smb_file_attribute_xxx": 2, "see": [2, 6, 8], "smb_constant": [2, 6, 10], "py": [2, 6, 10], "filter": 2, "appli": [2, 8], "listshar": 2, "shareddevic": [2, 10], "describ": [2, 9], "listsnapshot": 2, "avail": [2, 5, 6, 10], "snapshot": 2, "shadow": 2, "copi": [2, 10], "featur": [2, 7], "busi": 2, "enterpris": 2, "ultim": 2, "edit": 2, "datetim": 2, "gmt": 2, "utc": 2, "zone": 2, "renam": 2, "old_path": 2, "new_path": 2, "across": 2, "differ": [2, 9, 10], "refer": [2, 5, 6, 10, 11], "old": 2, "resetfileattribut": 2, "128": 2, "reset": 2, "unlock": 2, "veri": 2, "help": 2, "By": 2, "attr_norm": 2, "therefor": 2, "clear": 2, "http": 2, "msdn": 2, "microsoft": [2, 10], "com": [2, 3], "en": 2, "librari": [2, 10], "cc232110": 2, "aspx": 2, "further": 2, "current": [2, 7], "desir": 2, "write": [2, 9, 11], "retrievefilefromoffset": [2, 11], "offset": 2, "written": 2, "continu": 2, "eof": 2, "python3": 2, "accept": [2, 4, 9], "element": 2, "tupl": 2, "max_length": 2, "first": [2, 3], "neg": 2, "storefil": [2, 4], "store": [2, 6], "alreadi": 2, "exist": [2, 3], "truncat": [2, 11], "overwritten": 2, "upload": [2, 3], "storefilefromoffset": [2, 11], "next": 2, "isusingsmb2": 2, "conveni": [2, 6, 8], "support": [3, 6, 7, 10, 11], "url": [3, 10], "urllib2": [3, 10], "packag": 3, "fulli": 3, "qualifi": 3, "hostnam": 3, "resolv": 3, "dn": 3, "myserv": 3, "test": [3, 6, 10], "192": 3, "168": 3, "comma": 3, "separ": [3, 10], "nbname": 3, "point": 3, "subsequ": 3, "parent": 3, "urlerror": 3, "code": 3, "snippet": 3, "utf": 3, "8": [3, 6, 10], "director": 3, "build_open": 3, "fh": 3, "myuserid": 3, "mypassword": 3, "sharedfold": 3, "process": [3, 9], "simpli": 3, "fh2": 3, "u": 3, "\u6d4b\u8bd5\u6587\u4ef6\u5939": 3, "\u5783\u573e\u6587\u4ef6": 3, "dat": 3, "file_fh": 3, "local_fil": 3, "rb": 3, "upload_fil": 3, "urllib": 3, "those": 4, "want": [4, 10], "smbprotocol": [4, 6, 10], "case": 4, "directli": [4, 6], "expos": 4, "subclass": [4, 9], "overrid": [4, 9], "onauthok": [4, 9], "onauthfail": [4, 9], "post": [4, 9], "authenthent": 4, "handl": [4, 9], "onc": [4, 9], "pymsb": 4, "intern": [4, 9, 10], "readi": [4, 7], "through": 4, "public": 4, "etc": 4, "closeconnect": 4, "functionl": 4, "internet": 4, "notreadyerror": [4, 7], "except": [4, 10], "notconnectederror": [4, 7], "entir": 4, "period": 4, "errback": 4, "smbtimeout": [4, 7], "retrievefilefactori": 4, "def": 4, "self": [4, 9], "arg": 4, "kwarg": 4, "fileretriev": 4, "write_result": 4, "file_s": [4, 6], "loseconnect": 4, "d": [4, 5], "adderrback": 4, "print": [4, 10], "auth": 4, "factori": 4, "connecttcp": 4, "avoid": 4, "reus": 4, "transfer": [4, 10], "thousand": 4, "queue": 4, "batch": 4, "precis": 4, "accur": 4, "interv": 4, "5": [4, 8], "sec": 4, "type": [5, 8], "comment": 5, "devic": [5, 6], "descript": 5, "isspeci": 5, "special": 5, "reserv": 5, "interprocess": 5, "ipc": 5, "administr": 5, "admin": 5, "c": 5, "forth": 5, "istemporari": 5, "persist": 5, "creation": [5, 6], "initi": [5, 9], "integr": [5, 10], "disk_tre": 5, "print_queu": 5, "comm_devic": 5, "create_tim": 6, "last_access_tim": 6, "last_write_tim": 6, "last_attr_change_tim": 6, "alloc_s": 6, "short_nam": 6, "file_id": [6, 11], "As": [6, 10], "These": [6, 10], "smbprotocolfactori": [6, 10, 11], "short": 6, "correspond": [6, 8], "could": [6, 10, 11], "prohibit": 6, "ms": [6, 8, 10], "detail": [6, 9, 10], "sinc": 6, "1970": 6, "01": 6, "00": 6, "last": 6, "modif": 6, "chang": [6, 11], "size": 6, "total": 6, "alloc": 6, "smb_ext_file_attr": 6, "wise": 6, "statu": 6, "attr_xxx": 6, "length": [6, 8], "256": [6, 10], "repres": [6, 8, 11], "field": [6, 8], "fscc": 6, "4": [6, 8, 10], "17": 6, "isdirectori": 6, "isnorm": [6, 11], "isreadonli": [6, 11], "class": [7, 8, 9, 10, 11], "while": 7, "respons": 7, "yet": 7, "unsupportedfeatur": 7, "present": [7, 8], "protocolerror": 7, "data_buf": 7, "smb_messag": 7, "associ": 8, "structur": 8, "dtyp": 8, "sid": 8, "revis": 8, "identifier_author": 8, "subauthor": 8, "princip": 8, "group": 8, "sequenc": 8, "consist": 8, "author": 8, "variabl": 8, "alwai": [8, 10], "ac": 8, "type_": 8, "mask": 8, "additional_data": 8, "dictionari": 8, "addit": 8, "depend": [8, 10], "object_typ": 8, "inherited_object_typ": 8, "application_data": 8, "attribute_data": 8, "bitmask": 8, "aceflag": 8, "isinheritonli": 8, "inherit": 8, "mean": 8, "doesn": 8, "t": 8, "access_mask": 8, "truste": 8, "One": 8, "ace_type_": 8, "acetyp": 8, "acl": 8, "encapsul": 8, "owner": 8, "dacl": 8, "sacl": 8, "6": 8, "discretionari": 8, "restrict": 8, "audit": 8, "log": 8, "page": [9, 10, 11], "briefli": 9, "step": 9, "involv": 9, "gener": 9, "take": [9, 10], "care": 9, "Then": 9, "synchron": [9, 10], "And": 9, "now": [9, 11], "abov": 9, "technic": 9, "often": 9, "part": 9, "loop": 9, "feeddata": 9, "buffer": 9, "incomplet": 9, "session": [9, 10], "report": 9, "ntlm": [9, 10], "constructor": 9, "onnmbsessionfail": 9, "due": 9, "wrong": 9, "pure": 10, "side": 10, "smb2": 10, "facilit": 10, "between": 10, "well": 10, "linux": 10, "samba": 10, "against": 10, "latest": 10, "version": 10, "miketeo": 10, "net": 10, "under": 10, "opensourc": 10, "commerci": 10, "purpos": 10, "term": 10, "pleas": [10, 11], "come": 10, "3rd": 10, "parti": 10, "whose": 10, "cover": 10, "possibl": 10, "conflict": 10, "exercis": 10, "discret": 10, "section": 10, "alon": 10, "pyasn1": 10, "asn": 10, "pars": 10, "encod": 10, "togeth": 10, "md4": 10, "u32": 10, "hash": 10, "32": 10, "unsign": 10, "dmitri": 10, "rozmanov": 10, "lgpl": 10, "pyde": 10, "de": 10, "todd": 10, "whiteman": 10, "sha256": 10, "sha": 10, "digest": 10, "thoma": 10, "dixon": 10, "mit": 10, "variou": 10, "place": 10, "specif": 10, "referenc": 10, "download": 10, "web": 10, "site": 10, "promis": 10, "googl": 10, "exampl": 10, "nt": 10, "lm": 10, "dialect": 10, "organ": 10, "main": 10, "relat": 10, "familiar": 10, "yourself": 10, "netbiossess": 10, "abstract": 10, "o": 10, "netbiosprotocol": 10, "routin": 10, "decod": 10, "securityblob": 10, "ntlmssp": 10, "blob": 10, "smb2_constant": 10, "smb2_struct": 10, "smbconnect": [10, 11], "smbhandler": 10, "look": 10, "translat": 10, "thei": 10, "style": 10, "softwar": 10, "modifi": 10, "extend": 10, "upgrad": 10, "older": 10, "document": 11, "improv": 11, "api": 11, "incompat": 11, "previou": 11, "switch": 11, "given": 11, "context": 11, "manag": 11, "ad": 11, "filesystem": 11, "two": 11, "were": 11, "finer": 11, "rewritten": 11, "rewrit": 11}, "objects": {"nmb.NetBIOS": [[1, 0, 1, "", "NetBIOS"]], "nmb.NetBIOS.NetBIOS": [[1, 1, 1, "", "__init__"], [1, 1, 1, "", "close"], [1, 1, 1, "", "queryIPForName"], [1, 1, 1, "", "queryName"]], "smb.SMBConnection": [[2, 0, 1, "", "SMBConnection"]], "smb.SMBConnection.SMBConnection": [[2, 2, 1, "", "SIGN_NEVER"], [2, 2, 1, "", "SIGN_WHEN_REQUIRED"], [2, 2, 1, "", "SIGN_WHEN_SUPPORTED"], [2, 1, 1, "", "__init__"], [2, 1, 1, "", "close"], [2, 1, 1, "", "connect"], [2, 1, 1, "", "createDirectory"], [2, 1, 1, "", "deleteDirectory"], [2, 1, 1, "", "deleteFiles"], [2, 1, 1, "", "echo"], [2, 1, 1, "", "getAttributes"], [2, 1, 1, "", "getSecurity"], [2, 3, 1, "", "isUsingSMB2"], [2, 1, 1, "", "listPath"], [2, 1, 1, "", "listShares"], [2, 1, 1, "", "listSnapshots"], [2, 1, 1, "", "rename"], [2, 1, 1, "", "resetFileAttributes"], [2, 1, 1, "", "retrieveFile"], [2, 1, 1, "", "retrieveFileFromOffset"], [2, 1, 1, "", "storeFile"], [2, 1, 1, "", "storeFileFromOffset"]], "smb.base": [[7, 0, 1, "", "NotConnectedError"], [7, 0, 1, "", "NotReadyError"], [7, 0, 1, "", "SMBTimeout"], [5, 0, 1, "", "SharedDevice"], [6, 0, 1, "", "SharedFile"]], "smb.base.SharedDevice": [[5, 2, 1, "", "comments"], [5, 3, 1, "", "isSpecial"], [5, 3, 1, "", "isTemporary"], [5, 2, 1, "", "name"], [5, 3, 1, "", "type"]], "smb.base.SharedFile": [[6, 2, 1, "", "alloc_size"], [6, 2, 1, "", "create_time"], [6, 2, 1, "", "file_attributes"], [6, 2, 1, "", "file_id"], [6, 2, 1, "", "file_size"], [6, 2, 1, "", "filename"], [6, 3, 1, "", "isDirectory"], [6, 3, 1, "", "isNormal"], [6, 3, 1, "", "isReadOnly"], [6, 2, 1, "", "last_access_time"], [6, 2, 1, "", "last_attr_change_time"], [6, 2, 1, "", "last_write_time"], [6, 2, 1, "", "short_name"]], "smb": [[8, 4, 0, "-", "security_descriptors"]], "smb.security_descriptors": [[8, 0, 1, "", "ACE"], [8, 0, 1, "", "ACL"], [8, 0, 1, "", "SID"], [8, 0, 1, "", "SecurityDescriptor"]], "smb.security_descriptors.ACE": [[8, 2, 1, "", "additional_data"], [8, 2, 1, "", "flags"], [8, 3, 1, "", "isInheritOnly"], [8, 2, 1, "", "mask"], [8, 2, 1, "", "sid"], [8, 2, 1, "", "type"]], "smb.security_descriptors.ACL": [[8, 2, 1, "", "aces"], [8, 2, 1, "", "revision"]], "smb.security_descriptors.SID": [[8, 2, 1, "", "identifier_authority"], [8, 2, 1, "", "revision"], [8, 2, 1, "", "subauthorities"]], "smb.security_descriptors.SecurityDescriptor": [[8, 2, 1, "", "dacl"], [8, 2, 1, "", "flags"], [8, 2, 1, "", "group"], [8, 2, 1, "", "owner"], [8, 2, 1, "", "sacl"]], "smb.smb_structs": [[7, 0, 1, "", "OperationFailure"], [7, 0, 1, "", "ProtocolError"], [7, 0, 1, "", "UnsupportedFeature"]]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:attribute", "3": "py:property", "4": "py:module"}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "property", "Python property"], "4": ["py", "module", "Python module"]}, "titleterms": {"nbnsprotocol": 0, "class": [0, 1, 2, 3, 4, 5, 6], "netbio": 1, "smbconnect": 2, "exampl": [2, 3, 4], "smb2": [2, 4], "support": [2, 4], "caveat": [2, 4], "smbhandler": 3, "note": 3, "smbprotocolfactori": 4, "shareddevic": 5, "sharedfil": 6, "smb": 7, "except": 7, "secur": 8, "descriptor": 8, "extend": 9, "pysmb": [9, 10, 11], "For": 9, "other": 9, "framework": 9, "welcom": 10, "s": 10, "document": 10, "licens": 10, "credit": 10, "packag": 10, "content": 10, "descript": 10, "us": 10, "indic": 10, "tabl": 10, "upgrad": 11, "from": 11, "older": 11, "version": 11, "1": 11, "2": 11, "0": 11, "28": 11, "26": 11, "25": 11, "20": 11, "15": 11, "11": 11, "10": 11, "3": 11}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.todo": 2, "sphinx.ext.viewcode": 1, "sphinx": 56}})
0
1 <!DOCTYPE html>
2
3 <html lang="en">
4 <head>
5 <meta charset="utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
7
8 <title>Upgrading from older pysmb versions &#8212; pysmb 1.2.8 documentation</title>
9 <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
10 <link rel="stylesheet" type="text/css" href="_static/sphinxdoc.css" />
11 <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
12 <script src="_static/jquery.js"></script>
13 <script src="_static/underscore.js"></script>
14 <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
15 <script src="_static/doctools.js"></script>
16 <link rel="index" title="Index" href="genindex.html" />
17 <link rel="search" title="Search" href="search.html" />
18 <link rel="prev" title="Extending pysmb For Other Frameworks" href="extending.html" />
19 </head><body>
20 <div class="related" role="navigation" aria-label="related navigation">
21 <h3>Navigation</h3>
22 <ul>
23 <li class="right" style="margin-right: 10px">
24 <a href="genindex.html" title="General Index"
25 accesskey="I">index</a></li>
26 <li class="right" >
27 <a href="py-modindex.html" title="Python Module Index"
28 >modules</a> |</li>
29 <li class="right" >
30 <a href="extending.html" title="Extending pysmb For Other Frameworks"
31 accesskey="P">previous</a> |</li>
32 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
33 <li class="nav-item nav-item-this"><a href="">Upgrading from older pysmb versions</a></li>
34 </ul>
35 </div>
36
37 <div class="document">
38 <div class="documentwrapper">
39 <div class="bodywrapper">
40 <div class="body" role="main">
41
42 <section id="upgrading-from-older-pysmb-versions">
43 <h1>Upgrading from older pysmb versions<a class="headerlink" href="#upgrading-from-older-pysmb-versions" title="Permalink to this heading">¶</a></h1>
44 <p>This page documents the improvements and changes to the API that could be incompatible with previous releases.</p>
45 <section id="pysmb-1-2-0">
46 <h2>pysmb 1.2.0<a class="headerlink" href="#pysmb-1-2-0" title="Permalink to this heading">¶</a></h2>
47 <ul class="simple">
48 <li><p>Add new <cite>delete_matching_folders</cite> parameter to <cite>deleteFiles()</cite> method in SMBProtocolFactory and SMBConnection
49 class to support deletion of sub-folders. If you are passing timeout parameter to the <cite>deleteFiles()</cite> method
50 in your application, please switch to using named parameter for timeout.</p></li>
51 </ul>
52 </section>
53 <section id="pysmb-1-1-28">
54 <h2>pysmb 1.1.28<a class="headerlink" href="#pysmb-1-1-28" title="Permalink to this heading">¶</a></h2>
55 <ul class="simple">
56 <li><p>SharedFile instances returned from the <cite>listPath()</cite> method now has a new property
57 <cite>file_id</cite> attribute which represents the file reference number given by the remote SMB server.</p></li>
58 </ul>
59 </section>
60 <section id="pysmb-1-1-26">
61 <h2>pysmb 1.1.26<a class="headerlink" href="#pysmb-1-1-26" title="Permalink to this heading">¶</a></h2>
62 <ul class="simple">
63 <li><p>SMBConnection class can now be used as a context manager</p></li>
64 </ul>
65 </section>
66 <section id="pysmb-1-1-25">
67 <h2>pysmb 1.1.25<a class="headerlink" href="#pysmb-1-1-25" title="Permalink to this heading">¶</a></h2>
68 <ul class="simple">
69 <li><p>SharedFile class has a new property <cite>isNormal</cite> which will be True if the file is a
70 ‘normal’ file. pysmb defines a ‘normal’ file as a file entry that is not
71 read-only, not hidden, not system, not archive and not a directory;
72 it ignores other attributes like compression, indexed, sparse, temporary and encryption.</p></li>
73 <li><p><cite>listPath()</cite> method in SMBProtocolFactory and SMBConnection class will now include
74 ‘normal’ files by default if you do not specify the <cite>search</cite> parameter.</p></li>
75 </ul>
76 </section>
77 <section id="pysmb-1-1-20">
78 <h2>pysmb 1.1.20<a class="headerlink" href="#pysmb-1-1-20" title="Permalink to this heading">¶</a></h2>
79 <ul class="simple">
80 <li><p>A new method <cite>getSecurity()</cite> was added to SMBConnection and SMBProtocolFactory class.</p></li>
81 </ul>
82 </section>
83 <section id="pysmb-1-1-15">
84 <h2>pysmb 1.1.15<a class="headerlink" href="#pysmb-1-1-15" title="Permalink to this heading">¶</a></h2>
85 <ul class="simple">
86 <li><p>Add new <cite>truncate</cite> parameter to <cite>storeFileFromOffset()</cite> in SMBProtocolFactory and SMBConnection
87 class to support truncation of the file before writing. If you are passing timeout parameter
88 to the <cite>storeFileFromOffset()</cite> method in your application, please switch to using named parameter for timeout.</p></li>
89 </ul>
90 </section>
91 <section id="pysmb-1-1-11">
92 <h2>pysmb 1.1.11<a class="headerlink" href="#pysmb-1-1-11" title="Permalink to this heading">¶</a></h2>
93 <ul class="simple">
94 <li><p>A new method <cite>storeFileFromOffset()</cite> was added to SMBConnection and SMBProtocolFactory class.</p></li>
95 </ul>
96 </section>
97 <section id="pysmb-1-1-10">
98 <h2>pysmb 1.1.10<a class="headerlink" href="#pysmb-1-1-10" title="Permalink to this heading">¶</a></h2>
99 <ul class="simple">
100 <li><p>A new method <cite>getAttributes()</cite> was added to SMBConnection and SMBProtocolFactory class</p></li>
101 <li><p>SharedFile class has a new property <cite>isReadOnly</cite> to indicate the file is read-only on the remote filesystem.</p></li>
102 </ul>
103 </section>
104 <section id="pysmb-1-1-2">
105 <h2>pysmb 1.1.2<a class="headerlink" href="#pysmb-1-1-2" title="Permalink to this heading">¶</a></h2>
106 <ul class="simple">
107 <li><p><cite>queryIPForName()</cite> method in nmb.NetBIOS and nmb.NBNSProtocol class will now return only the server machine name and ignore workgroup names.</p></li>
108 </ul>
109 </section>
110 <section id="pysmb-1-0-3">
111 <h2>pysmb 1.0.3<a class="headerlink" href="#pysmb-1-0-3" title="Permalink to this heading">¶</a></h2>
112 <ul class="simple">
113 <li><p>Two new methods were added to NBNSProtocol class: <cite>queryIPForName()</cite> and <cite>NetBIOS.queryIPForName()</cite>
114 to support querying for a machine’s NetBIOS name at the given IP address.</p></li>
115 <li><p>A new method <cite>retrieveFileFromOffset()</cite> was added to SMBProtocolFactory and SMBConnection
116 to support finer control of file retrieval operation.</p></li>
117 </ul>
118 </section>
119 <section id="pysmb-1-0-0">
120 <h2>pysmb 1.0.0<a class="headerlink" href="#pysmb-1-0-0" title="Permalink to this heading">¶</a></h2>
121 <p>pysmb was completely rewritten in version 1.0.0.
122 If you are upgrading from pysmb 0.x, you most likely have to rewrite your application for the new 1.x API.</p>
123 </section>
124 </section>
125
126
127 <div class="clearer"></div>
128 </div>
129 </div>
130 </div>
131 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
132 <div class="sphinxsidebarwrapper">
133 <div>
134 <h3><a href="index.html">Table of Contents</a></h3>
135 <ul>
136 <li><a class="reference internal" href="#">Upgrading from older pysmb versions</a><ul>
137 <li><a class="reference internal" href="#pysmb-1-2-0">pysmb 1.2.0</a></li>
138 <li><a class="reference internal" href="#pysmb-1-1-28">pysmb 1.1.28</a></li>
139 <li><a class="reference internal" href="#pysmb-1-1-26">pysmb 1.1.26</a></li>
140 <li><a class="reference internal" href="#pysmb-1-1-25">pysmb 1.1.25</a></li>
141 <li><a class="reference internal" href="#pysmb-1-1-20">pysmb 1.1.20</a></li>
142 <li><a class="reference internal" href="#pysmb-1-1-15">pysmb 1.1.15</a></li>
143 <li><a class="reference internal" href="#pysmb-1-1-11">pysmb 1.1.11</a></li>
144 <li><a class="reference internal" href="#pysmb-1-1-10">pysmb 1.1.10</a></li>
145 <li><a class="reference internal" href="#pysmb-1-1-2">pysmb 1.1.2</a></li>
146 <li><a class="reference internal" href="#pysmb-1-0-3">pysmb 1.0.3</a></li>
147 <li><a class="reference internal" href="#pysmb-1-0-0">pysmb 1.0.0</a></li>
148 </ul>
149 </li>
150 </ul>
151
152 </div>
153 <div>
154 <h4>Previous topic</h4>
155 <p class="topless"><a href="extending.html"
156 title="previous chapter">Extending pysmb For Other Frameworks</a></p>
157 </div>
158 <div role="note" aria-label="source link">
159 <h3>This Page</h3>
160 <ul class="this-page-menu">
161 <li><a href="_sources/upgrading.rst.txt"
162 rel="nofollow">Show Source</a></li>
163 </ul>
164 </div>
165 <div id="searchbox" style="display: none" role="search">
166 <h3 id="searchlabel">Quick search</h3>
167 <div class="searchformwrapper">
168 <form class="search" action="search.html" method="get">
169 <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
170 <input type="submit" value="Go" />
171 </form>
172 </div>
173 </div>
174 <script>document.getElementById('searchbox').style.display = "block"</script>
175 </div>
176 </div>
177 <div class="clearer"></div>
178 </div>
179 <div class="related" role="navigation" aria-label="related navigation">
180 <h3>Navigation</h3>
181 <ul>
182 <li class="right" style="margin-right: 10px">
183 <a href="genindex.html" title="General Index"
184 >index</a></li>
185 <li class="right" >
186 <a href="py-modindex.html" title="Python Module Index"
187 >modules</a> |</li>
188 <li class="right" >
189 <a href="extending.html" title="Extending pysmb For Other Frameworks"
190 >previous</a> |</li>
191 <li class="nav-item nav-item-0"><a href="index.html">pysmb 1.2.8 documentation</a> &#187;</li>
192 <li class="nav-item nav-item-this"><a href="">Upgrading from older pysmb versions</a></li>
193 </ul>
194 </div>
195 <div class="footer" role="contentinfo">
196 &#169; Copyright 2001-2021, Michael Teo https://miketeo.net/.
197 Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.1.
198 </div>
199 </body>
200 </html>
7676 self.onNMBSessionOK()
7777 elif packet.type == NEGATIVE_SESSION_RESPONSE:
7878 self.onNMBSessionFailed()
79 elif packet.type == SESSION_KEEPALIVE:
80 # Discard keepalive packets - [RFC1002]: 5.2.2.1
81 pass
7982 else:
8083 self.log.warning('Unrecognized NMB session type: 0x%02x', packet.type)
8184
150153 opcode = (code >> 11) & 0x0F
151154 flags = (code >> 4) & 0x7F
152155 rcode = code & 0x0F
153 numnames = struct.unpack('B', data[self.HEADER_STRUCT_SIZE + 44])[0]
154156
155 if numnames > 0:
156 ret = [ ]
157 offset = self.HEADER_STRUCT_SIZE + 45
157 try:
158 numnames = struct.unpack('B', data[self.HEADER_STRUCT_SIZE + 44])[0]
158159
159 for i in range(0, numnames):
160 mynme = data[offset:offset + 15]
161 mynme = mynme.strip()
162 ret.append(( mynme, ord(data[offset+15]) ))
163 offset += 18
160 if numnames > 0:
161 ret = [ ]
162 offset = self.HEADER_STRUCT_SIZE + 45
164163
165 return trn_id, ret
166 else:
167 return trn_id, None
164 for i in range(0, numnames):
165 mynme = data[offset:offset + 15]
166 mynme = mynme.strip()
167 ret.append(( mynme, ord(data[offset+15]) ))
168 offset += 18
169
170 return trn_id, ret
171 except IndexError:
172 pass
173
174 return trn_id, None
168175
169176 #
170177 # Contributed by Jason Anderson
2020 Create a new SMBConnection instance.
2121
2222 *username* and *password* are the user credentials required to authenticate the underlying SMB connection with the remote server.
23 *password* can be a string or a callable returning a string.
2324 File operations can only be proceeded after the connection has been authenticated successfully.
2425
2526 Note that you need to call *connect* method to actually establish the SMB connection to the remote server and perform authentication.
2829 Some newer server installations might also support Direct hosting of SMB over TCP/IP; for these servers, the default TCP port is 445.
2930
3031 :param string my_name: The local NetBIOS machine name that will identify where this connection is originating from.
31 You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\/:*?";|+``
32 You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\\/:*?";|+``
3233 :param string remote_name: The NetBIOS machine name of the remote server.
3334 On windows, you can find out the machine name by right-clicking on the "My Computer" and selecting "Properties".
3435 This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.
7172 total_sent = total_sent + sent
7273
7374 #
75 # Support for "with" context
76 #
77 def __enter__(self):
78 return self
79
80 def __exit__(self, *args):
81 self.close()
82
83 #
7484 # Misc Properties
7585 #
7686
152162 return results
153163
154164 def listPath(self, service_name, path,
155 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE,
165 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL,
156166 pattern = '*', timeout = 30):
157167 """
158168 Retrieve a directory listing of files/folders at *path*
169
170 For simplicity, pysmb defines a "normal" file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.
171 It ignores other attributes like compression, indexed, sparse, temporary and encryption.
172
173 Note that the default search parameter will query for all read-only (SMB_FILE_ATTRIBUTE_READONLY), hidden (SMB_FILE_ATTRIBUTE_HIDDEN),
174 system (SMB_FILE_ATTRIBUTE_SYSTEM), archive (SMB_FILE_ATTRIBUTE_ARCHIVE), normal (SMB_FILE_ATTRIBUTE_INCL_NORMAL) files
175 and directories (SMB_FILE_ATTRIBUTE_DIRECTORY).
176 If you do not need to include "normal" files in the result, define your own search parameter without the SMB_FILE_ATTRIBUTE_INCL_NORMAL constant.
177 SMB_FILE_ATTRIBUTE_NORMAL should be used by itself and not be used with other bit constants.
159178
160179 :param string/unicode service_name: the name of the shared folder for the *path*
161180 :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders.
162181 :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py).
163 The default *search* value will query for all read-only, hidden, system, archive files and directories.
164182 :param string/unicode pattern: the filter to apply to the results before returning to the client.
165183 :return: A list of :doc:`smb.base.SharedFile<smb_SharedFile>` instances.
166184 """
244262 self.is_busy = True
245263 try:
246264 self._getAttributes(service_name, path, cb, eb, timeout)
265 while self.is_busy:
266 self._pollForNetBIOSPacket(timeout)
267 finally:
268 self.is_busy = False
269
270 return results[0]
271
272 def getSecurity(self, service_name, path, timeout = 30):
273 """
274 Retrieve the security descriptor of the file at *path* on the *service_name*.
275
276 :param string/unicode service_name: the name of the shared folder for the *path*
277 :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure<smb_exceptions>` will be raised.
278 :return: A :class:`smb.security_descriptors.SecurityDescriptor` instance containing the security information of the file.
279 """
280 if not self.sock:
281 raise NotConnectedError('Not connected to server')
282
283 results = [ ]
284
285 def cb(info):
286 self.is_busy = False
287 results.append(info)
288
289 def eb(failure):
290 self.is_busy = False
291 raise failure
292
293 self.is_busy = True
294 try:
295 self._getSecurity(service_name, path, cb, eb, timeout)
247296 while self.is_busy:
248297 self._pollForNetBIOSPacket(timeout)
249298 finally:
349398
350399 return results[0]
351400
352 def deleteFiles(self, service_name, path_file_pattern, timeout = 30):
401 def deleteFiles(self, service_name, path_file_pattern, delete_matching_folders = False, timeout = 30):
353402 """
354403 Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.
404
405 If delete_matching_folders is True, immediate sub-folders that match the path_file_pattern will be deleted recursively.
355406
356407 :param string/unicode service_name: Contains the name of the shared folder.
357408 :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.
371422
372423 self.is_busy = True
373424 try:
374 self._deleteFiles(service_name, path_file_pattern, cb, eb, timeout = timeout)
375 while self.is_busy:
376 self._pollForNetBIOSPacket(timeout)
377 finally:
378 self.is_busy = False
379
380 def resetFileAttributes(self, service_name, path_file_pattern, timeout = 30):
425 self._deleteFiles(service_name, path_file_pattern, delete_matching_folders, cb, eb, timeout = timeout)
426 while self.is_busy:
427 self._pollForNetBIOSPacket(timeout)
428 finally:
429 self.is_busy = False
430
431 def resetFileAttributes(self, service_name, path_file_pattern, file_attributes = ATTR_NORMAL, timeout = 30):
381432 """
382433 Reset file attributes of one or more regular files or folders.
383434 It supports the use of wildcards in file names, allowing for unlocking of multiple files/folders in a single request.
384435 This function is very helpful when deleting files/folders that are read-only.
385 Note: this function is currently only implemented for SMB2! Technically, it sets the FILE_ATTRIBUTE_NORMAL flag, therefore clearing all other flags. (See https://msdn.microsoft.com/en-us/library/cc232110.aspx for further information)
386
436 By default, it sets the ATTR_NORMAL flag, therefore clearing all other flags.
437 (See https://msdn.microsoft.com/en-us/library/cc232110.aspx for further information)
438
439 Note: this function is currently only implemented for SMB2!
440
387441 :param string/unicode service_name: Contains the name of the shared folder.
388442 :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.
389443 Wildcards may be used in the filename component of the path.
390444 If your path/filename contains non-English characters, you must pass in an unicode string.
445 :param int file_attributes: The desired file attributes to set. Defaults to `ATTR_NORMAL`.
391446 :return: None
392447 """
393448 if not self.sock:
402457
403458 self.is_busy = True
404459 try:
405 self._resetFileAttributes(service_name, path_file_pattern, cb, eb, timeout = timeout)
460 self._resetFileAttributes(service_name, path_file_pattern, cb, eb, file_attributes, timeout = timeout)
406461 while self.is_busy:
407462 self._pollForNetBIOSPacket(timeout)
408463 finally:
494549 """
495550 Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*.
496551
497 :param string data: Data to send to the remote server.
552 :param bytes data: Data to send to the remote server. Must be a bytes object.
498553 :return: The *data* parameter
499554 """
500555 if not self.sock:
4343 passwd = passwd or ''
4444 myname = MACHINE_NAME or self.generateClientMachineName()
4545
46 n = NetBIOS()
47 names = n.queryIPForName(host)
48 if names:
49 server_name = names[0]
50 else:
51 raise urllib2.URLError('SMB error: Hostname does not reply back with its machine name')
46 server_name,host = host.split(',') if ',' in host else [None,host]
47
48 if server_name is None:
49 n = NetBIOS()
50 names = n.queryIPForName(host)
51 if names:
52 server_name = names[0]
53 else:
54 raise urllib2.URLError('SMB error: Hostname does not reply back with its machine name')
5255
5356 path, attrs = splitattr(req.get_selector())
5457 if path.startswith('/'):
176176 return d
177177
178178 def listPath(self, service_name, path,
179 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE,
179 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL,
180180 pattern = '*', timeout = 30):
181181 """
182182 Retrieve a directory listing of files/folders at *path*
183
184 For simplicity, pysmb defines a "normal" file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.
185 It ignores other attributes like compression, indexed, sparse, temporary and encryption.
186
187 Note that the default search parameter will query for all read-only (SMB_FILE_ATTRIBUTE_READONLY), hidden (SMB_FILE_ATTRIBUTE_HIDDEN),
188 system (SMB_FILE_ATTRIBUTE_SYSTEM), archive (SMB_FILE_ATTRIBUTE_ARCHIVE), normal (SMB_FILE_ATTRIBUTE_INCL_NORMAL) files
189 and directories (SMB_FILE_ATTRIBUTE_DIRECTORY).
190 If you do not need to include "normal" files in the result, define your own search parameter without the SMB_FILE_ATTRIBUTE_INCL_NORMAL constant.
191 SMB_FILE_ATTRIBUTE_NORMAL should be used by itself and not be used with other bit constants.
183192
184193 :param string/unicode service_name: the name of the shared folder for the *path*
185194 :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders.
186195 :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py).
187 The default *search* value will query for all read-only, hidden, system, archive files and directories.
188196 :param string/unicode pattern: the filter to apply to the results before returning to the client.
189197 :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.
190198 :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of :doc:`smb.base.SharedFile<smb_SharedFile>` instances.
367375 """
368376 Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*.
369377
370 :param string data: Data to send to the remote server.
378 :param bytes data: Data to send to the remote server. Must be a bytes object.
371379 :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.
372380 :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *data* parameter.
373381 """
44 from smb2_constants import *
55 from smb_structs import *
66 from smb2_structs import *
7 from .security_descriptors import SecurityDescriptor
78 from nmb.base import NMBSession
89 from utils import convertFILETIMEtoEpoch
910 import ntlm, securityblob
5859 def __init__(self, username, password, my_name, remote_name, domain = '', use_ntlm_v2 = True, sign_options = SIGN_WHEN_REQUIRED, is_direct_tcp = False):
5960 NMBSession.__init__(self, my_name, remote_name, is_direct_tcp = is_direct_tcp)
6061 self.username = _convert_to_unicode(username)
61 self.password = _convert_to_unicode(password)
62 self._password = password
6263 self.domain = _convert_to_unicode(domain)
6364 self.sign_options = sign_options
6465 self.is_direct_tcp = is_direct_tcp
6566 self.use_ntlm_v2 = use_ntlm_v2 #: Similar to LMAuthenticationPolicy and NTAuthenticationPolicy as described in [MS-CIFS] 3.2.1.1
6667 self.smb_message = SMBMessage()
6768 self.is_using_smb2 = False #: Are we communicating using SMB2 protocol? self.smb_message will be a SMB2Message instance if this flag is True
69 self.async_requests = { } #: AsyncID mapped to _PendingRequest instance
6870 self.pending_requests = { } #: MID mapped to _PendingRequest instance
6971 self.connected_trees = { } #: Share name mapped to TID
7072 self.next_rpc_call_id = 1 #: Next RPC callID value. Not used directly in SMB message. Usually encapsulated in sub-commands under SMB_COM_TRANSACTION or SMB_COM_TRANSACTION2 messages
103105 (self.use_ntlm_v2 and 'v2') or 'v1',
104106 (SUPPORT_EXTENDED_SECURITY and 'with') or 'without')
105107
108 @property
109 def password(self):
110 password = self._password() if callable(self._password) else self._password
111 return _convert_to_unicode(password)
106112
107113 #
108114 # NMBSession Methods
172178 self._listShares = self._listShares_SMB1
173179 self._listPath = self._listPath_SMB1
174180 self._listSnapshots = self._listSnapshots_SMB1
181 self._getSecurity = self._getSecurity_SMB1
175182 self._getAttributes = self._getAttributes_SMB1
176183 self._retrieveFile = self._retrieveFile_SMB1
177184 self._retrieveFileFromOffset = self._retrieveFileFromOffset_SMB1
195202 self._listPath = self._listPath_SMB2
196203 self._listSnapshots = self._listSnapshots_SMB2
197204 self._getAttributes = self._getAttributes_SMB2
205 self._getSecurity = self._getSecurity_SMB2
198206 self._retrieveFile = self._retrieveFile_SMB2
199207 self._retrieveFileFromOffset = self._retrieveFileFromOffset_SMB2
200208 self._storeFile = self._storeFile_SMB2
218226 if smb_message.mid == 0:
219227 smb_message.mid = self._getNextMID_SMB2()
220228
221 if smb_message.command != SMB2_COM_NEGOTIATE and smb_message.command != SMB2_COM_ECHO:
229 if smb_message.command != SMB2_COM_NEGOTIATE:
222230 smb_message.session_id = self.session_id
223231
224232 if self.is_signing_active:
255263 if result == securityblob.RESULT_ACCEPT_COMPLETED:
256264 self.has_authenticated = True
257265 self.log.info('Authentication (on SMB2) successful!')
266
267 # [MS-SMB2]: 3.2.5.3.1
268 # If the security subsystem indicates that the session was established by an anonymous user,
269 # Session.SigningRequired MUST be set to FALSE.
270 # If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags field of the
271 # SMB2 SESSION_SETUP Response and if Session.SigningRequired is TRUE, this indicates a SESSION_SETUP
272 # failure and the connection MUST be terminated. If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags
273 # field of the SMB2 SESSION_SETUP Response and if RequireMessageSigning is FALSE, Session.SigningRequired
274 # MUST be set to FALSE.
275 if message.payload.isGuestSession or message.payload.isAnonymousSession:
276 self.is_signing_active = False
277 self.log.info('Signing disabled because session is guest/anonymous')
278
258279 self.onAuthOK()
259280 else:
260281 raise ProtocolError('SMB2_COM_SESSION_SETUP status is 0 but security blob negResult value is %d' % result, message.raw_data, message)
268289 self._handleSessionChallenge(message, ntlm_token)
269290 except ( securityblob.BadSecurityBlobError, securityblob.UnsupportedSecurityProvider ), ex:
270291 raise ProtocolError(str(ex), message.raw_data, message)
271 elif message.status == 0xc000006d: # STATUS_LOGON_FAILURE
292 elif (message.status == 0xc000006d # STATUS_LOGON_FAILURE
293 or message.status == 0xc0000064 # STATUS_NO_SUCH_USER
294 or message.status == 0xc000006a):# STATUS_WRONG_PASSWORD
272295 self.has_authenticated = False
273296 self.log.info('Authentication (on SMB2) failed. Please check username and password.')
274297 self.onAuthFailed()
298 elif (message.status == 0xc0000193 # STATUS_ACCOUNT_EXPIRED
299 or message.status == 0xC0000071): # STATUS_PASSWORD_EXPIRED
300 self.has_authenticated = False
301 self.log.info('Authentication (on SMB2) failed. Account or password has expired.')
302 self.onAuthFailed()
303 elif message.status == 0xc0000234: # STATUS_ACCOUNT_LOCKED_OUT
304 self.has_authenticated = False
305 self.log.info('Authentication (on SMB2) failed. Account has been locked due to too many invalid logon attempts.')
306 self.onAuthFailed()
307 elif message.status == 0xc0000072: # STATUS_ACCOUNT_DISABLED
308 self.has_authenticated = False
309 self.log.info('Authentication (on SMB2) failed. Account has been disabled.')
310 self.onAuthFailed()
311 elif (message.status == 0xc000006f # STATUS_INVALID_LOGON_HOURS
312 or message.status == 0xc000015b # STATUS_LOGON_TYPE_NOT_GRANTED
313 or message.status == 0xc0000070): # STATUS_INVALID_WORKSTATION
314 self.has_authenticated = False
315 self.log.info('Authentication (on SMB2) failed. Not allowed.')
316 self.onAuthFailed()
317 elif message.status == 0xc000018c: # STATUS_TRUSTED_DOMAIN_FAILURE
318 self.has_authenticated = False
319 self.log.info('Authentication (on SMB2) failed. Domain not trusted.')
320 self.onAuthFailed()
321 elif message.status == 0xc000018d: # STATUS_TRUSTED_RELATIONSHIP_FAILURE
322 self.has_authenticated = False
323 self.log.info('Authentication (on SMB2) failed. Workstation not trusted.')
324 self.onAuthFailed()
275325 else:
276326 raise ProtocolError('Unknown status value (0x%08X) in SMB_COM_SESSION_SETUP_ANDX (with extended security)' % message.status,
277327 message.raw_data, message)
278328
279 req = self.pending_requests.pop(message.mid, None)
280 if req:
281 req.callback(message, **req.kwargs)
282 return True
329 if message.isAsync:
330 if message.status == 0x00000103: # STATUS_PENDING
331 req = self.pending_requests.pop(message.mid, None)
332 if req:
333 self.async_requests[message.async_id] = req
334 else: # All other status including SUCCESS
335 req = self.async_requests.pop(message.async_id, None)
336 if req:
337 req.callback(message, **req.kwargs)
338 return True
339 else:
340 req = self.pending_requests.pop(message.mid, None)
341 if req:
342 req.callback(message, **req.kwargs)
343 return True
283344
284345
285346 def _updateServerInfo_SMB2(self, payload):
314375 self.log.info('Performing NTLMv1 authentication (on SMB2) with server challenge "%s"', binascii.hexlify(server_challenge))
315376 nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(self.password, server_challenge, True)
316377
317 ntlm_data = ntlm.generateAuthenticateMessage(server_flags,
318 nt_challenge_response,
319 lm_challenge_response,
320 session_key,
321 self.username,
322 self.domain)
378 ntlm_data, session_signing_key = ntlm.generateAuthenticateMessage(server_flags,
379 nt_challenge_response,
380 lm_challenge_response,
381 session_key,
382 self.username,
383 self.domain,
384 self.my_name)
323385
324386 if self.log.isEnabledFor(logging.DEBUG):
325387 self.log.debug('NT challenge response is "%s" (%d bytes)', binascii.hexlify(nt_challenge_response), len(nt_challenge_response))
339401
340402 if self.is_signing_active:
341403 self.log.info("SMB signing activated. All SMB messages will be signed.")
342 self.signing_session_key = (session_key + '\0'*16)[:16]
404 self.signing_session_key = session_signing_key
405 if self.log.isEnabledFor(logging.DEBUG):
406 self.log.info("SMB signing key is %s", binascii.hexlify(self.signing_session_key))
407
343408 if self.capabilities & CAP_EXTENDED_SECURITY:
344409 self.signing_challenge_response = None
345410 else:
368433
369434 m.tid = tid
370435 self._sendSMBMessage(m)
371 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectSrvSvcCB, errback)
436 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectSrvSvcCB, errback, tid = tid)
372437 messages_history.append(m)
373438
374439 def connectSrvSvcCB(create_message, **kwargs):
390455 01 00 00 00
391456 """.replace(' ', '').replace('\n', ''))
392457 m = SMB2Message(SMB2WriteRequest(create_message.payload.fid, data_bytes, 0))
393 m.tid = create_message.tid
458 m.tid = kwargs['tid']
394459 self._sendSMBMessage(m)
395 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, rpcBindCB, errback, fid = create_message.payload.fid)
460 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, rpcBindCB, errback, tid = kwargs['tid'], fid = create_message.payload.fid)
396461 messages_history.append(m)
397462 else:
398463 errback(OperationFailure('Failed to list shares: Unable to locate Server Service RPC endpoint', messages_history))
401466 messages_history.append(trans_message)
402467 if trans_message.status == 0:
403468 m = SMB2Message(SMB2ReadRequest(kwargs['fid'], read_len = 1024, read_offset = 0))
404 m.tid = trans_message.tid
469 m.tid = kwargs['tid']
405470 self._sendSMBMessage(m)
406 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, rpcReadCB, errback, fid = kwargs['fid'])
471 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, rpcReadCB, errback, tid = kwargs['tid'], fid = kwargs['fid'])
407472 messages_history.append(m)
408473 else:
409 closeFid(trans_message.tid, kwargs['fid'], error = 'Failed to list shares: Unable to read from Server Service RPC endpoint')
474 closeFid(kwargs['tid'], kwargs['fid'], error = 'Failed to list shares: Unable to read from Server Service RPC endpoint')
410475
411476 def rpcReadCB(read_message, **kwargs):
412477 messages_history.append(read_message)
434499 00 00 00 00 ff ff ff ff 08 00 02 00 00 00 00 00
435500 """.replace(' ', '').replace('\n', ''))
436501 m = SMB2Message(SMB2IoctlRequest(kwargs['fid'], 0x0011C017, flags = 0x01, max_out_size = 8196, in_data = data_bytes))
437 m.tid = read_message.tid
502 m.tid = kwargs['tid']
438503 self._sendSMBMessage(m)
439 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, listShareResultsCB, errback, fid = kwargs['fid'])
504 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, listShareResultsCB, errback, tid = kwargs['tid'], fid = kwargs['fid'])
440505 messages_history.append(m)
441506 else:
442 closeFid(read_message.tid, kwargs['fid'], error = 'Failed to list shares: Unable to bind to Server Service RPC endpoint')
507 closeFid(kwargs['tid'], kwargs['fid'], error = 'Failed to list shares: Unable to bind to Server Service RPC endpoint')
443508
444509 def listShareResultsCB(result_message, **kwargs):
445510 messages_history.append(result_message)
448513 data_bytes = result_message.payload.out_data
449514
450515 if ord(data_bytes[3]) & 0x02 == 0:
451 sendReadRequest(result_message.tid, kwargs['fid'], data_bytes)
452 else:
453 decodeResults(result_message.tid, kwargs['fid'], data_bytes)
454 elif result_message.status == 0x0103: # STATUS_PENDING
455 self.pending_requests[result_message.mid] = _PendingRequest(result_message.mid, expiry_time, listShareResultsCB, errback, fid = kwargs['fid'])
456 else:
457 closeFid(result_message.tid, kwargs['fid'])
516 sendReadRequest(kwargs['tid'], kwargs['fid'], data_bytes)
517 else:
518 decodeResults(kwargs['tid'], kwargs['fid'], data_bytes)
519 else:
520 closeFid(kwargs['tid'], kwargs['fid'])
458521 errback(OperationFailure('Failed to list shares: Unable to retrieve shared device list', messages_history))
459522
460523 def decodeResults(tid, fid, data_bytes):
493556 m.tid = tid
494557 self._sendSMBMessage(m)
495558 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, readCB, errback,
496 fid = fid, data_bytes = data_bytes)
559 tid = tid, fid = fid, data_bytes = data_bytes)
497560
498561 def readCB(read_message, **kwargs):
499562 messages_history.append(read_message)
500563 if read_message.status == 0:
501 data_len = read_message.payload.data_length
502564 data_bytes = read_message.payload.data
503565
504566 if ord(data_bytes[3]) & 0x02 == 0:
505 sendReadRequest(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:data_len-24])
506 else:
507 decodeResults(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:data_len-24])
508 else:
509 closeFid(read_message.tid, kwargs['fid'])
567 sendReadRequest(kwargs['tid'], kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:])
568 else:
569 decodeResults(kwargs['tid'], kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:])
570 else:
571 closeFid(kwargs['tid'], kwargs['fid'])
510572 errback(OperationFailure('Failed to list shares: Unable to retrieve shared device list', messages_history))
511573
512574 def closeFid(tid, fid, results = None, error = None):
562624 """.replace(' ', '').replace('\n', ''))
563625 m = SMB2Message(SMB2CreateRequest(path,
564626 file_attributes = 0,
565 access_mask = FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
627 access_mask = FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
566628 share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
567629 oplock = SMB2_OPLOCK_LEVEL_NONE,
568630 impersonation = SEC_IMPERSONATE,
571633 create_context_data = create_context_data))
572634 m.tid = tid
573635 self._sendSMBMessage(m)
574 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback)
636 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback, tid = tid)
575637 messages_history.append(m)
576638
577639 def createCB(create_message, **kwargs):
578640 messages_history.append(create_message)
579641 if create_message.status == 0:
580 sendQuery(create_message.tid, create_message.payload.fid, '')
642 sendQuery(kwargs['tid'], create_message.payload.fid, '')
643 elif create_message.status == 0xC0000034L: # [MS-ERREF]: STATUS_OBJECT_NAME_INVALID
644 errback(OperationFailure('Failed to list %s on %s: Path not found' % ( path, service_name ), messages_history))
581645 else:
582646 errback(OperationFailure('Failed to list %s on %s: Unable to open directory' % ( path, service_name ), messages_history))
583647
584648 def sendQuery(tid, fid, data_buf):
585649 m = SMB2Message(SMB2QueryDirectoryRequest(fid, pattern,
586 info_class = 0x03, # FileBothDirectoryInformation
650 info_class = 0x25, # FileIdBothDirectoryInformation
587651 flags = 0,
588652 output_buf_len = self.max_transact_size))
589653 m.tid = tid
590654 self._sendSMBMessage(m)
591 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, queryCB, errback, fid = fid, data_buf = data_buf)
655 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, queryCB, errback, tid = tid, fid = fid, data_buf = data_buf)
592656 messages_history.append(m)
593657
594658 def queryCB(query_message, **kwargs):
595659 messages_history.append(query_message)
596660 if query_message.status == 0:
597661 data_buf = decodeQueryStruct(kwargs['data_buf'] + query_message.payload.data)
598 sendQuery(query_message.tid, kwargs['fid'], data_buf)
662 sendQuery(kwargs['tid'], kwargs['fid'], data_buf)
663 elif query_message.status == 0xC000000FL: # [MS-ERREF]: STATUS_NO_SUCH_FILE
664 # If there are no matching files, we just treat as success instead of failing
665 closeFid(kwargs['tid'], kwargs['fid'], results = results)
599666 elif query_message.status == 0x80000006L: # STATUS_NO_MORE_FILES
600 closeFid(query_message.tid, kwargs['fid'], results = results)
601 else:
602 closeFid(query_message.tid, kwargs['fid'], error = query_message.status)
667 closeFid(kwargs['tid'], kwargs['fid'], results = results)
668 else:
669 closeFid(kwargs['tid'], kwargs['fid'], error = query_message.status)
603670
604671 def decodeQueryStruct(data_bytes):
605 # SMB_FIND_FILE_BOTH_DIRECTORY_INFO structure. See [MS-CIFS]: 2.2.8.1.7 and [MS-SMB]: 2.2.8.1.1
606 info_format = '<IIQQQQQQIIIBB24s'
672 # FileIdBothDirectoryInformation structure. See [MS-SMB]: 2.2.8.1.3 and [MS-FSCC]: 2.4.17
673 info_format = '<IIQQQQQQIIIBB24sHQ'
607674 info_size = struct.calcsize(info_format)
608675
609676 data_length = len(data_bytes)
615682 next_offset, _, \
616683 create_time, last_access_time, last_write_time, last_attr_change_time, \
617684 file_size, alloc_size, file_attributes, filename_length, ea_size, \
618 short_name_length, _, short_name = struct.unpack(info_format, data_bytes[offset:offset+info_size])
685 short_name_length, _, short_name, _, file_id = struct.unpack(info_format, data_bytes[offset:offset+info_size])
619686
620687 offset2 = offset + info_size
621688 if offset2 + filename_length > data_length:
622689 return data_bytes[offset:]
623690
624691 filename = data_bytes[offset2:offset2+filename_length].decode('UTF-16LE')
625 short_name = short_name.decode('UTF-16LE')
626 results.append(SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time),
627 convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
628 file_size, alloc_size, file_attributes, short_name, filename))
692 short_name = short_name[:short_name_length].decode('UTF-16LE')
693
694 accept_result = False
695 if (file_attributes & 0xff) in ( 0x00, ATTR_NORMAL ): # Only the first 8-bits are compared. We ignore other bits like temp, compressed, encryption, sparse, indexed, etc
696 accept_result = (search == SMB_FILE_ATTRIBUTE_NORMAL) or (search & SMB_FILE_ATTRIBUTE_INCL_NORMAL)
697 else:
698 accept_result = (file_attributes & search) > 0
699 if accept_result:
700 results.append(SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time),
701 convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
702 file_size, alloc_size, file_attributes, short_name, filename, file_id))
629703
630704 if next_offset:
631705 offset += next_offset
644718 if kwargs['results'] is not None:
645719 callback(kwargs['results'])
646720 elif kwargs['error'] is not None:
647 errback(OperationFailure('Failed to list %s on %s: Query failed with errorcode 0x%08x' % ( path, service_name, kwargs['error'] ), messages_history))
721 if kwargs['error'] == 0xC000000F: # [MS-ERREF]: STATUS_NO_SUCH_FILE
722 # Remote server returns STATUS_NO_SUCH_FILE error so we assume that the search returns no matching files
723 callback([ ])
724 else:
725 errback(OperationFailure('Failed to list %s on %s: Query failed with errorcode 0x%08x' % ( path, service_name, kwargs['error'] ), messages_history))
648726
649727 if not self.connected_trees.has_key(service_name):
650728 def connectCB(connect_message, **kwargs):
694772 create_context_data = create_context_data))
695773 m.tid = tid
696774 self._sendSMBMessage(m)
697 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback)
775 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback, tid = tid)
698776 messages_history.append(m)
699777
700778 def createCB(create_message, **kwargs):
701779 messages_history.append(create_message)
702780 if create_message.status == 0:
703781 p = create_message.payload
782 filename = self._extractLastPathComponent(unicode(path))
704783 info = SharedFile(p.create_time, p.lastaccess_time, p.lastwrite_time, p.change_time,
705784 p.file_size, p.allocation_size, p.file_attributes,
706 unicode(path), unicode(path))
707 closeFid(create_message.tid, p.fid, info = info)
785 filename, filename)
786 closeFid(kwargs['tid'], p.fid, info = info)
708787 else:
709788 errback(OperationFailure('Failed to get attributes for %s on %s: Unable to open remote file object' % ( path, service_name ), messages_history))
710789
729808 sendCreate(connect_message.tid)
730809 else:
731810 errback(OperationFailure('Failed to get attributes for %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
811
812 m = SMB2Message(SMB2TreeConnectRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name )))
813 self._sendSMBMessage(m)
814 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = service_name)
815 messages_history.append(m)
816 else:
817 sendCreate(self.connected_trees[service_name])
818
819 def _getSecurity_SMB2(self, service_name, path, callback, errback, timeout = 30):
820 if not self.has_authenticated:
821 raise NotReadyError('SMB connection not authenticated')
822
823 expiry_time = time.time() + timeout
824 path = path.replace('/', '\\')
825 if path.startswith('\\'):
826 path = path[1:]
827 if path.endswith('\\'):
828 path = path[:-1]
829 messages_history = [ ]
830 results = [ ]
831
832 def sendCreate(tid):
833 m = SMB2Message(SMB2CreateRequest(path,
834 file_attributes = 0,
835 access_mask = FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | READ_CONTROL | SYNCHRONIZE,
836 share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
837 oplock = SMB2_OPLOCK_LEVEL_NONE,
838 impersonation = SEC_IMPERSONATE,
839 create_options = 0,
840 create_disp = FILE_OPEN))
841 m.tid = tid
842 self._sendSMBMessage(m)
843 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback, tid = tid)
844 messages_history.append(m)
845
846 def createCB(create_message, **kwargs):
847 messages_history.append(create_message)
848 if create_message.status == 0:
849 m = SMB2Message(SMB2QueryInfoRequest(create_message.payload.fid,
850 flags = 0,
851 additional_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
852 info_type = SMB2_INFO_SECURITY,
853 file_info_class = 0, # [MS-SMB2] 2.2.37, 3.2.4.12
854 input_buf = '',
855 output_buf_len = self.max_transact_size))
856 m.tid = kwargs['tid']
857 self._sendSMBMessage(m)
858 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, queryCB, errback, tid = kwargs['tid'], fid = create_message.payload.fid)
859 messages_history.append(m)
860 else:
861 errback(OperationFailure('Failed to get the security descriptor of %s on %s: Unable to open file or directory' % ( path, service_name ), messages_history))
862
863 def queryCB(query_message, **kwargs):
864 messages_history.append(query_message)
865 if query_message.status == 0:
866 security = SecurityDescriptor.from_bytes(query_message.payload.data)
867 closeFid(kwargs['tid'], kwargs['fid'], result = security)
868 else:
869 closeFid(kwargs['tid'], kwargs['fid'], error = query_message.status)
870
871 def closeFid(tid, fid, result = None, error = None):
872 m = SMB2Message(SMB2CloseRequest(fid))
873 m.tid = tid
874 self._sendSMBMessage(m)
875 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, closeCB, errback, result = result, error = error)
876 messages_history.append(m)
877
878 def closeCB(close_message, **kwargs):
879 if kwargs['result'] is not None:
880 callback(kwargs['result'])
881 elif kwargs['error'] is not None:
882 errback(OperationFailure('Failed to get the security descriptor of %s on %s: Query failed with errorcode 0x%08x' % ( path, service_name, kwargs['error'] ), messages_history))
883
884 if not self.connected_trees.has_key(service_name):
885 def connectCB(connect_message, **kwargs):
886 messages_history.append(connect_message)
887 if connect_message.status == 0:
888 self.connected_trees[service_name] = connect_message.tid
889 sendCreate(connect_message.tid)
890 else:
891 errback(OperationFailure('Failed to get the security descriptor of %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
732892
733893 m = SMB2Message(SMB2TreeConnectRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name )))
734894 self._sendSMBMessage(m)
765925 m = SMB2Message(SMB2CreateRequest(path,
766926 file_attributes = 0,
767927 access_mask = FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | READ_CONTROL | SYNCHRONIZE,
768 share_access = FILE_SHARE_READ,
928 share_access = FILE_SHARE_READ | FILE_SHARE_WRITE,
769929 oplock = SMB2_OPLOCK_LEVEL_NONE,
770930 impersonation = SEC_IMPERSONATE,
771931 create_options = FILE_SEQUENTIAL_ONLY | FILE_NON_DIRECTORY_FILE,
783943 flags = 0,
784944 additional_info = 0,
785945 info_type = SMB2_INFO_FILE,
786 file_info_class = 0x16, # FileStreamInformation [MS-FSCC] 2.4
946 file_info_class = 0x05, # FileStandardInformation [MS-FSCC] 2.4
787947 input_buf = '',
788948 output_buf_len = 4096))
789 m.tid = create_message.tid
949 m.tid = kwargs['tid']
790950 self._sendSMBMessage(m)
791951 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, infoCB, errback,
792 fid = create_message.payload.fid, file_attributes = create_message.payload.file_attributes)
952 tid = kwargs['tid'],
953 fid = create_message.payload.fid,
954 file_attributes = create_message.payload.file_attributes)
793955 messages_history.append(m)
794956 else:
795 errback(OperationFailure('Failed to list %s on %s: Unable to open file' % ( path, service_name ), messages_history))
957 errback(OperationFailure('Failed to retrieve %s on %s: Unable to open file' % ( path, service_name ), messages_history))
796958
797959 def infoCB(info_message, **kwargs):
798960 messages_history.append(info_message)
807969 remaining_len = file_len
808970 if starting_offset + remaining_len > file_len:
809971 remaining_len = file_len - starting_offset
810 sendRead(info_message.tid, kwargs['fid'], starting_offset, remaining_len, 0, kwargs['file_attributes'])
811 else:
812 errback(OperationFailure('Failed to list %s on %s: Unable to retrieve information on file' % ( path, service_name ), messages_history))
972 sendRead(kwargs['tid'], kwargs['fid'], starting_offset, remaining_len, 0, kwargs['file_attributes'])
973 else:
974 errback(OperationFailure('Failed to retrieve %s on %s: Unable to retrieve information on file' % ( path, service_name ), messages_history))
813975
814976 def sendRead(tid, fid, offset, remaining_len, read_len, file_attributes):
815977 read_count = min(self.max_read_size, remaining_len)
817979 m.tid = tid
818980 self._sendSMBMessage(m)
819981 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, readCB, errback,
820 fid = fid, offset = offset,
982 tid = tid, fid = fid, offset = offset,
821983 remaining_len = remaining_len,
822984 read_len = read_len,
823985 file_attributes = file_attributes)
831993 remaining_len = kwargs['remaining_len'] - data_len
832994
833995 if remaining_len > 0:
834 sendRead(read_message.tid, kwargs['fid'], kwargs['offset'] + data_len, remaining_len, kwargs['read_len'] + data_len, kwargs['file_attributes'])
835 else:
836 closeFid(read_message.tid, kwargs['fid'], ret = ( file_obj, kwargs['file_attributes'], kwargs['read_len'] + data_len ))
996 sendRead(kwargs['tid'], kwargs['fid'], kwargs['offset'] + data_len, remaining_len, kwargs['read_len'] + data_len, kwargs['file_attributes'])
997 else:
998 closeFid(kwargs['tid'], kwargs['fid'], ret = ( file_obj, kwargs['file_attributes'], kwargs['read_len'] + data_len ))
837999 else:
8381000 messages_history.append(read_message)
839 closeFid(read_message.tid, kwargs['fid'], error = read_message.status)
1001 closeFid(kwargs['tid'], kwargs['fid'], error = read_message.status)
8401002
8411003 def closeFid(tid, fid, ret = None, error = None):
8421004 m = SMB2Message(SMB2CloseRequest(fid))
9121074 messages_history.append(create_message)
9131075 if create_message.status == 0:
9141076 sendWrite(create_message.tid, create_message.payload.fid, starting_offset)
915 elif create_message.status == 0x0103: # STATUS_PENDING
916 self.pending_requests[create_message.mid] = _PendingRequest(create_message.mid, expiry_time,
917 createCB, errback,
918 tid=kwargs['tid'])
9191077 else:
9201078 errback(OperationFailure('Failed to store %s on %s: Unable to open file' % ( path, service_name ), messages_history))
9211079
9271085 m = SMB2Message(SMB2WriteRequest(fid, data, offset))
9281086 m.tid = tid
9291087 self._sendSMBMessage(m)
930 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, writeCB, errback, fid = fid, offset = offset+data_len)
1088 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, writeCB, errback, tid = tid, fid = fid, offset = offset+data_len)
9311089 else:
9321090 closeFid(tid, fid, offset = offset)
9331091
9341092 def writeCB(write_message, **kwargs):
9351093 # To avoid crazy memory usage when saving large files, we do not save every write_message in messages_history.
9361094 if write_message.status == 0:
937 sendWrite(write_message.tid, kwargs['fid'], kwargs['offset'])
1095 sendWrite(kwargs['tid'], kwargs['fid'], kwargs['offset'])
9381096 else:
9391097 messages_history.append(write_message)
940 closeFid(write_message.tid, kwargs['fid'])
1098 closeFid(kwargs['tid'], kwargs['fid'])
9411099 errback(OperationFailure('Failed to store %s on %s: Write failed' % ( path, service_name ), messages_history))
9421100
9431101 def closeFid(tid, fid, error = None, offset = None):
9701128 sendCreate(self.connected_trees[service_name])
9711129
9721130
973 def _deleteFiles_SMB2(self, service_name, path_file_pattern, callback, errback, timeout = 30):
1131 def _deleteFiles_SMB2(self, service_name, path_file_pattern, delete_matching_folders, callback, errback, timeout = 30):
9741132 if not self.has_authenticated:
9751133 raise NotReadyError('SMB connection not authenticated')
9761134
9771135 expiry_time = time.time() + timeout
1136 pattern = None
9781137 path = path_file_pattern.replace('/', '\\')
9791138 if path.startswith('\\'):
9801139 path = path[1:]
9811140 if path.endswith('\\'):
9821141 path = path[:-1]
1142 else:
1143 path_components = path.split('\\')
1144 if path_components[-1].find('*') > -1 or path_components[-1].find('?') > -1:
1145 path = '\\'.join(path_components[:-1])
1146 pattern = path_components[-1]
1147 messages_history, files_queue = [ ], [ ]
1148
1149 if pattern is None:
1150 path_components = path.split('\\')
1151 if len(path_components) > 1:
1152 files_queue.append(( '\\'.join(path_components[:-1]), path_components[-1] ))
1153 else:
1154 files_queue.append(( '', path ))
1155
1156 def deleteCB(path):
1157 if files_queue:
1158 p, filename = files_queue.pop(0)
1159 if filename:
1160 if p:
1161 filename = p + '\\' + filename
1162 self._deleteFiles_SMB2__del(service_name, self.connected_trees[service_name], filename, deleteCB, errback, timeout)
1163 else:
1164 self._deleteDirectory_SMB2(service_name, p, deleteCB, errback, timeout)
1165 else:
1166 callback(path_file_pattern)
1167
1168 def listCB(files_list):
1169 files_queue.extend(files_list)
1170 deleteCB(None)
1171
1172 if not self.connected_trees.has_key(service_name):
1173 def connectCB(connect_message, **kwargs):
1174 messages_history.append(connect_message)
1175 if connect_message.status == 0:
1176 self.connected_trees[service_name] = connect_message.tid
1177 if files_queue:
1178 deleteCB(None)
1179 else:
1180 self._deleteFiles_SMB2__list(service_name, path, pattern, delete_matching_folders, listCB, errback, timeout)
1181 else:
1182 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
1183
1184 m = SMB2Message(SMB2TreeConnectRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name )))
1185 self._sendSMBMessage(m)
1186 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = service_name)
1187 messages_history.append(m)
1188 else:
1189 if files_queue:
1190 deleteCB(None)
1191 else:
1192 self._deleteFiles_SMB2__list(service_name, path, pattern, delete_matching_folders, listCB, errback, timeout)
1193
1194 def _deleteFiles_SMB2__list(self, service_name, path, pattern, delete_matching_folders, callback, errback, timeout = 30):
1195 folder_queue = [ ]
1196 files_list = [ ]
1197 current_path = [ path ]
1198 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL
1199
1200 def listCB(results):
1201 files = [ ]
1202 for f in filter(lambda x: x.filename not in [ '.', '..' ], results):
1203 if f.isDirectory:
1204 if delete_matching_folders:
1205 folder_queue.append(current_path[0]+'\\'+f.filename)
1206 else:
1207 files.append(( current_path[0], f.filename ))
1208 if current_path[0]!=path and delete_matching_folders:
1209 files.append(( current_path[0], None ))
1210
1211 if files:
1212 files_list[0:0] = files
1213
1214 if folder_queue:
1215 p = folder_queue.pop()
1216 current_path[0] = p
1217 self._listPath_SMB2(service_name, current_path[0], listCB, errback, search = search, pattern = '*', timeout = 30)
1218 else:
1219 callback(files_list)
1220
1221 self._listPath_SMB2(service_name, path, listCB, errback, search = search, pattern = pattern, timeout = timeout)
1222
1223 def _deleteFiles_SMB2__del(self, service_name, tid, path, callback, errback, timeout = 30):
9831224 messages_history = [ ]
9841225
9851226 def sendCreate(tid):
10101251 messages_history.append(open_message)
10111252 if open_message.status == 0:
10121253 sendDelete(open_message.tid, open_message.payload.fid)
1013 elif open_message.status == 0x0103: # STATUS_PENDING
1014 self.pending_requests[open_message.mid] = _PendingRequest(open_message.mid, expiry_time,
1015 createCB, errback,
1016 tid=kwargs['tid'])
1254 elif open_message.status == 0xC0000034L: # [MS-ERREF]: STATUS_OBJECT_NAME_NOT_FOUND
1255 callback(path)
1256 elif open_message.status == 0xC00000BAL: # [MS-ERREF]: STATUS_FILE_IS_A_DIRECTORY
1257 errback(OperationFailure('Failed to delete %s on %s: Cannot delete a folder. Please use deleteDirectory() method or append "/*" to your path if you wish to delete all files in the folder.' % ( path, service_name ), messages_history))
10171258 else:
10181259 errback(OperationFailure('Failed to delete %s on %s: Unable to open file' % ( path, service_name ), messages_history))
10191260
10231264 info_type = SMB2_INFO_FILE,
10241265 file_info_class = 0x0d, # SMB2_FILE_DISPOSITION_INFO
10251266 data = '\x01'))
1026 '''
1027 Resources:
1028 https://msdn.microsoft.com/en-us/library/cc246560.aspx
1029 https://msdn.microsoft.com/en-us/library/cc232098.aspx
1030 '''
1031 m.tid = tid
1032 self._sendSMBMessage(m)
1033 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback, fid = fid)
1267 # [MS-SMB2]: 2.2.39, [MS-FSCC]: 2.4.11
1268 m.tid = tid
1269 self._sendSMBMessage(m)
1270 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback, tid = tid, fid = fid)
10341271 messages_history.append(m)
10351272
10361273 def deleteCB(delete_message, **kwargs):
10371274 messages_history.append(delete_message)
10381275 if delete_message.status == 0:
1039 closeFid(delete_message.tid, kwargs['fid'], status = 0)
1040 else:
1041 closeFid(delete_message.tid, kwargs['fid'], status = delete_message.status)
1276 closeFid(kwargs['tid'], kwargs['fid'], status = 0)
1277 else:
1278 closeFid(kwargs['tid'], kwargs['fid'], status = delete_message.status)
10421279
10431280 def closeFid(tid, fid, status = None):
10441281 m = SMB2Message(SMB2CloseRequest(fid))
10491286
10501287 def closeCB(close_message, **kwargs):
10511288 if kwargs['status'] == 0:
1052 callback(path_file_pattern)
1289 callback(path)
10531290 else:
10541291 errback(OperationFailure('Failed to delete %s on %s: Delete failed' % ( path, service_name ), messages_history))
10551292
1056 if not self.connected_trees.has_key(service_name):
1057 def connectCB(connect_message, **kwargs):
1058 messages_history.append(connect_message)
1059 if connect_message.status == 0:
1060 self.connected_trees[service_name] = connect_message.tid
1061 sendCreate(connect_message.tid)
1062 else:
1063 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
1064
1065 m = SMB2Message(SMB2TreeConnectRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name )))
1066 self._sendSMBMessage(m)
1067 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = service_name)
1068 messages_history.append(m)
1069 else:
1070 sendCreate(self.connected_trees[service_name])
1071
1072 def _resetFileAttributes_SMB2(self, service_name, path_file_pattern, callback, errback, timeout = 30):
1293 sendCreate(tid)
1294
1295 def _resetFileAttributes_SMB2(self, service_name, path_file_pattern, callback, errback, file_attributes = ATTR_NORMAL, timeout = 30):
10731296 if not self.has_authenticated:
10741297 raise NotReadyError('SMB connection not authenticated')
10751298
11081331 def createCB(open_message, **kwargs):
11091332 messages_history.append(open_message)
11101333 if open_message.status == 0:
1111 sendReset(open_message.tid, open_message.payload.fid)
1334 sendReset(kwargs['tid'], open_message.payload.fid)
11121335 else:
11131336 errback(OperationFailure('Failed to reset attributes of %s on %s: Unable to open file' % ( path, service_name ), messages_history))
11141337
11171340 additional_info = 0,
11181341 info_type = SMB2_INFO_FILE,
11191342 file_info_class = 4, # FileBasicInformation
1120 data = struct.pack('qqqqii',0,0,0,0,0x80,0))) # FILE_ATTRIBUTE_NORMAL
1121 '''
1122 Resources:
1123 https://msdn.microsoft.com/en-us/library/cc246560.aspx
1124 https://msdn.microsoft.com/en-us/library/cc232064.aspx
1125 https://msdn.microsoft.com/en-us/library/cc232094.aspx
1126 https://msdn.microsoft.com/en-us/library/cc232110.aspx
1127 '''
1128 m.tid = tid
1129 self._sendSMBMessage(m)
1130 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, resetCB, errback, fid = fid)
1343 data = struct.pack('qqqqii',0,0,0,0,file_attributes,0)))
1344 # [MS-SMB2]: 2.2.39, [MS-FSCC]: 2.4, [MS-FSCC]: 2.4.7, [MS-FSCC]: 2.6
1345 m.tid = tid
1346 self._sendSMBMessage(m)
1347 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, resetCB, errback, tid = tid, fid = fid)
11311348 messages_history.append(m)
11321349
11331350 def resetCB(reset_message, **kwargs):
11341351 messages_history.append(reset_message)
11351352 if reset_message.status == 0:
1136 closeFid(reset_message.tid, kwargs['fid'], status = 0)
1137 else:
1138 closeFid(reset_message.tid, kwargs['fid'], status = reset_message.status)
1353 closeFid(kwargs['tid'], kwargs['fid'], status = 0)
1354 else:
1355 closeFid(kwargs['tid'], kwargs['fid'], status = reset_message.status)
11391356
11401357 def closeFid(tid, fid, status = None):
11411358 m = SMB2Message(SMB2CloseRequest(fid))
11981415 create_context_data = create_context_data))
11991416 m.tid = tid
12001417 self._sendSMBMessage(m)
1201 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback)
1418 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback, tid = tid)
12021419 messages_history.append(m)
12031420
12041421 def createCB(create_message, **kwargs):
12051422 messages_history.append(create_message)
12061423 if create_message.status == 0:
1207 closeFid(create_message.tid, create_message.payload.fid)
1424 closeFid(kwargs['tid'], create_message.payload.fid)
12081425 else:
12091426 errback(OperationFailure('Failed to create directory %s on %s: Create failed' % ( path, service_name ), messages_history))
12101427
12721489 def createCB(open_message, **kwargs):
12731490 messages_history.append(open_message)
12741491 if open_message.status == 0:
1275 sendDelete(open_message.tid, open_message.payload.fid)
1492 sendDelete(kwargs['tid'], open_message.payload.fid)
12761493 else:
12771494 errback(OperationFailure('Failed to delete %s on %s: Unable to open directory' % ( path, service_name ), messages_history))
12781495
12841501 data = '\x01'))
12851502 m.tid = tid
12861503 self._sendSMBMessage(m)
1287 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback, fid = fid)
1504 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback, tid = tid, fid = fid)
12881505 messages_history.append(m)
12891506
12901507 def deleteCB(delete_message, **kwargs):
12911508 messages_history.append(delete_message)
12921509 if delete_message.status == 0:
1293 closeFid(delete_message.tid, kwargs['fid'], status = 0)
1294 else:
1295 closeFid(delete_message.tid, kwargs['fid'], status = delete_message.status)
1510 closeFid(kwargs['tid'], kwargs['fid'], status = 0)
1511 else:
1512 closeFid(kwargs['tid'], kwargs['fid'], status = delete_message.status)
12961513
12971514 def closeFid(tid, fid, status = None):
12981515 m = SMB2Message(SMB2CloseRequest(fid))
13681585 def createCB(create_message, **kwargs):
13691586 messages_history.append(create_message)
13701587 if create_message.status == 0:
1371 sendRename(create_message.tid, create_message.payload.fid)
1588 sendRename(kwargs['tid'], create_message.payload.fid)
13721589 else:
13731590 errback(OperationFailure('Failed to rename %s on %s: Unable to open file/directory' % ( old_path, service_name ), messages_history))
13741591
13811598 data = data))
13821599 m.tid = tid
13831600 self._sendSMBMessage(m)
1384 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, renameCB, errback, fid = fid)
1601 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, renameCB, errback, tid = tid, fid = fid)
13851602 messages_history.append(m)
13861603
13871604 def renameCB(rename_message, **kwargs):
13881605 messages_history.append(rename_message)
13891606 if rename_message.status == 0:
1390 closeFid(rename_message.tid, kwargs['fid'], status = 0)
1391 else:
1392 closeFid(rename_message.tid, kwargs['fid'], status = rename_message.status)
1607 closeFid(kwargs['tid'], kwargs['fid'], status = 0)
1608 else:
1609 closeFid(kwargs['tid'], kwargs['fid'], status = rename_message.status)
13931610
13941611 def closeFid(tid, fid, status = None):
13951612 m = SMB2Message(SMB2CloseRequest(fid))
14561673 def createCB(create_message, **kwargs):
14571674 messages_history.append(create_message)
14581675 if create_message.status == 0:
1459 sendEnumSnapshots(create_message.tid, create_message.payload.fid)
1676 sendEnumSnapshots(kwargs['tid'], create_message.payload.fid)
14601677 else:
14611678 errback(OperationFailure('Failed to list snapshots %s on %s: Unable to open file/directory' % ( old_path, service_name ), messages_history))
14621679
15971814 self._handleSessionChallenge(message, ntlm_token)
15981815 except ( securityblob.BadSecurityBlobError, securityblob.UnsupportedSecurityProvider ), ex:
15991816 raise ProtocolError(str(ex), message.raw_data, message)
1600 elif message.status.internal_value == 0xc000006d: # STATUS_LOGON_FAILURE
1817 elif (message.status.internal_value == 0xc000006d # STATUS_LOGON_FAILURE
1818 or message.status.internal_value == 0xc0000064 # STATUS_NO_SUCH_USER
1819 or message.status.internal_value == 0xc000006a): # STATUS_WRONG_PASSWORD
16011820 self.has_authenticated = False
1602 self.log.info('Authentication (with extended security) failed. Please check username and password. You may need to enable/disable NTLMv2 authentication.')
1821 self.log.info('Authentication (with extended security) failed. Please check username and password.')
1822 self.onAuthFailed()
1823 elif (message.status.internal_value == 0xc0000193 # STATUS_ACCOUNT_EXPIRED
1824 or message.status.internal_value == 0xC0000071): # STATUS_PASSWORD_EXPIRED
1825 self.has_authenticated = False
1826 self.log.info('Authentication (with extended security) failed. Account or password has expired.')
1827 self.onAuthFailed()
1828 elif message.status.internal_value == 0xc0000234: # STATUS_ACCOUNT_LOCKED_OUT
1829 self.has_authenticated = False
1830 self.log.info('Authentication (with extended security) failed. Account has been locked due to too many invalid logon attempts.')
1831 self.onAuthFailed()
1832 elif message.status.internal_value == 0xc0000072: # STATUS_ACCOUNT_DISABLED
1833 self.has_authenticated = False
1834 self.log.info('Authentication (with extended security) failed. Account has been disabled.')
1835 self.onAuthFailed()
1836 elif (message.status.internal_value == 0xc000006f # STATUS_INVALID_LOGON_HOURS
1837 or message.status.internal_value == 0xc000015b # STATUS_LOGON_TYPE_NOT_GRANTED
1838 or message.status.internal_value == 0xc0000070): # STATUS_INVALID_WORKSTATION
1839 self.has_authenticated = False
1840 self.log.info('Authentication (with extended security) failed. Not allowed.')
1841 self.onAuthFailed()
1842 elif message.status.internal_value == 0xc000018c: # STATUS_TRUSTED_DOMAIN_FAILURE
1843 self.has_authenticated = False
1844 self.log.info('Authentication (with extended security) failed. Domain not trusted.')
1845 self.onAuthFailed()
1846 elif message.status.internal_value == 0xc000018d: # STATUS_TRUSTED_RELATIONSHIP_FAILURE
1847 self.has_authenticated = False
1848 self.log.info('Authentication (with extended security) failed. Workstation not trusted.')
16031849 self.onAuthFailed()
16041850 else:
16051851 raise ProtocolError('Unknown status value (0x%08X) in SMB_COM_SESSION_SETUP_ANDX (with extended security)' % message.status.internal_value,
16611907 self.log.info('Performing NTLMv1 authentication (with extended security) with server challenge "%s"', binascii.hexlify(server_challenge))
16621908 nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(self.password, server_challenge, True)
16631909
1664 ntlm_data = ntlm.generateAuthenticateMessage(server_flags,
1665 nt_challenge_response,
1666 lm_challenge_response,
1667 session_key,
1668 self.username,
1669 self.domain)
1910 ntlm_data, session_signing_key = ntlm.generateAuthenticateMessage(server_flags,
1911 nt_challenge_response,
1912 lm_challenge_response,
1913 session_key,
1914 self.username,
1915 self.domain,
1916 self.my_name)
16701917
16711918 if self.log.isEnabledFor(logging.DEBUG):
16721919 self.log.debug('NT challenge response is "%s" (%d bytes)', binascii.hexlify(nt_challenge_response), len(nt_challenge_response))
16861933
16871934 if self.is_signing_active:
16881935 self.log.info("SMB signing activated. All SMB messages will be signed.")
1689 self.signing_session_key = session_key
1936 self.signing_session_key = session_signing_key
16901937 if self.capabilities & CAP_EXTENDED_SECURITY:
16911938 self.signing_challenge_response = None
16921939 else:
18602107 def readCB(read_message, **kwargs):
18612108 messages_history.append(read_message)
18622109 if not read_message.status.hasError:
1863 data_len = read_message.payload.data_length
18642110 data_bytes = read_message.payload.data
18652111
18662112 if ord(data_bytes[3]) & 0x02 == 0:
1867 sendReadRequest(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:data_len-24])
1868 else:
1869 decodeResults(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:data_len-24])
2113 sendReadRequest(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:])
2114 else:
2115 decodeResults(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:])
18702116 else:
18712117 closeFid(read_message.tid, kwargs['fid'])
18722118 errback(OperationFailure('Failed to list shares: Unable to retrieve shared device list', messages_history))
19052151 setup_bytes = struct.pack('<H', 0x0001) # TRANS2_FIND_FIRST2 sub-command. See [MS-CIFS]: 2.2.6.2.1
19062152 params_bytes = \
19072153 struct.pack('<HHHHI',
1908 search, # SearchAttributes
2154 search & 0xFFFF, # SearchAttributes (need to restrict the values due to introduction of SMB_FILE_ATTRIBUTE_INCL_NORMAL)
19092155 100, # SearchCount
19102156 0x0006, # Flags: SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS
19112157 0x0104, # InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO
1912 0x0000) # SearchStorageType
2158 0x0000) # SearchStorageType (seems to be ignored by Windows)
19132159 if support_dfs:
19142160 params_bytes += ("\\" + self.remote_name + "\\" + service_name + path + pattern + '\0').encode('UTF-16LE')
19152161 else:
1916 params_bytes += (path + pattern).encode('UTF-16LE')
2162 params_bytes += (path + pattern + '\0').encode('UTF-16LE')
19172163
19182164 m = SMBMessage(ComTransaction2Request(max_params_count = 10,
19192165 max_data_count = 16644,
19492195
19502196 filename = data_bytes[offset2:offset2+filename_length].decode('UTF-16LE')
19512197 short_name = short_name.decode('UTF-16LE')
1952 results.append(SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time),
1953 convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
1954 file_size, alloc_size, file_attributes, short_name, filename))
2198
2199 accept_result = False
2200 if (file_attributes & 0xff) in ( 0x00, ATTR_NORMAL ): # Only the first 8-bits are compared. We ignore other bits like temp, compressed, encryption, sparse, indexed, etc
2201 accept_result = (search == SMB_FILE_ATTRIBUTE_NORMAL) or (search & SMB_FILE_ATTRIBUTE_INCL_NORMAL)
2202 else:
2203 accept_result = (file_attributes & search) > 0
2204 if accept_result:
2205 results.append(SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time),
2206 convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
2207 file_size, alloc_size, file_attributes, short_name, filename))
19552208
19562209 if next_offset:
19572210 offset += next_offset
19912244 elif end_of_search:
19922245 callback(results)
19932246 else:
1994 sendFindNext(find_message.tid, sid, last_name_offset, kwargs.get('support_dfs', False))
1995 else:
1996 errback(OperationFailure('Failed to list %s on %s: Unable to retrieve file list' % ( path, service_name ), messages_history))
1997
1998 def sendFindNext(tid, sid, resume_key, support_dfs=False):
2247 sendFindNext(find_message.tid, sid, 0, results[-1].filename, kwargs.get('support_dfs', False))
2248 else:
2249 if find_message.status.internal_value == 0xC000000F: # [MS-ERREF]: STATUS_NO_SUCH_FILE
2250 # Remote server returns STATUS_NO_SUCH_FILE error so we assume that the search returns no matching files
2251 callback([ ])
2252 else:
2253 errback(OperationFailure('Failed to list %s on %s: Unable to retrieve file list' % ( path, service_name ), messages_history))
2254
2255 def sendFindNext(tid, sid, resume_key, resume_file, support_dfs=False):
19992256 setup_bytes = struct.pack('<H', 0x0002) # TRANS2_FIND_NEXT2 sub-command. See [MS-CIFS]: 2.2.6.3.1
20002257 params_bytes = \
20012258 struct.pack('<HHHIH',
20032260 100, # SearchCount
20042261 0x0104, # InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO
20052262 resume_key, # ResumeKey
2006 0x000a) # Flags: SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS
2007 if support_dfs:
2008 params_bytes += ("\\" + self.remote_name + "\\" + service_name + path + pattern + '\0').encode('UTF-16LE')
2009 else:
2010 params_bytes += (path + pattern).encode('UTF-16LE')
2263 0x0006) # Flags: SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS
2264 params_bytes += (resume_file+'\0').encode('UTF-16LE')
20112265
20122266 m = SMBMessage(ComTransaction2Request(max_params_count = 10,
20132267 max_data_count = 16644,
20532307 elif end_of_search:
20542308 callback(results)
20552309 else:
2056 sendFindNext(find_message.tid, kwargs['sid'], last_name_offset, kwargs.get('support_dfs', False))
2310 sendFindNext(find_message.tid, kwargs['sid'], 0, results[-1].filename, kwargs.get('support_dfs', False))
20572311 else:
20582312 errback(OperationFailure('Failed to list %s on %s: Unable to retrieve file list' % ( path, service_name ), messages_history))
20592313
21312385 info_size = struct.calcsize(info_format)
21322386 create_time, last_access_time, last_write_time, last_attr_change_time, \
21332387 file_attributes, _, alloc_size, file_size = struct.unpack(info_format, query_message.payload.data_bytes[:info_size])
2134
2135 info = SharedFile(create_time, last_access_time, last_write_time, last_attr_change_time,
2136 file_size, alloc_size, file_attributes, unicode(path), unicode(path))
2388 filename = self._extractLastPathComponent(unicode(path))
2389
2390 info = SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time), convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
2391 file_size, alloc_size, file_attributes, filename, filename)
21372392 callback(info)
21382393 else:
21392394 errback(OperationFailure('Failed to get attributes for %s on %s: Read failed' % ( path, service_name ), messages_history))
21532408 messages_history.append(m)
21542409 else:
21552410 sendQuery(self.connected_trees[service_name])
2411
2412 def _getSecurity_SMB1(self, service_name, path_file_pattern, callback, errback, timeout = 30):
2413 raise NotReadyError('getSecurity is not yet implemented for SMB1')
21562414
21572415 def _retrieveFile_SMB1(self, service_name, path, file_obj, callback, errback, timeout = 30):
21582416 return self._retrieveFileFromOffset(service_name, path, file_obj, callback, errback, 0L, -1L, timeout)
22772535 errback(OperationFailure('Failed to store %s on %s: Unable to open file' % ( path, service_name ), messages_history))
22782536
22792537 def sendWrite(tid, fid, offset):
2280 # For message signing, the total SMB message size must be not exceed the max_buffer_size. Non-message signing does not have this limitation
2281 write_count = min((self.is_signing_active and (self.max_buffer_size-64)) or self.max_raw_size, 0xFFFF-1) # Need to minus 1 byte from 0xFFFF because of the first NULL byte in the ComWriteAndxRequest message data
2538 # [MS-SMB] 2.2.4.5.2.2: The total SMB message size (inclusive of SMB header) must be not exceed the max_buffer_size.
2539 write_count = min(self.max_buffer_size-64, 0xFFFF-64) # SMB header is 32-bytes. We factor in another 32-bytes for the message parameter block
22822540 data_bytes = file_obj.read(write_count)
22832541 data_len = len(data_bytes)
22842542 if data_len > 0:
23212579 else:
23222580 sendOpen(self.connected_trees[service_name])
23232581
2324 def _deleteFiles_SMB1(self, service_name, path_file_pattern, callback, errback, timeout = 30):
2582 def _deleteFiles_SMB1(self, service_name, path_file_pattern, delete_matching_folders, callback, errback, timeout = 30):
23252583 if not self.has_authenticated:
23262584 raise NotReadyError('SMB connection not authenticated')
23272585
2586 expiry_time = time.time() + timeout
2587 pattern = None
23282588 path = path_file_pattern.replace('/', '\\')
2589 if path.startswith('\\'):
2590 path = path[1:]
2591 if path.endswith('\\'):
2592 path = path[:-1]
2593 else:
2594 path_components = path.split('\\')
2595 if path_components[-1].find('*') > -1 or path_components[-1].find('?') > -1:
2596 path = '\\'.join(path_components[:-1])
2597 pattern = path_components[-1]
2598 messages_history, files_queue = [ ], [ ]
2599
2600 if pattern is None:
2601 path_components = path.split('\\')
2602 if len(path_components) > 1:
2603 files_queue.append(( '\\'.join(path_components[:-1]), path_components[-1] ))
2604 else:
2605 files_queue.append(( '', path ))
2606
2607 def deleteCB(path):
2608 if files_queue:
2609 p, filename = files_queue.pop(0)
2610 if filename:
2611 if p:
2612 filename = p + '\\' + filename
2613 self._deleteFiles_SMB1__del(service_name, self.connected_trees[service_name], filename, deleteCB, errback, timeout)
2614 else:
2615 self._deleteDirectory_SMB1(service_name, p, deleteCB, errback, timeout = 30)
2616 else:
2617 callback(path_file_pattern)
2618
2619 def listCB(files_list):
2620 files_queue.extend(files_list)
2621 deleteCB(None)
2622
2623 if not self.connected_trees.has_key(service_name):
2624 def connectCB(connect_message, **kwargs):
2625 messages_history.append(connect_message)
2626 if not connect_message.status.hasError:
2627 self.connected_trees[service_name] = connect_message.tid
2628 if files_queue:
2629 deleteCB(None)
2630 else:
2631 self._deleteFiles_SMB1__list(service_name, path, pattern, delete_matching_folders, listCB, errback, timeout)
2632 else:
2633 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2634
2635 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
2636 self._sendSMBMessage(m)
2637 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = service_name)
2638 messages_history.append(m)
2639 else:
2640 if files_queue:
2641 deleteCB(None)
2642 else:
2643 self._deleteFiles_SMB1__list(service_name, path, pattern, delete_matching_folders, listCB, errback, timeout)
2644
2645 def _deleteFiles_SMB1__list(self, service_name, path, pattern, delete_matching_folders, callback, errback, timeout = 30):
2646 folder_queue = [ ]
2647 files_list = [ ]
2648 current_path = [ path ]
2649 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL
2650
2651 def listCB(results):
2652 files = [ ]
2653 for f in filter(lambda x: x.filename not in [ '.', '..' ], results):
2654 if f.isDirectory:
2655 if delete_matching_folders:
2656 folder_queue.append(current_path[0]+'\\'+f.filename)
2657 else:
2658 files.append(( current_path[0], f.filename ))
2659 if current_path[0]!=path and delete_matching_folders:
2660 files.append(( current_path[0], None ))
2661
2662 if files:
2663 files_list[0:0] = files
2664
2665 if folder_queue:
2666 p = folder_queue.pop()
2667 current_path[0] = p
2668 self._listPath_SMB1(service_name, current_path[0], listCB, errback, search = search, pattern = '*', timeout = 30)
2669 else:
2670 callback(files_list)
2671
2672 self._listPath_SMB1(service_name, path, listCB, errback, search = search, pattern = pattern, timeout = timeout)
2673
2674
2675 def _deleteFiles_SMB1__del(self, service_name, tid, path, callback, errback, timeout = 30):
23292676 messages_history = [ ]
23302677
23312678 def sendDelete(tid):
23392686 def deleteCB(delete_message, **kwargs):
23402687 messages_history.append(delete_message)
23412688 if not delete_message.status.hasError:
2689 callback(path)
2690 elif delete_message.status.internal_value == 0xC000000FL: # [MS-ERREF]: STATUS_NO_SUCH_FILE
2691 # If there are no matching files, we just treat as success instead of failing
23422692 callback(path_file_pattern)
2343 else:
2344 errback(OperationFailure('Failed to store %s on %s: Delete failed' % ( path, service_name ), messages_history))
2693 elif delete_message.status.internal_value == 0xC00000BAL: # [MS-ERREF]: STATUS_FILE_IS_A_DIRECTORY
2694 errback(OperationFailure('Failed to delete %s on %s: Cannot delete a folder. Please use deleteDirectory() method or append "/*" to your path if you wish to delete all files in the folder.' % ( path, service_name ), messages_history))
2695 elif delete_message.status.internal_value == 0xC0000034L: # [MS-ERREF]: STATUS_OBJECT_NAME_INVALID
2696 errback(OperationFailure('Failed to delete %s on %s: Path not found' % ( path, service_name ), messages_history))
2697 else:
2698 errback(OperationFailure('Failed to delete %s on %s: Delete failed' % ( path, service_name ), messages_history))
2699
2700 sendDelete(tid)
2701
2702 def _resetFileAttributes_SMB1(self, service_name, path_file_pattern, callback, errback, file_attributes=ATTR_NORMAL, timeout = 30):
2703 raise NotReadyError('resetFileAttributes is not yet implemented for SMB1')
2704
2705 def _createDirectory_SMB1(self, service_name, path, callback, errback, timeout = 30):
2706 if not self.has_authenticated:
2707 raise NotReadyError('SMB connection not authenticated')
2708
2709 path = path.replace('/', '\\')
2710 messages_history = [ ]
2711
2712 def sendCreate(tid):
2713 m = SMBMessage(ComCreateDirectoryRequest(path))
2714 m.tid = tid
2715 self._sendSMBMessage(m)
2716 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback)
2717 messages_history.append(m)
2718
2719 def createCB(create_message, **kwargs):
2720 messages_history.append(create_message)
2721 if not create_message.status.hasError:
2722 callback(path)
2723 else:
2724 errback(OperationFailure('Failed to create directory %s on %s: Create failed' % ( path, service_name ), messages_history))
2725
2726 if not self.connected_trees.has_key(service_name):
2727 def connectCB(connect_message, **kwargs):
2728 messages_history.append(connect_message)
2729 if not connect_message.status.hasError:
2730 self.connected_trees[service_name] = connect_message.tid
2731 sendCreate(connect_message.tid)
2732 else:
2733 errback(OperationFailure('Failed to create directory %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2734
2735 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
2736 self._sendSMBMessage(m)
2737 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name)
2738 messages_history.append(m)
2739 else:
2740 sendCreate(self.connected_trees[service_name])
2741
2742 def _deleteDirectory_SMB1(self, service_name, path, callback, errback, timeout = 30):
2743 if not self.has_authenticated:
2744 raise NotReadyError('SMB connection not authenticated')
2745
2746 path = path.replace('/', '\\')
2747 messages_history = [ ]
2748
2749 def sendDelete(tid):
2750 m = SMBMessage(ComDeleteDirectoryRequest(path))
2751 m.tid = tid
2752 self._sendSMBMessage(m)
2753 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback)
2754 messages_history.append(m)
2755
2756 def deleteCB(delete_message, **kwargs):
2757 messages_history.append(delete_message)
2758 if not delete_message.status.hasError:
2759 callback(path)
2760 else:
2761 errback(OperationFailure('Failed to delete directory %s on %s: Delete failed' % ( path, service_name ), messages_history))
23452762
23462763 if not self.connected_trees.has_key(service_name):
23472764 def connectCB(connect_message, **kwargs):
23502767 self.connected_trees[service_name] = connect_message.tid
23512768 sendDelete(connect_message.tid)
23522769 else:
2353 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2354
2355 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
2356 self._sendSMBMessage(m)
2357 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name)
2358 messages_history.append(m)
2359 else:
2360 sendDelete(self.connected_trees[service_name])
2361
2362 def _resetFileAttributes_SMB1(self, service_name, path_file_pattern, callback, errback, timeout = 30):
2363 raise NotReadyError('resetFileAttributes is not yet implemented for SMB1')
2364
2365 def _createDirectory_SMB1(self, service_name, path, callback, errback, timeout = 30):
2366 if not self.has_authenticated:
2367 raise NotReadyError('SMB connection not authenticated')
2368
2369 path = path.replace('/', '\\')
2370 messages_history = [ ]
2371
2372 def sendCreate(tid):
2373 m = SMBMessage(ComCreateDirectoryRequest(path))
2374 m.tid = tid
2375 self._sendSMBMessage(m)
2376 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback)
2377 messages_history.append(m)
2378
2379 def createCB(create_message, **kwargs):
2380 messages_history.append(create_message)
2381 if not create_message.status.hasError:
2382 callback(path)
2383 else:
2384 errback(OperationFailure('Failed to create directory %s on %s: Create failed' % ( path, service_name ), messages_history))
2385
2386 if not self.connected_trees.has_key(service_name):
2387 def connectCB(connect_message, **kwargs):
2388 messages_history.append(connect_message)
2389 if not connect_message.status.hasError:
2390 self.connected_trees[service_name] = connect_message.tid
2391 sendCreate(connect_message.tid)
2392 else:
2393 errback(OperationFailure('Failed to create directory %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2394
2395 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
2396 self._sendSMBMessage(m)
2397 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name)
2398 messages_history.append(m)
2399 else:
2400 sendCreate(self.connected_trees[service_name])
2401
2402 def _deleteDirectory_SMB1(self, service_name, path, callback, errback, timeout = 30):
2403 if not self.has_authenticated:
2404 raise NotReadyError('SMB connection not authenticated')
2405
2406 path = path.replace('/', '\\')
2407 messages_history = [ ]
2408
2409 def sendDelete(tid):
2410 m = SMBMessage(ComDeleteDirectoryRequest(path))
2411 m.tid = tid
2412 self._sendSMBMessage(m)
2413 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback)
2414 messages_history.append(m)
2415
2416 def deleteCB(delete_message, **kwargs):
2417 messages_history.append(delete_message)
2418 if not delete_message.status.hasError:
2419 callback(path)
2420 else:
2421 errback(OperationFailure('Failed to delete directory %s on %s: Delete failed' % ( path, service_name ), messages_history))
2422
2423 if not self.connected_trees.has_key(service_name):
2424 def connectCB(connect_message, **kwargs):
2425 messages_history.append(connect_message)
2426 if not connect_message.status.hasError:
2427 self.connected_trees[service_name] = connect_message.tid
2428 sendDelete(connect_message.tid)
2429 else:
2430 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2770 errback(OperationFailure('Failed to delete directory %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
24312771
24322772 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
24332773 self._sendSMBMessage(m)
25622902 def _echo_SMB1(self, data, callback, errback, timeout = 30):
25632903 messages_history = [ ]
25642904
2905 if not isinstance(data, type(b'')):
2906 raise TypeError('Echo data must be %s not %s' % (type(b'').__name__, type(data).__name__))
2907
25652908 def echoCB(echo_message, **kwargs):
25662909 messages_history.append(echo_message)
25672910 if not echo_message.status.hasError:
25742917 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, echoCB, errback)
25752918 messages_history.append(m)
25762919
2920 def _extractLastPathComponent(self, path):
2921 return path.replace('\\', '/').split('/')[-1]
2922
25772923
25782924 class SharedDevice:
25792925 """
25802926 Contains information about a single shared device on the remote server.
2927
2928 The following attributes are available:
2929
2930 * name : An unicode string containing the name of the shared device
2931 * comments : An unicode string containing the user description of the shared device
25812932 """
25822933
25832934 # The following constants are taken from [MS-SRVS]: 2.2.2.4
26322983
26332984 If you encounter *SharedFile* instance where its short_name attribute is empty but the filename attribute contains a short name which does not correspond
26342985 to any files/folders on your remote shared device, it could be that the original filename on the file/folder entry on the shared device contains
2635 one of these prohibited characters: "\/[]:+|<>=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).
2986 one of these prohibited characters: "\\/[]:+|<>=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).
2987
2988 The following attributes are available:
2989
2990 * create_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server
2991 * last_access_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server
2992 * last_write_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server
2993 * last_attr_change_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server
2994 * file_size : File size in number of bytes
2995 * alloc_size : Total number of bytes allocated to store this file
2996 * file_attributes : A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3. You can perform bit-wise tests to determine the status of the file using the ATTR_xxx constants in smb_constants.py.
2997 * short_name : Unicode string containing the short name of this file (usually in 8.3 notation)
2998 * filename : Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.
2999 * file_id : Long value representing the file reference number for the file. If the remote system does not support this field, this field will be None or 0. See [MS-FSCC]: 2.4.17
26363000 """
26373001
2638 def __init__(self, create_time, last_access_time, last_write_time, last_attr_change_time, file_size, alloc_size, file_attributes, short_name, filename):
3002 def __init__(self, create_time, last_access_time, last_write_time, last_attr_change_time, file_size, alloc_size, file_attributes, short_name, filename, file_id=None):
26393003 self.create_time = create_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server
26403004 self.last_access_time = last_access_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server
26413005 self.last_write_time = last_write_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server
26423006 self.last_attr_change_time = last_attr_change_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server
26433007 self.file_size = file_size #: File size in number of bytes
26443008 self.alloc_size = alloc_size #: Total number of bytes allocated to store this file
2645 self.file_attributes = file_attributes #: A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3
3009 self.file_attributes = file_attributes #: A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3. You can perform bit-wise tests to determine the status of the file using the ATTR_xxx constants in smb_constants.py.
26463010 self.short_name = short_name #: Unicode string containing the short name of this file (usually in 8.3 notation)
26473011 self.filename = filename #: Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.
3012 self.file_id = file_id #: Long value representing the file reference number for the file. If the remote system does not support this field, this field will be None or 0. See [MS-FSCC]: 2.4.17
26483013
26493014 @property
26503015 def isDirectory(self):
26553020 def isReadOnly(self):
26563021 """A convenient property to return True if this file resource is read-only on the remote server"""
26573022 return bool(self.file_attributes & ATTR_READONLY)
3023
3024 @property
3025 def isNormal(self):
3026 """
3027 A convenient property to return True if this is a normal file.
3028
3029 Note that pysmb defines a normal file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.
3030 It ignores other attributes like compression, indexed, sparse, temporary and encryption.
3031 """
3032 return (self.file_attributes==ATTR_NORMAL) or ((self.file_attributes & 0xff)==0)
26583033
26593034 def __unicode__(self):
26603035 return u'Shared file: %s (FileSize:%d bytes, isDirectory:%s)' % ( self.filename, self.file_size, self.isDirectory )
00
1 import types, hmac, binascii, struct, random
1 import types, hmac, binascii, struct, random, string
2 from .utils.rc4 import RC4_encrypt
23 from utils.pyDes import des
34
45 try:
5758
5859 NTLM_FLAGS = NTLM_NegotiateUnicode | \
5960 NTLM_RequestTarget | \
61 NTLM_NegotiateSign | \
6062 NTLM_NegotiateNTLM | \
6163 NTLM_NegotiateAlwaysSign | \
6264 NTLM_NegotiateExtendedSecurity | \
6365 NTLM_NegotiateTargetInfo | \
6466 NTLM_NegotiateVersion | \
6567 NTLM_Negotiate128 | \
66 NTLM_NegotiateKeyExchange | \
67 NTLM_Negotiate56
68 NTLM_NegotiateKeyExchange
6869
6970 def generateNegotiateMessage():
7071 """
8081 return s
8182
8283
83 def generateAuthenticateMessage(challenge_flags, nt_response, lm_response, session_key, user, domain = 'WORKGROUP', workstation = 'LOCALHOST'):
84 def generateAuthenticateMessage(challenge_flags, nt_response, lm_response, request_session_key, user, domain = 'WORKGROUP', workstation = 'LOCALHOST'):
8485 """
8586 References:
8687 ===========
8889 """
8990 FORMAT = '<8sIHHIHHIHHIHHIHHIHHII'
9091 FORMAT_SIZE = struct.calcsize(FORMAT)
92
93 # [MS-NLMP]: 3.1.5.1.2
94 # http://grutz.jingojango.net/exploits/davenport-ntlm.html
95 session_key = session_signing_key = request_session_key
96 if challenge_flags & NTLM_NegotiateKeyExchange:
97 session_signing_key = "".join([ random.choice(string.digits+string.ascii_letters) for _ in range(16) ]).encode('ascii')
98 session_key = RC4_encrypt(request_session_key, session_signing_key)
9199
92100 lm_response_length = len(lm_response)
93101 lm_response_offset = FORMAT_SIZE
124132 session_key_length, session_key_length, session_key_offset,
125133 auth_flags)
126134
127 return s + lm_response + nt_response + padding + domain_unicode + user_unicode + workstation_unicode + session_key
135 return s + lm_response + nt_response + padding + domain_unicode + user_unicode + workstation_unicode + session_key, session_signing_key
128136
129137
130138 def decodeChallengeMessage(ntlm_data):
0 """
1 This module implements security descriptors, and the partial structures
2 used in them, as specified in [MS-DTYP].
3 """
4
5 import struct
6
7
8 # Security descriptor control flags
9 # [MS-DTYP]: 2.4.6
10 SECURITY_DESCRIPTOR_OWNER_DEFAULTED = 0x0001
11 SECURITY_DESCRIPTOR_GROUP_DEFAULTED = 0x0002
12 SECURITY_DESCRIPTOR_DACL_PRESENT = 0x0004
13 SECURITY_DESCRIPTOR_DACL_DEFAULTED = 0x0008
14 SECURITY_DESCRIPTOR_SACL_PRESENT = 0x0010
15 SECURITY_DESCRIPTOR_SACL_DEFAULTED = 0x0020
16 SECURITY_DESCRIPTOR_SERVER_SECURITY = 0x0040
17 SECURITY_DESCRIPTOR_DACL_TRUSTED = 0x0080
18 SECURITY_DESCRIPTOR_DACL_COMPUTED_INHERITANCE_REQUIRED = 0x0100
19 SECURITY_DESCRIPTOR_SACL_COMPUTED_INHERITANCE_REQUIRED = 0x0200
20 SECURITY_DESCRIPTOR_DACL_AUTO_INHERITED = 0x0400
21 SECURITY_DESCRIPTOR_SACL_AUTO_INHERITED = 0x0800
22 SECURITY_DESCRIPTOR_DACL_PROTECTED = 0x1000
23 SECURITY_DESCRIPTOR_SACL_PROTECTED = 0x2000
24 SECURITY_DESCRIPTOR_RM_CONTROL_VALID = 0x4000
25 SECURITY_DESCRIPTOR_SELF_RELATIVE = 0x8000
26
27 # ACE types
28 # [MS-DTYP]: 2.4.4.1
29 ACE_TYPE_ACCESS_ALLOWED = 0x00
30 ACE_TYPE_ACCESS_DENIED = 0x01
31 ACE_TYPE_SYSTEM_AUDIT = 0x02
32 ACE_TYPE_SYSTEM_ALARM = 0x03
33 ACE_TYPE_ACCESS_ALLOWED_COMPOUND = 0x04
34 ACE_TYPE_ACCESS_ALLOWED_OBJECT = 0x05
35 ACE_TYPE_ACCESS_DENIED_OBJECT = 0x06
36 ACE_TYPE_SYSTEM_AUDIT_OBJECT = 0x07
37 ACE_TYPE_SYSTEM_ALARM_OBJECT = 0x08
38 ACE_TYPE_ACCESS_ALLOWED_CALLBACK = 0x09
39 ACE_TYPE_ACCESS_DENIED_CALLBACK = 0x0A
40 ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT = 0x0B
41 ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT = 0x0C
42 ACE_TYPE_SYSTEM_AUDIT_CALLBACK = 0x0D
43 ACE_TYPE_SYSTEM_ALARM_CALLBACK = 0x0E
44 ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT = 0x0F
45 ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT = 0x10
46 ACE_TYPE_SYSTEM_MANDATORY_LABEL = 0x11
47 ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE = 0x12
48 ACE_TYPE_SYSTEM_SCOPED_POLICY_ID = 0x13
49
50 # ACE flags
51 # [MS-DTYP]: 2.4.4.1
52 ACE_FLAG_OBJECT_INHERIT = 0x01
53 ACE_FLAG_CONTAINER_INHERIT = 0x02
54 ACE_FLAG_NO_PROPAGATE_INHERIT = 0x04
55 ACE_FLAG_INHERIT_ONLY = 0x08
56 ACE_FLAG_INHERITED = 0x10
57 ACE_FLAG_SUCCESSFUL_ACCESS = 0x40
58 ACE_FLAG_FAILED_ACCESS = 0x80
59
60 # Pre-defined well-known SIDs
61 # [MS-DTYP]: 2.4.2.4
62 SID_NULL = "S-1-0-0"
63 SID_EVERYONE = "S-1-1-0"
64 SID_LOCAL = "S-1-2-0"
65 SID_CONSOLE_LOGON = "S-1-2-1"
66 SID_CREATOR_OWNER = "S-1-3-0"
67 SID_CREATOR_GROUP = "S-1-3-1"
68 SID_OWNER_SERVER = "S-1-3-2"
69 SID_GROUP_SERVER = "S-1-3-3"
70 SID_OWNER_RIGHTS = "S-1-3-4"
71 SID_NT_AUTHORITY = "S-1-5"
72 SID_DIALUP = "S-1-5-1"
73 SID_NETWORK = "S-1-5-2"
74 SID_BATCH = "S-1-5-3"
75 SID_INTERACTIVE = "S-1-5-4"
76 SID_SERVICE = "S-1-5-6"
77 SID_ANONYMOUS = "S-1-5-7"
78 SID_PROXY = "S-1-5-8"
79 SID_ENTERPRISE_DOMAIN_CONTROLLERS = "S-1-5-9"
80 SID_PRINCIPAL_SELF = "S-1-5-10"
81 SID_AUTHENTICATED_USERS = "S-1-5-11"
82 SID_RESTRICTED_CODE = "S-1-5-12"
83 SID_TERMINAL_SERVER_USER = "S-1-5-13"
84 SID_REMOTE_INTERACTIVE_LOGON = "S-1-5-14"
85 SID_THIS_ORGANIZATION = "S-1-5-15"
86 SID_IUSR = "S-1-5-17"
87 SID_LOCAL_SYSTEM = "S-1-5-18"
88 SID_LOCAL_SERVICE = "S-1-5-19"
89 SID_NETWORK_SERVICE = "S-1-5-20"
90 SID_COMPOUNDED_AUTHENTICATION = "S-1-5-21-0-0-0-496"
91 SID_CLAIMS_VALID = "S-1-5-21-0-0-0-497"
92 SID_BUILTIN_ADMINISTRATORS = "S-1-5-32-544"
93 SID_BUILTIN_USERS = "S-1-5-32-545"
94 SID_BUILTIN_GUESTS = "S-1-5-32-546"
95 SID_POWER_USERS = "S-1-5-32-547"
96 SID_ACCOUNT_OPERATORS = "S-1-5-32-548"
97 SID_SERVER_OPERATORS = "S-1-5-32-549"
98 SID_PRINTER_OPERATORS = "S-1-5-32-550"
99 SID_BACKUP_OPERATORS = "S-1-5-32-551"
100 SID_REPLICATOR = "S-1-5-32-552"
101 SID_ALIAS_PREW2KCOMPACC = "S-1-5-32-554"
102 SID_REMOTE_DESKTOP = "S-1-5-32-555"
103 SID_NETWORK_CONFIGURATION_OPS = "S-1-5-32-556"
104 SID_INCOMING_FOREST_TRUST_BUILDERS = "S-1-5-32-557"
105 SID_PERFMON_USERS = "S-1-5-32-558"
106 SID_PERFLOG_USERS = "S-1-5-32-559"
107 SID_WINDOWS_AUTHORIZATION_ACCESS_GROUP = "S-1-5-32-560"
108 SID_TERMINAL_SERVER_LICENSE_SERVERS = "S-1-5-32-561"
109 SID_DISTRIBUTED_COM_USERS = "S-1-5-32-562"
110 SID_IIS_IUSRS = "S-1-5-32-568"
111 SID_CRYPTOGRAPHIC_OPERATORS = "S-1-5-32-569"
112 SID_EVENT_LOG_READERS = "S-1-5-32-573"
113 SID_CERTIFICATE_SERVICE_DCOM_ACCESS = "S-1-5-32-574"
114 SID_RDS_REMOTE_ACCESS_SERVERS = "S-1-5-32-575"
115 SID_RDS_ENDPOINT_SERVERS = "S-1-5-32-576"
116 SID_RDS_MANAGEMENT_SERVERS = "S-1-5-32-577"
117 SID_HYPER_V_ADMINS = "S-1-5-32-578"
118 SID_ACCESS_CONTROL_ASSISTANCE_OPS = "S-1-5-32-579"
119 SID_REMOTE_MANAGEMENT_USERS = "S-1-5-32-580"
120 SID_WRITE_RESTRICTED_CODE = "S-1-5-33"
121 SID_NTLM_AUTHENTICATION = "S-1-5-64-10"
122 SID_SCHANNEL_AUTHENTICATION = "S-1-5-64-14"
123 SID_DIGEST_AUTHENTICATION = "S-1-5-64-21"
124 SID_THIS_ORGANIZATION_CERTIFICATE = "S-1-5-65-1"
125 SID_NT_SERVICE = "S-1-5-80"
126 SID_USER_MODE_DRIVERS = "S-1-5-84-0-0-0-0-0"
127 SID_LOCAL_ACCOUNT = "S-1-5-113"
128 SID_LOCAL_ACCOUNT_AND_MEMBER_OF_ADMINISTRATORS_GROUP = "S-1-5-114"
129 SID_OTHER_ORGANIZATION = "S-1-5-1000"
130 SID_ALL_APP_PACKAGES = "S-1-15-2-1"
131 SID_ML_UNTRUSTED = "S-1-16-0"
132 SID_ML_LOW = "S-1-16-4096"
133 SID_ML_MEDIUM = "S-1-16-8192"
134 SID_ML_MEDIUM_PLUS = "S-1-16-8448"
135 SID_ML_HIGH = "S-1-16-12288"
136 SID_ML_SYSTEM = "S-1-16-16384"
137 SID_ML_PROTECTED_PROCESS = "S-1-16-20480"
138 SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = "S-1-18-1"
139 SID_SERVICE_ASSERTED_IDENTITY = "S-1-18-2"
140 SID_FRESH_PUBLIC_KEY_IDENTITY = "S-1-18-3"
141 SID_KEY_TRUST_IDENTITY = "S-1-18-4"
142 SID_KEY_PROPERTY_MFA = "S-1-18-5"
143 SID_KEY_PROPERTY_ATTESTATION = "S-1-18-6"
144
145
146 class SID(object):
147 """
148 A Windows security identifier. Represents a single principal, such a
149 user or a group, as a sequence of numbers consisting of the revision,
150 identifier authority, and a variable-length list of subauthorities.
151
152 See [MS-DTYP]: 2.4.2
153 """
154 def __init__(self, revision, identifier_authority, subauthorities):
155 #: Revision, should always be 1.
156 self.revision = revision
157 #: An integer representing the identifier authority.
158 self.identifier_authority = identifier_authority
159 #: A list of integers representing all subauthorities.
160 self.subauthorities = subauthorities
161
162 def __str__(self):
163 """
164 String representation, as specified in [MS-DTYP]: 2.4.2.1
165 """
166 if self.identifier_authority >= 2**32:
167 id_auth = '%#x' % (self.identifier_authority,)
168 else:
169 id_auth = self.identifier_authority
170 auths = [self.revision, id_auth] + self.subauthorities
171 return 'S-' + '-'.join(str(subauth) for subauth in auths)
172
173 def __repr__(self):
174 return 'SID(%r)' % (str(self),)
175
176 @classmethod
177 def from_bytes(cls, data, return_tail=False):
178 revision, subauth_count = struct.unpack('<BB', data[:2])
179 identifier_authority = struct.unpack('>Q', '\x00\x00' + data[2:8])[0]
180 subauth_data = data[8:]
181 subauthorities = [struct.unpack('<L', subauth_data[4 * i : 4 * (i+1)])[0]
182 for i in range(subauth_count)]
183 sid = cls(revision, identifier_authority, subauthorities)
184 if return_tail:
185 return sid, subauth_data[4 * subauth_count :]
186 return sid
187
188
189 class ACE(object):
190 """
191 Represents a single access control entry.
192
193 See [MS-DTYP]: 2.4.4
194 """
195 HEADER_FORMAT = '<BBH'
196
197 def __init__(self, type_, flags, mask, sid, additional_data):
198 #: An integer representing the type of the ACE. One of the
199 #: ``ACE_TYPE_*`` constants. Corresponds to the ``AceType`` field
200 #: from [MS-DTYP] 2.4.4.1.
201 self.type = type_
202 #: An integer bitmask with ACE flags, corresponds to the
203 #: ``AceFlags`` field.
204 self.flags = flags
205 #: An integer representing the ``ACCESS_MASK`` as specified in
206 #: [MS-DTYP] 2.4.3.
207 self.mask = mask
208 #: The :class:`SID` of a trustee.
209 self.sid = sid
210 #: A dictionary of additional fields present in the ACE, depending
211 #: on the type. The following fields can be present:
212 #:
213 #: * ``flags``
214 #: * ``object_type``
215 #: * ``inherited_object_type``
216 #: * ``application_data``
217 #: * ``attribute_data``
218 self.additional_data = additional_data
219
220 def __repr__(self):
221 return "ACE(type=%#04x, flags=%#04x, mask=%#010x, sid=%s)" % (
222 self.type, self.flags, self.mask, self.sid,
223 )
224
225 @property
226 def isInheritOnly(self):
227 """Convenience property which indicates if this ACE is inherit
228 only, meaning that it doesn't apply to the object itself."""
229 return bool(self.flags & ACE_FLAG_INHERIT_ONLY)
230
231 @classmethod
232 def from_bytes(cls, data):
233 header_size = struct.calcsize(cls.HEADER_FORMAT)
234 header = data[:header_size]
235 type_, flags, size = struct.unpack(cls.HEADER_FORMAT, header)
236
237 assert len(data) >= size
238
239 body = data[header_size:size]
240 additional_data = {}
241
242 # In all ACE types, the mask immediately follows the header.
243 mask = struct.unpack('<I', body[:4])[0]
244 body = body[4:]
245
246 # All OBJECT-type ACEs contain additional flags, and two GUIDs as
247 # the following fields.
248 if type_ in (ACE_TYPE_ACCESS_ALLOWED_OBJECT,
249 ACE_TYPE_ACCESS_DENIED_OBJECT,
250 ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT,
251 ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT,
252 ACE_TYPE_SYSTEM_AUDIT_OBJECT,
253 ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT):
254 additional_data['flags'] = struct.unpack('<I', body[:4])[0]
255 additional_data['object_type'] = body[4:20]
256 additional_data['inherited_object_type'] = body[20:36]
257 body = body[36:]
258
259 # Then the SID in all types.
260 sid, body = SID.from_bytes(body, return_tail=True)
261
262 # CALLBACK-type ACEs (and for some obscure reason,
263 # SYSTEM_AUDIT_OBJECT) have a final tail of application data.
264 if type_ in (ACE_TYPE_ACCESS_ALLOWED_CALLBACK,
265 ACE_TYPE_ACCESS_DENIED_CALLBACK,
266 ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT,
267 ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT,
268 ACE_TYPE_SYSTEM_AUDIT_OBJECT,
269 ACE_TYPE_SYSTEM_AUDIT_CALLBACK,
270 ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT):
271 additional_data['application_data'] = body
272
273 # SYSTEM_RESOURCE_ATTRIBUTE ACEs have a tail of attribute data.
274 if type_ == ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE:
275 additional_data['attribute_data'] = body
276
277 return cls(type_, flags, mask, sid, additional_data)
278
279
280 class ACL(object):
281 """
282 Access control list, encapsulating a sequence of access control
283 entries.
284
285 See [MS-DTYP]: 2.4.5
286 """
287 HEADER_FORMAT = '<BBHHH'
288
289 def __init__(self, revision, aces):
290 #: Integer value of the revision.
291 self.revision = revision
292 #: List of :class:`ACE` instances.
293 self.aces = aces
294
295 def __repr__(self):
296 return "ACL(%r)" % (self.aces,)
297
298 @classmethod
299 def from_bytes(cls, data):
300 revision = None
301 aces = []
302
303 header_size = struct.calcsize(cls.HEADER_FORMAT)
304 header, remaining = data[:header_size], data[header_size:]
305 revision, sbz1, size, count, sbz2 = struct.unpack(cls.HEADER_FORMAT, header)
306
307 assert len(data) >= size
308
309 for i in range(count):
310 ace_size = struct.unpack('<H', remaining[2:4])[0]
311 ace_data, remaining = remaining[:ace_size], remaining[ace_size:]
312 aces.append(ACE.from_bytes(ace_data))
313
314 return cls(revision, aces)
315
316
317 class SecurityDescriptor(object):
318 """
319 Represents a security descriptor.
320
321 See [MS-DTYP]: 2.4.6
322 """
323
324 HEADER_FORMAT = '<BBHIIII'
325
326 def __init__(self, flags, owner, group, dacl, sacl):
327 #: Integer bitmask of control flags. Corresponds to the
328 #: ``Control`` field in [MS-DTYP] 2.4.6.
329 self.flags = flags
330 #: Instance of :class:`SID` representing the owner user.
331 self.owner = owner
332 #: Instance of :class:`SID` representing the owner group.
333 self.group = group
334 #: Instance of :class:`ACL` representing the discretionary access
335 #: control list, which specifies access restrictions of an object.
336 self.dacl = dacl
337 #: Instance of :class:`ACL` representing the system access control
338 #: list, which specifies audit logging of an object.
339 self.sacl = sacl
340
341 @classmethod
342 def from_bytes(cls, data):
343 owner = None
344 group = None
345 dacl = None
346 sacl = None
347
348 header = data[:struct.calcsize(cls.HEADER_FORMAT)]
349 (revision, sbz1, flags, owner_offset, group_offset, sacl_offset,
350 dacl_offset) = struct.unpack(cls.HEADER_FORMAT, header)
351
352 assert revision == 1
353 assert flags & SECURITY_DESCRIPTOR_SELF_RELATIVE
354 for offset in (owner_offset, group_offset, sacl_offset, dacl_offset):
355 assert 0 <= offset < len(data)
356
357 if owner_offset:
358 owner = SID.from_bytes(data[owner_offset:])
359 if group_offset:
360 group = SID.from_bytes(data[group_offset:])
361 if dacl_offset:
362 dacl = ACL.from_bytes(data[dacl_offset:])
363 if sacl_offset:
364 sacl = ACL.from_bytes(data[sacl_offset:])
365
366 return cls(flags, owner, group, dacl, sacl)
269269 STRUCTURE_FORMAT = "<HHHH"
270270 STRUCTURE_SIZE = struct.calcsize(STRUCTURE_FORMAT)
271271
272 @property
273 def isGuestSession(self):
274 return (self.session_flags & 0x0001) > 0 # SMB2_SESSION_FLAG_IS_GUEST
275
276 @property
277 def isAnonymousSession(self):
278 return (self.session_flags & 0x0002) > 0 # SMB2_SESSION_FLAG_IS_NULL
279
272280 def decode(self, message):
273281 assert message.command == SMB2_COM_SESSION_SETUP
274282
361369
362370 def prepare(self, message):
363371 buf = self.filename.encode('UTF-16LE')
372 filename_len = len(buf)
364373 if self.create_context_data:
365374 n = SMB2Message.HEADER_SIZE + self.STRUCTURE_SIZE + len(buf)
366375 if n % 8 != 0:
388397 self.create_disp,
389398 self.create_options,
390399 SMB2Message.HEADER_SIZE + self.STRUCTURE_SIZE, # NameOffset
391 len(self.filename)*2, # NameLength in bytes
400 filename_len, # Length of encoded filename in bytes
392401 create_context_offset, # CreateContextOffset
393402 len(self.create_context_data) # CreateContextLength
394403 ) + buf
114114 FILE_READ_EA = 0x08
115115 FILE_WRITE_EA = 0x10
116116 FILE_EXECUTE = 0x20
117 FILE_DELETE_CHILD = 0x40
117118 FILE_READ_ATTRIBUTES = 0x80
118119 FILE_WRITE_ATTRIBUTES = 0x0100
119120 DELETE = 0x010000
224225 SMB_FILE_ATTRIBUTE_READONLY = 0x01
225226 SMB_FILE_ATTRIBUTE_HIDDEN = 0x02
226227 SMB_FILE_ATTRIBUTE_SYSTEM = 0x04
227 SMB_FILE_ATTRIBUTE_VOLUME = 0x08
228 SMB_FILE_ATTRIBUTE_VOLUME = 0x08 # Unsupported for listPath() operations
228229 SMB_FILE_ATTRIBUTE_DIRECTORY = 0x10
229230 SMB_FILE_ATTRIBUTE_ARCHIVE = 0x20
231 # SMB_FILE_ATTRIBUTE_INCL_NORMAL is a special placeholder to include normal files for
232 # with other search attributes for listPath() operations. It is not defined in the MS-CIFS specs.
233 SMB_FILE_ATTRIBUTE_INCL_NORMAL = 0x10000
234 # Do not use the following values for listPath() operations as they are not supported for SMB2
230235 SMB_SEARCH_ATTRIBUTE_READONLY = 0x0100
231236 SMB_SEARCH_ATTRIBUTE_HIDDEN = 0x0200
232237 SMB_SEARCH_ATTRIBUTE_SYSTEM = 0x0400
236241 # Bitmask for OptionalSupport field in SMB_COM_TREE_CONNECT_ANDX response
237242 SMB_TREE_CONNECTX_SUPPORT_SEARCH = 0x0001
238243 SMB_TREE_CONNECTX_SUPPORT_DFS = 0x0002
244
245 # Bitmask for security information fields, specified as
246 # AdditionalInformation in SMB2
247 # [MS-SMB]: 2.2.7.4
248 # [MS-SMB2]: 2.2.37
249 OWNER_SECURITY_INFORMATION = 0x00000001
250 GROUP_SECURITY_INFORMATION = 0x00000002
251 DACL_SECURITY_INFORMATION = 0x00000004
252 SACL_SECURITY_INFORMATION = 0x00000008
253 LABEL_SECURITY_INFORMATION = 0x00000010
254 ATTRIBUTE_SECURITY_INFORMATION = 0x00000020
255 SCOPE_SECURITY_INFORMATION = 0x00000040
256 BACKUP_SECURITY_INFORMATION = 0x00010000
12791279 - [MS-CIFS]: 2.2.4.39.1
12801280 """
12811281
1282 def __init__(self, echo_data = '', echo_count = 1):
1282 def __init__(self, echo_data = b'', echo_count = 1):
12831283 self.echo_count = echo_count
12841284 self.echo_data = echo_data
12851285
0
1 def RC4_encrypt(key, data):
2 S = list(range(256))
3 j = 0
4
5 key_len = len(key)
6 for i in list(range(256)):
7 j = (j + S[i] + ord(key[i % key_len])) % 256
8 S[i], S[j] = S[j], S[i]
9
10 j = 0
11 y = 0
12 out = []
13
14 for char in data:
15 j = (j + 1) % 256
16 y = (y + S[j]) % 256
17 S[j], S[y] = S[y], S[j]
18
19 out.append(chr(ord(char) ^ S[(S[j] + S[y]) % 256]))
20
21 return ''.join(out)
0 #!/usr/bin/python
10 __author__ = 'Thomas Dixon'
21 __license__ = 'MIT'
32
33 from nose.tools import with_setup
44 from smb import smb_structs
55
6 conn = None
6 conn, conn2, conn3 = None, None, None
77
88 def teardown_func():
9 global conn
10 conn.close()
9 global conn, conn2, conn3
10 if conn:
11 conn.close()
12 if conn2:
13 conn2.close()
14 if conn3:
15 conn3.close();
1116
1217 @with_setup(teardown = teardown_func)
1318 def test_NTLMv1_auth_SMB1():
14 global conn
19 global conn, conn2, conn3
1520 smb_structs.SUPPORT_SMB2 = False
1621 info = getConnectionInfo()
17 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False)
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
1823 assert conn.connect(info['server_ip'], info['server_port'])
24
25 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
26 assert not conn2.connect(info['server_ip'], info['server_port'])
27
28 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
29 assert not conn3.connect(info['server_ip'], info['server_port'])
30
31 @with_setup(teardown = teardown_func)
32 def test_NTLMv1_auth_SMB1_callable_password():
33 global conn, conn2, conn3
34 smb_structs.SUPPORT_SMB2 = False
35 info = getConnectionInfo()
36 conn = SMBConnection(info['user'], lambda: info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
37 assert conn.connect(info['server_ip'], info['server_port'])
38
39 conn2 = SMBConnection(info['user'], lambda: 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
40 assert not conn2.connect(info['server_ip'], info['server_port'])
41
42 conn3 = SMBConnection('INVALIDUSER', lambda: 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
43 assert not conn3.connect(info['server_ip'], info['server_port'])
1944
2045 @with_setup(teardown = teardown_func)
2146 def test_NTLMv2_auth_SMB1():
22 global conn
47 global conn, conn2, conn3
2348 smb_structs.SUPPORT_SMB2 = False
2449 info = getConnectionInfo()
25 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
50 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2651 assert conn.connect(info['server_ip'], info['server_port'])
52
53 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
54 assert not conn2.connect(info['server_ip'], info['server_port'])
55
56 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
57 assert not conn3.connect(info['server_ip'], info['server_port'])
2758
2859 @with_setup(teardown = teardown_func)
2960 def test_NTLMv1_auth_SMB2():
30 global conn
61 global conn, conn2, conn3
3162 smb_structs.SUPPORT_SMB2 = True
3263 info = getConnectionInfo()
33 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False)
64 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
3465 assert conn.connect(info['server_ip'], info['server_port'])
66
67 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
68 assert not conn2.connect(info['server_ip'], info['server_port'])
69
70 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
71 assert not conn3.connect(info['server_ip'], info['server_port'])
3572
3673 @with_setup(teardown = teardown_func)
3774 def test_NTLMv2_auth_SMB2():
38 global conn
75 global conn, conn2, conn3
3976 smb_structs.SUPPORT_SMB2 = True
4077 info = getConnectionInfo()
41 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
78 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
4279 assert conn.connect(info['server_ip'], info['server_port'])
80
81 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
82 assert not conn2.connect(info['server_ip'], info['server_port'])
83
84 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
85 assert not conn3.connect(info['server_ip'], info['server_port'])
1212 smb_structs.SUPPORT_SMB2 = False
1313
1414 info = getConnectionInfo()
15 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
15 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1616 assert conn.connect(info['server_ip'], info['server_port'])
1717
1818 def setup_func_SMB2():
2020 smb_structs.SUPPORT_SMB2 = True
2121
2222 info = getConnectionInfo()
23 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
23 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2424 assert conn.connect(info['server_ip'], info['server_port'])
2525
2626 def teardown_func():
88 def setup_func():
99 global conn
1010 info = getConnectionInfo()
11 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
11 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1212 assert conn.connect(info['server_ip'], info['server_port'])
1313
1414 def teardown_func():
2121
2222 data = '%d' % random.randint(1000, 9999)
2323 assert conn.echo(data) == data
24
00 # -*- coding: utf-8 -*-
11
22 from smb.SMBConnection import SMBConnection
3 from smb.smb_constants import *
34 from util import getConnectionInfo
45 from nose.tools import with_setup
56 from smb import smb_structs
1011 global conn
1112 smb_structs.SUPPORT_SMB2 = False
1213 info = getConnectionInfo()
13 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
14 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1415 assert conn.connect(info['server_ip'], info['server_port'])
1516
1617 def setup_func_SMB2():
1718 global conn
1819 smb_structs.SUPPORT_SMB2 = True
1920 info = getConnectionInfo()
20 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
21 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2122 assert conn.connect(info['server_ip'], info['server_port'])
2223
2324 def teardown_func():
4445 assert ( u'Test Folder', True ) in filenames
4546 assert ( u'子文件夹', True ) in filenames
4647
48 @with_setup(setup_func_SMB1, teardown_func)
49 def test_listPathWithManyFiles_SMB1():
50 global conn
51 results = conn.listPath('smbtest', '/RFC Archive/')
52 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
53 assert len(filenames)==999
54
4755 @with_setup(setup_func_SMB2, teardown_func)
4856 def test_listPath_SMB2():
4957 global conn
6371 assert ( u'Test File.txt', False ) in filenames
6472 assert ( u'Test Folder', True ) in filenames
6573 assert ( u'子文件夹', True ) in filenames
74
75 @with_setup(setup_func_SMB2, teardown_func)
76 def test_listPathWithManyFiles_SMB2():
77 global conn
78 results = conn.listPath('smbtest', '/RFC Archive/')
79 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
80 assert len(filenames)==999
81
82 @with_setup(setup_func_SMB1, teardown_func)
83 def test_listPathFilterForDirectory_SMB1():
84 global conn
85 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_DIRECTORY)
86 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
87 assert len(filenames) > 0
88 for f, isDirectory in filenames:
89 assert isDirectory
90
91 @with_setup(setup_func_SMB2, teardown_func)
92 def test_listPathFilterForDirectory_SMB2():
93 global conn
94 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_DIRECTORY)
95 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
96 assert len(filenames) > 0
97 for f, isDirectory in filenames:
98 assert isDirectory
99
100 @with_setup(setup_func_SMB1, teardown_func)
101 def test_listPathFilterForFiles_SMB1():
102 global conn
103 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL)
104 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
105 assert len(filenames) > 0
106 for f, isDirectory in filenames:
107 assert not isDirectory
108
109 @with_setup(setup_func_SMB2, teardown_func)
110 def test_listPathFilterForFiles_SMB2():
111 global conn
112 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL)
113 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
114 assert len(filenames) > 0
115 for f, isDirectory in filenames:
116 assert not isDirectory
117
118 @with_setup(setup_func_SMB1, teardown_func)
119 def test_listPathFilterPattern_SMB1():
120 global conn
121 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = 'Test*')
122 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
123 assert len(filenames) == 2
124 assert ( u'Test File.txt', False ) in filenames
125 assert ( u'Test Folder', True ) in filenames
126 assert ( u'子文件夹', True ) not in filenames
127
128 @with_setup(setup_func_SMB2, teardown_func)
129 def test_listPathFilterPattern_SMB2():
130 global conn
131 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = 'Test*')
132 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
133 assert len(filenames) == 2
134 assert ( u'Test File.txt', False ) in filenames
135 assert ( u'Test Folder', True ) in filenames
136 assert ( u'子文件夹', True ) not in filenames
137
138 @with_setup(setup_func_SMB1, teardown_func)
139 def test_listPathFilterUnicodePattern_SMB1():
140 global conn
141 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = u'*件夹')
142 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
143 assert len(filenames) == 1
144 assert ( u'Test File.txt', False ) not in filenames
145 assert ( u'Test Folder', True ) not in filenames
146 assert ( u'子文件夹', True ) in filenames
147
148 @with_setup(setup_func_SMB2, teardown_func)
149 def test_listPathFilterUnicodePattern_SMB2():
150 global conn
151 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = u'*件夹')
152 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
153 assert len(filenames) == 1
154 assert ( u'Test File.txt', False ) not in filenames
155 assert ( u'Test Folder', True ) not in filenames
156 assert ( u'子文件夹', True ) in filenames
99 global conn
1010 smb_structs.SUPPORT_SMB2 = False
1111 info = getConnectionInfo()
12 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
12 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1313 assert conn.connect(info['server_ip'], info['server_port'])
1414
1515 def setup_func_SMB2():
1616 global conn
1717 smb_structs.SUPPORT_SMB2 = True
1818 info = getConnectionInfo()
19 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
19 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2020 assert conn.connect(info['server_ip'], info['server_port'])
2121
2222 def teardown_func():
99 global conn
1010 smb_structs.SUPPORT_SMB2 = False
1111 info = getConnectionInfo()
12 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
12 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1313 assert conn.connect(info['server_ip'], info['server_port'])
1414
1515 def setup_func_SMB2():
1616 global conn
1717 smb_structs.SUPPORT_SMB2 = True
1818 info = getConnectionInfo()
19 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
19 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2020 assert conn.connect(info['server_ip'], info['server_port'])
2121
2222 def teardown_func():
1212 global conn
1313 smb_structs.SUPPORT_SMB2 = False
1414 info = getConnectionInfo()
15 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
15 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1616 assert conn.connect(info['server_ip'], info['server_port'])
1717
1818 def setup_func_SMB2():
1919 global conn
2020 smb_structs.SUPPORT_SMB2 = True
2121 info = getConnectionInfo()
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2323 assert conn.connect(info['server_ip'], info['server_port'])
2424
2525 def teardown_func():
1919 global conn
2020 smb_structs.SUPPORT_SMB2 = False
2121 info = getConnectionInfo()
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2323 assert conn.connect(info['server_ip'], info['server_port'])
2424
2525 def setup_func_SMB2():
2626 global conn
2727 smb_structs.SUPPORT_SMB2 = True
2828 info = getConnectionInfo()
29 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
29 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
3030 assert conn.connect(info['server_ip'], info['server_port'])
3131
3232 def teardown_func():
2424 smb_structs.SUPPORT_SMB2 = False
2525
2626 info = getConnectionInfo()
27 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
27 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2828 assert conn.connect(info['server_ip'], info['server_port'])
2929
3030 def setup_func_SMB2():
3232 smb_structs.SUPPORT_SMB2 = True
3333
3434 info = getConnectionInfo()
35 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
35 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
3636 assert conn.connect(info['server_ip'], info['server_port'])
3737
3838 def teardown_func():
99 info = {
1010 'server_name': cp.get('server', 'name'),
1111 'server_ip': cp.get('server', 'ip'),
12 'server_port': cp.getint('server', 'port'),
12 'server_port': cp.getint('server', 'direct_port'),
1313 'client_name': cp.get('client', 'name'),
1414 'user': cp.get('user', 'name'),
1515 'password': cp.get('user', 'password'),
0
1 Steps to Follow to Run the Unit Tests
2 =====================================
3
4 ## Step 1: Install system dependencies ##
5
6 If you are using Ubuntu 20.04 LTS, you can install the system dependencies with the following command
7 ```
8 $> apt-get install virtualenv python-dev gcc g++ make automake autoconf
9 ```
10 For other distributions, you can use their package managers and install the system dependencies (although the package names might differ slightly).
11
12 ## Step 2: Setup python virtualenv ##
13
14 We will create a python2 virtualenv and install the python dependencies for testing in the "venv2" folder.
15
16 ```
17 $> cd <pysmb-home>/python2
18 $> virtualenv -p /usr/bin/python2 venv2
19 $> source venv2/bin/activate
20 $venv2> pip install nose pyasn1 twisted
21 ```
22
23 ## Step 3: Setup shared folder on your remote SMB server ##
24
25 Prepare a shared folder called "smbtest" on your remote SMB server (Windows or Samba).
26
27 Then, download [smbtest.zip](https://miketeo.net/files/Projects/pysmb/smbtest.zip) and unzip the contents of this zip file in the shared folder.
28
29 You should also configure a user on the SMB server with read-write access to the "smbtest" folder.
30
31 ## Step 4: Update connection details in connection.ini ##
32
33 In the same folder where you are viewing this readme file, there should be an ini file called "connection.ini". Edit this file's connection details to match the shared folder's access information.
34
35 ## Step 5: Run the unit tests in the python2 folder ##
36
37 Before running the tests, the venv2 virtualenv must be activated.
38 ```
39 $> cd <pysmb-home>/python2
40 $> source venv2/bin/activate
41 ```
42
43 To run all the tests:
44 ```
45 $venv2> nosetests -v tests
46 ```
47
48 To selectively run some tests:
49 ```
50 $venv2> nosetests -v tests/SMBConnectionTests
51 $venv2> nosetests -v tests/SMBConnectionTests/test_rename.py
52 $venv2> nosetests -v tests/SMBConnectionTests/test_rename.py:test_rename_english_file_SMB1
53 ```
54
55 For more information, please consult the [documentation for nose](https://nose.readthedocs.io/).
56
57
+0
-32
python2/tests/README_1st.txt less more
0
1 Steps to Follow to Run the Unit Tests
2 =====================================
3
4 1a. Install Nose Testing Framework
5 All the unit tests here are designed to be conducted with the nose testing framework.
6 You can install the latest nose testing framework by running: easy_install nose
7 For more information on nose testing, please visit http://readthedocs.org/docs/nose/en/latest/
8
9 1b. Install the Twisted framework
10 If you need to test the SMB/NetBIOS protocol implementations for Twisted framework,
11 you should install the Twisted framework from http://twistedmatrix.com/
12 or by running: easy_install Twisted
13 Without the Twisted framework, the Twisted tests will fail.
14
15 2. Prepare a Shared Folder "smbtest" on a Remote Server
16 To run the unit tests here, besides installing the nose testing framework, you will
17 also need to prepare a shared folder on a remote server.
18 pysmb has been tested against Samba 3.x, Windows XP SP3 and Windows Vista.
19 The shared folder must be named "smbtest".
20
21 3. Unzip smbtest.zip in the Shared Folder
22 In the same folder where you are viewing this readme file, there should be a zip file
23 called "smbtest.zip". Unzip the contents of this zip file in the shared folder.
24
25 4. Update Connection Details in connection.ini
26 In the same folder where you are viewing this readme file, there should be an ini file
27 called "connection.ini". Edit this file's connection details to match the shared folder's
28 access information.
29
30 5. Run the Unit Tests
31 Just run: nosetests
33 from nose.tools import with_setup
44 from smb import smb_structs
55
6 conn = None
6 conn, conn2, conn3 = None, None, None
77
88 def teardown_func():
9 global conn
10 conn.close()
9 global conn, conn2, conn3
10 if conn:
11 conn.close()
12 if conn2:
13 conn2.close()
14 if conn3:
15 conn3.close();
1116
1217 @with_setup(teardown = teardown_func)
1318 def test_NTLMv1_auth_SMB1():
1722 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], domain = info['domain'], use_ntlm_v2 = False)
1823 assert conn.connect(info['server_ip'], info['server_port'])
1924
25 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False)
26 assert not conn2.connect(info['server_ip'], info['server_port'])
27
28 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False)
29 assert not conn3.connect(info['server_ip'], info['server_port'])
30
2031 @with_setup(teardown = teardown_func)
2132 def test_NTLMv2_auth_SMB1():
2233 global conn
2435 info = getConnectionInfo()
2536 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], domain = info['domain'], use_ntlm_v2 = True)
2637 assert conn.connect(info['server_ip'], info['server_port'])
38
39 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True)
40 assert not conn2.connect(info['server_ip'], info['server_port'])
41
42 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True)
43 assert not conn3.connect(info['server_ip'], info['server_port'])
2744
2845 @with_setup(teardown = teardown_func)
2946 def test_NTLMv1_auth_SMB2():
3350 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], domain = info['domain'], use_ntlm_v2 = False)
3451 assert conn.connect(info['server_ip'], info['server_port'])
3552
53 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False)
54 assert not conn2.connect(info['server_ip'], info['server_port'])
55
56 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False)
57 assert not conn3.connect(info['server_ip'], info['server_port'])
58
3659 @with_setup(teardown = teardown_func)
3760 def test_NTLMv2_auth_SMB2():
3861 global conn
4063 info = getConnectionInfo()
4164 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], domain = info['domain'], use_ntlm_v2 = True)
4265 assert conn.connect(info['server_ip'], info['server_port'])
66
67 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True)
68 assert not conn2.connect(info['server_ip'], info['server_port'])
69
70 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True)
71 assert not conn3.connect(info['server_ip'], info['server_port'])
2929 conn.close()
3030
3131 @with_setup(setup_func_SMB1, teardown_func)
32 def test_delete_SMB1():
33 global conn
34
35 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
36 conn.createDirectory('smbtest', path)
37
38 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
39 conn.storeFile('smbtest', path+"/"+filename, StringIO("0123456789"))
40
41 results = conn.listPath('smbtest', path)
42 filenames = map(lambda r: r.filename, results)
32 def test_delete_without_subfolder_SMB1():
33 global conn
34
35 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
36 conn.createDirectory('smbtest', path)
37
38 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
39 conn.storeFile('smbtest', path+"/"+filename, StringIO("0123456789"))
40
41 for p in [ 'aaTest.Folder', 'aaTest.Folder/xyz', 'bbTest.Folder' ]:
42 conn.createDirectory('smbtest', path+"/"+p)
43 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
44 conn.storeFile('smbtest', path+"/"+p+"/"+filename, StringIO("0123456789"))
45
46 results = conn.listPath('smbtest', path)
47 filenames = map(lambda r: r.filename, results)
48 assert 'aaTest.Folder' in filenames
49 assert 'bbTest.Folder' in filenames
4350 assert 'aaTest.txt' in filenames
4451 assert 'aaBest.txt' in filenames
4552 assert 'aaTest.bin' in filenames
5057
5158 results = conn.listPath('smbtest', path)
5259 filenames = map(lambda r: r.filename, results)
60 assert 'aaTest.Folder' in filenames
61 assert 'bbTest.Folder' in filenames
5362 assert 'aaTest.txt' not in filenames
5463 assert 'aaBest.txt' not in filenames
5564 assert 'aaTest.bin' in filenames
6069
6170 results = conn.listPath('smbtest', path)
6271 filenames = map(lambda r: r.filename, results)
63 assert 'aaTest.bin' not in filenames
64 assert 'aaBest.bin' in filenames
65 assert 'random.txt' in filenames
66
67 conn.deleteFiles('smbtest', path+'/*')
68 conn.deleteDirectory('smbtest', path)
72 assert 'aaTest.Folder' in filenames
73 assert 'bbTest.Folder' in filenames
74 assert 'aaTest.bin' not in filenames
75 assert 'aaBest.bin' in filenames
76 assert 'random.txt' in filenames
77
78
79 @with_setup(setup_func_SMB1, teardown_func)
80 def test_delete_with_subfolder_SMB1():
81 global conn
82
83 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
84 conn.createDirectory('smbtest', path)
85
86 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
87 conn.storeFile('smbtest', path+"/"+filename, StringIO("0123456789"))
88
89 for p in [ 'aaTest.Folder', 'aaTest.Folder/xyz', 'bbTest.Folder' ]:
90 conn.createDirectory('smbtest', path+"/"+p)
91 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
92 conn.storeFile('smbtest', path+"/"+p+"/"+filename, StringIO("0123456789"))
93
94 results = conn.listPath('smbtest', path)
95 filenames = map(lambda r: r.filename, results)
96 assert 'aaTest.Folder' in filenames
97 assert 'bbTest.Folder' in filenames
98 assert 'aaTest.txt' in filenames
99 assert 'aaBest.txt' in filenames
100 assert 'aaTest.bin' in filenames
101 assert 'aaBest.bin' in filenames
102 assert 'random.txt' in filenames
103
104 conn.deleteFiles('smbtest', path+'/aa*.txt', delete_matching_folders=True)
105
106 results = conn.listPath('smbtest', path)
107 filenames = map(lambda r: r.filename, results)
108 assert 'aaTest.Folder' in filenames
109 assert 'bbTest.Folder' in filenames
110 assert 'aaTest.txt' not in filenames
111 assert 'aaBest.txt' not in filenames
112 assert 'aaTest.bin' in filenames
113 assert 'aaBest.bin' in filenames
114 assert 'random.txt' in filenames
115
116 conn.deleteFiles('smbtest', path+'/aaTest.*', delete_matching_folders=True)
117
118 results = conn.listPath('smbtest', path)
119 filenames = map(lambda r: r.filename, results)
120 assert 'aaTest.Folder' not in filenames
121 assert 'bbTest.Folder' in filenames
122 assert 'aaTest.bin' not in filenames
123 assert 'aaBest.bin' in filenames
124 assert 'random.txt' in filenames
125
69126
70127 @with_setup(setup_func_SMB2, teardown_func)
71 def test_delete_SMB2():
72 global conn
73
74 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
75 conn.createDirectory('smbtest', path)
76
77 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
78 conn.storeFile('smbtest', path+"/"+filename, StringIO("0123456789"))
79
80 results = conn.listPath('smbtest', path)
81 filenames = map(lambda r: r.filename, results)
128 def test_delete_without_subfolder_SMB2():
129 global conn
130
131 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
132 conn.createDirectory('smbtest', path)
133
134 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
135 conn.storeFile('smbtest', path+"/"+filename, StringIO("0123456789"))
136
137 for p in [ 'aaTest.Folder', 'aaTest.Folder/xyz', 'bbTest.Folder' ]:
138 conn.createDirectory('smbtest', path+"/"+p)
139 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
140 conn.storeFile('smbtest', path+"/"+p+"/"+filename, StringIO("0123456789"))
141
142 results = conn.listPath('smbtest', path)
143 filenames = map(lambda r: r.filename, results)
144 assert 'aaTest.Folder' in filenames
145 assert 'bbTest.Folder' in filenames
82146 assert 'aaTest.txt' in filenames
83147 assert 'aaBest.txt' in filenames
84148 assert 'aaTest.bin' in filenames
89153
90154 results = conn.listPath('smbtest', path)
91155 filenames = map(lambda r: r.filename, results)
156 assert 'aaTest.Folder' in filenames
157 assert 'bbTest.Folder' in filenames
92158 assert 'aaTest.txt' not in filenames
93159 assert 'aaBest.txt' not in filenames
94160 assert 'aaTest.bin' in filenames
99165
100166 results = conn.listPath('smbtest', path)
101167 filenames = map(lambda r: r.filename, results)
102 assert 'aaTest.bin' not in filenames
103 assert 'aaBest.bin' in filenames
104 assert 'random.txt' in filenames
168 assert 'aaTest.Folder' in filenames
169 assert 'bbTest.Folder' in filenames
170 assert 'aaTest.bin' not in filenames
171 assert 'aaBest.bin' in filenames
172 assert 'random.txt' in filenames
173
174 @with_setup(setup_func_SMB2, teardown_func)
175 def test_delete_with_subfolder_SMB2():
176 global conn
177
178 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
179 conn.createDirectory('smbtest', path)
180
181 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
182 conn.storeFile('smbtest', path+"/"+filename, StringIO("0123456789"))
183
184 for p in [ 'aaTest.Folder', 'aaTest.Folder/xyz', 'bbTest.Folder' ]:
185 conn.createDirectory('smbtest', path+"/"+p)
186 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
187 conn.storeFile('smbtest', path+"/"+p+"/"+filename, StringIO("0123456789"))
188
189 results = conn.listPath('smbtest', path)
190 filenames = map(lambda r: r.filename, results)
191 assert 'aaTest.Folder' in filenames
192 assert 'bbTest.Folder' in filenames
193 assert 'aaTest.txt' in filenames
194 assert 'aaBest.txt' in filenames
195 assert 'aaTest.bin' in filenames
196 assert 'aaBest.bin' in filenames
197 assert 'random.txt' in filenames
198
199 conn.deleteFiles('smbtest', path+'/aa*.txt', delete_matching_folders=True)
200
201 results = conn.listPath('smbtest', path)
202 filenames = map(lambda r: r.filename, results)
203 assert 'aaTest.Folder' in filenames
204 assert 'bbTest.Folder' in filenames
205 assert 'aaTest.txt' not in filenames
206 assert 'aaBest.txt' not in filenames
207 assert 'aaTest.bin' in filenames
208 assert 'aaBest.bin' in filenames
209 assert 'random.txt' in filenames
210
211 conn.deleteFiles('smbtest', path+'/aaTest.*', delete_matching_folders=True)
212
213 results = conn.listPath('smbtest', path)
214 filenames = map(lambda r: r.filename, results)
215 assert 'aaTest.Folder' not in filenames
216 assert 'bbTest.Folder' in filenames
217 assert 'aaTest.bin' not in filenames
218 assert 'aaBest.bin' in filenames
219 assert 'random.txt' in filenames
00 # -*- coding: utf-8 -*-
11
22 from smb.SMBConnection import SMBConnection
3 from smb.smb_constants import *
34 from util import getConnectionInfo
45 from nose.tools import with_setup
56 from smb import smb_structs
4445 assert ( u'Test Folder', True ) in filenames
4546 assert ( u'子文件夹', True ) in filenames
4647
48 @with_setup(setup_func_SMB1, teardown_func)
49 def test_listPathWithManyFiles_SMB1():
50 global conn
51 results = conn.listPath('smbtest', '/RFC Archive/')
52 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
53 assert len(filenames)==999
54
4755 @with_setup(setup_func_SMB2, teardown_func)
4856 def test_listPath_SMB2():
4957 global conn
6371 assert ( u'Test File.txt', False ) in filenames
6472 assert ( u'Test Folder', True ) in filenames
6573 assert ( u'子文件夹', True ) in filenames
74
75 @with_setup(setup_func_SMB2, teardown_func)
76 def test_listPathWithManyFiles_SMB2():
77 global conn
78 results = conn.listPath('smbtest', '/RFC Archive/')
79 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
80 assert len(filenames)==999
81
82 @with_setup(setup_func_SMB1, teardown_func)
83 def test_listPathFilterForDirectory_SMB1():
84 global conn
85 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_DIRECTORY)
86 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
87 assert len(filenames) > 0
88 for f, isDirectory in filenames:
89 assert isDirectory
90
91 @with_setup(setup_func_SMB2, teardown_func)
92 def test_listPathFilterForDirectory_SMB2():
93 global conn
94 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_DIRECTORY)
95 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
96 assert len(filenames) > 0
97 for f, isDirectory in filenames:
98 assert isDirectory
99
100 @with_setup(setup_func_SMB1, teardown_func)
101 def test_listPathFilterForFiles_SMB1():
102 global conn
103 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL)
104 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
105 assert len(filenames) > 0
106 for f, isDirectory in filenames:
107 assert not isDirectory
108
109 @with_setup(setup_func_SMB2, teardown_func)
110 def test_listPathFilterForFiles_SMB2():
111 global conn
112 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL)
113 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
114 assert len(filenames) > 0
115 for f, isDirectory in filenames:
116 assert not isDirectory
117
118 @with_setup(setup_func_SMB1, teardown_func)
119 def test_listPathFilterPattern_SMB1():
120 global conn
121 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = 'Test*')
122 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
123 assert len(filenames) == 2
124 assert ( u'Test File.txt', False ) in filenames
125 assert ( u'Test Folder', True ) in filenames
126 assert ( u'子文件夹', True ) not in filenames
127
128 @with_setup(setup_func_SMB2, teardown_func)
129 def test_listPathFilterPattern_SMB2():
130 global conn
131 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = 'Test*')
132 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
133 assert len(filenames) == 2
134 assert ( u'Test File.txt', False ) in filenames
135 assert ( u'Test Folder', True ) in filenames
136 assert ( u'子文件夹', True ) not in filenames
137
138 @with_setup(setup_func_SMB1, teardown_func)
139 def test_listPathFilterUnicodePattern_SMB1():
140 global conn
141 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = u'*件夹')
142 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
143 assert len(filenames) == 1
144 assert ( u'Test File.txt', False ) not in filenames
145 assert ( u'Test Folder', True ) not in filenames
146 assert ( u'子文件夹', True ) in filenames
147
148 @with_setup(setup_func_SMB2, teardown_func)
149 def test_listPathFilterUnicodePattern_SMB2():
150 global conn
151 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = u'*件夹')
152 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
153 assert len(filenames) == 1
154 assert ( u'Test File.txt', False ) not in filenames
155 assert ( u'Test Folder', True ) not in filenames
156 assert ( u'子文件夹', True ) in filenames
157
158 @with_setup(setup_func_SMB1, teardown_func)
159 def test_listPathFilterEmptyList_SMB1():
160 global conn
161 results = conn.listPath('smbtest', '/RFC Archive', pattern = '*.abc')
162 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
163
164 @with_setup(setup_func_SMB2, teardown_func)
165 def test_listPathFilterEmptyList_SMB2():
166 global conn
167 results = conn.listPath('smbtest', '/RFC Archive', pattern = '*.abc')
168 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
0 # -*- coding: utf-8 -*-
1
2 import os, tempfile
3 from StringIO import StringIO
4 from smb.SMBConnection import SMBConnection
5 from util import getConnectionInfo
6 from nose.tools import with_setup
7 from smb import smb_structs
8
9 try:
10 import hashlib
11 def MD5(): return hashlib.md5()
12 except ImportError:
13 import md5
14 def MD5(): return md5.new()
15
16 conn = None
17
18 def setup_func_SMB2():
19 global conn
20 smb_structs.SUPPORT_SMB2 = True
21 info = getConnectionInfo()
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
23 assert conn.connect(info['server_ip'], info['server_port'])
24
25 def teardown_func():
26 global conn
27 conn.close()
28
29 @with_setup(setup_func_SMB2, teardown_func)
30 def test_security_SMB2():
31 global conn
32 # TODO: Need a way to setup the environment on the remote server and perform some verification on the returned results.
33 attributes = conn.getSecurity('smbtest', '/rfc1001.txt')
0 # -*- coding: utf-8 -*-
1
2 from smb.SMBConnection import SMBConnection
3 from .util import getConnectionInfo
4
5 def test_context():
6 info = getConnectionInfo()
7 with SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) as conn:
8 assert conn.connect(info['server_ip'], info['server_port'])
9
10 assert conn.sock is None
22 name = SERVER
33 ip = 192.168.1.1
44 port = 139
5 direct_port = 445
56
67 [client]
78 name = TESTCLIENT
python2/tests/smbtest.7z less more
Binary diff not shown
0 import binascii
1
2 from smb import security_descriptors as sd
3 from smb import smb_constants as sc
4
5
6 def test_sid_string_representation():
7 sid = sd.SID(1, 5, [2, 3, 4])
8 assert str(sid) == "S-1-5-2-3-4"
9 sid = sd.SID(1, 2**32 + 3, [])
10 assert str(sid) == "S-1-0x100000003"
11 sid = sd.SID(1, 2**32, [3, 2, 1])
12 assert str(sid) == "S-1-0x100000000-3-2-1"
13
14
15 def test_sid_binary_parsing():
16 raw_sid = binascii.unhexlify("""
17 01 05 00 00 00 00 00 05 15 00 00 00 de 53 c1 2a
18 2a 4f da ca c1 79 a6 32 b1 04 00 00
19 """.translate(None, ' \n'))
20 assert str(sd.SID.from_bytes(raw_sid)) == "S-1-5-21-717312990-3403304746-849770945-1201"
21 raw_sid += "garbage"
22 assert str(sd.SID.from_bytes(raw_sid)) == "S-1-5-21-717312990-3403304746-849770945-1201"
23 sid, tail = sd.SID.from_bytes(raw_sid, return_tail=True)
24 assert str(sid) == "S-1-5-21-717312990-3403304746-849770945-1201"
25 assert tail == "garbage"
26
27
28 def test_ace_binary_parsing():
29 raw_ace = binascii.unhexlify("""
30 00 10 24 00 ff 01 1f 00 01 05 00 00 00 00 00 05
31 15 00 00 00 de 53 c1 2a 2a 4f da ca c1 79 a6 32
32 6e 04 00 00
33 """.translate(None, ' \n'))
34 ace = sd.ACE.from_bytes(raw_ace)
35 assert str(ace.sid) == "S-1-5-21-717312990-3403304746-849770945-1134"
36 assert ace.type == sd.ACE_TYPE_ACCESS_ALLOWED
37 assert ace.flags == sd.ACE_FLAG_INHERITED
38 assert ace.mask == (sc.SYNCHRONIZE | sc.WRITE_OWNER | sc.WRITE_DAC
39 | sc.READ_CONTROL | sc.DELETE | sc.FILE_READ_DATA
40 | sc.FILE_WRITE_DATA | sc.FILE_APPEND_DATA
41 | sc.FILE_READ_EA | sc.FILE_WRITE_EA | sc.FILE_EXECUTE
42 | sc.FILE_DELETE_CHILD | sc.FILE_READ_ATTRIBUTES
43 | sc.FILE_WRITE_ATTRIBUTES)
44 assert not ace.additional_data
45
46 raw_ace = binascii.unhexlify("""
47 00 13 18 00 a9 00 12 00 01 02 00 00 00 00 00 05
48 20 00 00 00 21 02 00 00
49 """.translate(None, ' \n'))
50 ace = sd.ACE.from_bytes(raw_ace)
51 assert str(ace.sid) == "S-1-5-32-545"
52 assert ace.type == sd.ACE_TYPE_ACCESS_ALLOWED
53 assert ace.flags == (sd.ACE_FLAG_INHERITED | sd.ACE_FLAG_CONTAINER_INHERIT
54 | sd.ACE_FLAG_OBJECT_INHERIT)
55 assert ace.mask == (sc.SYNCHRONIZE | sc.READ_CONTROL | sc.FILE_READ_DATA
56 | sc.FILE_READ_EA | sc.FILE_EXECUTE
57 | sc.FILE_READ_ATTRIBUTES)
58 assert not ace.additional_data
59
60 raw_ace = binascii.unhexlify("""
61 01 03 24 00 a9 00 02 00 01 05 00 00 00 00 00 05
62 15 00 00 00 de 53 c1 2a 2a 4f da ca c1 79 a6 32
63 6c 04 00 00
64 """.translate(None, ' \n'))
65 ace = sd.ACE.from_bytes(raw_ace)
66 assert str(ace.sid) == "S-1-5-21-717312990-3403304746-849770945-1132"
67 assert ace.type == sd.ACE_TYPE_ACCESS_DENIED
68 assert ace.flags == (sd.ACE_FLAG_CONTAINER_INHERIT
69 | sd.ACE_FLAG_OBJECT_INHERIT)
70 assert ace.mask == (sc.READ_CONTROL | sc.FILE_READ_DATA | sc.FILE_READ_EA
71 | sc.FILE_EXECUTE | sc.FILE_READ_ATTRIBUTES)
72 assert not ace.additional_data
73
74
75 def test_acl_binary_parsing():
76 raw_acl = binascii.unhexlify("""
77 02 00 70 00 04 00 00 00 00 10 18 00 89 00 10 00
78 01 02 00 00 00 00 00 05 20 00 00 00 21 02 00 00
79 00 10 14 00 ff 01 1f 00 01 01 00 00 00 00 00 05
80 12 00 00 00 00 10 18 00 ff 01 1f 00 01 02 00 00
81 00 00 00 05 20 00 00 00 20 02 00 00 00 10 24 00
82 ff 01 1f 00 01 05 00 00 00 00 00 05 15 00 00 00
83 de 53 c1 2a 2a 4f da ca c1 79 a6 32 b1 04 00 00
84 """.translate(None, ' \n'))
85 acl = sd.ACL.from_bytes(raw_acl)
86 assert acl.revision == 2
87 assert len(acl.aces) == 4
88
89 ace = acl.aces[0]
90 assert ace.type == sd.ACE_TYPE_ACCESS_ALLOWED
91 assert str(ace.sid) == "S-1-5-32-545"
92 assert ace.flags == sd.ACE_FLAG_INHERITED
93 assert ace.mask == (sc.SYNCHRONIZE | sc.FILE_READ_DATA | sc.FILE_READ_EA
94 | sc.FILE_READ_ATTRIBUTES)
95
96 ace = acl.aces[3]
97 assert ace.type == sd.ACE_TYPE_ACCESS_ALLOWED
98 assert str(ace.sid) == "S-1-5-21-717312990-3403304746-849770945-1201"
99 assert ace.flags == sd.ACE_FLAG_INHERITED
100 assert ace.mask == (sc.SYNCHRONIZE | sc.WRITE_OWNER | sc.WRITE_DAC
101 | sc.READ_CONTROL | sc.DELETE | sc.FILE_READ_DATA
102 | sc.FILE_WRITE_DATA | sc.FILE_APPEND_DATA
103 | sc.FILE_READ_EA | sc.FILE_WRITE_EA | sc.FILE_EXECUTE
104 | sc.FILE_DELETE_CHILD | sc.FILE_READ_ATTRIBUTES
105 | sc.FILE_WRITE_ATTRIBUTES)
106
107
108 def test_descriptor_binary_parsing():
109 raw_descriptor = binascii.unhexlify("""
110 01 00 04 84 14 00 00 00 30 00 00 00 00 00 00 00
111 4c 00 00 00 01 05 00 00 00 00 00 05 15 00 00 00
112 de 53 c1 2a 2a 4f da ca c1 79 a6 32 b1 04 00 00
113 01 05 00 00 00 00 00 05 15 00 00 00 de 53 c1 2a
114 2a 4f da ca c1 79 a6 32 01 02 00 00 02 00 70 00
115 04 00 00 00 00 10 18 00 89 00 10 00 01 02 00 00
116 00 00 00 05 20 00 00 00 21 02 00 00 00 10 14 00
117 ff 01 1f 00 01 01 00 00 00 00 00 05 12 00 00 00
118 00 10 18 00 ff 01 1f 00 01 02 00 00 00 00 00 05
119 20 00 00 00 20 02 00 00 00 10 24 00 ff 01 1f 00
120 01 05 00 00 00 00 00 05 15 00 00 00 de 53 c1 2a
121 2a 4f da ca c1 79 a6 32 b1 04 00 00
122 """.translate(None, ' \n'))
123 descriptor = sd.SecurityDescriptor.from_bytes(raw_descriptor)
124 assert descriptor.flags == (sd.SECURITY_DESCRIPTOR_SELF_RELATIVE
125 | sd.SECURITY_DESCRIPTOR_DACL_PRESENT
126 | sd.SECURITY_DESCRIPTOR_DACL_AUTO_INHERITED)
127 assert descriptor.dacl is not None
128 assert descriptor.sacl is None
129 assert str(descriptor.owner) == "S-1-5-21-717312990-3403304746-849770945-1201"
130 assert str(descriptor.group) == "S-1-5-21-717312990-3403304746-849770945-513"
131
132 acl = descriptor.dacl
133 assert acl.revision == 2
134 assert len(acl.aces) == 4
135 assert str(acl.aces[0].sid) == sd.SID_BUILTIN_USERS
136 assert str(acl.aces[1].sid) == sd.SID_LOCAL_SYSTEM
137 assert str(acl.aces[2].sid) == sd.SID_BUILTIN_ADMINISTRATORS
138 assert str(acl.aces[3].sid) == "S-1-5-21-717312990-3403304746-849770945-1201"
7676 self.onNMBSessionOK()
7777 elif packet.type == NEGATIVE_SESSION_RESPONSE:
7878 self.onNMBSessionFailed()
79 elif packet.type == SESSION_KEEPALIVE:
80 # Discard keepalive packets - [RFC1002]: 5.2.2.1
81 pass
7982 else:
8083 self.log.warning('Unrecognized NMB session type: 0x%02x', packet.type)
8184
152155 opcode = (code >> 11) & 0x0F
153156 flags = (code >> 4) & 0x7F
154157 rcode = code & 0x0F
155 numnames = data[self.HEADER_STRUCT_SIZE + 44]
156158
157 if numnames > 0:
158 ret = [ ]
159 offset = self.HEADER_STRUCT_SIZE + 45
159 try:
160 numnames = data[self.HEADER_STRUCT_SIZE + 44]
160161
161 for i in range(0, numnames):
162 mynme = data[offset:offset + 15]
163 mynme = mynme.strip()
164 ret.append(( str(mynme, 'ascii'), data[offset+15] ))
165 offset += 18
162 if numnames > 0:
163 ret = [ ]
164 offset = self.HEADER_STRUCT_SIZE + 45
166165
167 return trn_id, ret
168 else:
169 return trn_id, None
166 for i in range(0, numnames):
167 mynme = data[offset:offset + 15]
168 mynme = mynme.strip()
169 ret.append(( str(mynme, 'ascii'), data[offset+15] ))
170 offset += 18
171
172 return trn_id, ret
173 except IndexError:
174 pass
175
176 return trn_id, None
170177
171178 #
172179 # Contributed by Jason Anderson
0 Metadata-Version: 2.1
1 Name: pysmb
2 Version: 1.2.8
3 Summary: pysmb is an experimental SMB/CIFS library written in Python to support file sharing between Windows and Linux machines
4 Home-page: https://miketeo.net/projects/pysmb
5 Author: Michael Teo
6 Author-email: [email protected]
7 License: zlib/libpng
8 Keywords: windows samba cifs sharing ftp smb linux
9 Classifier: Development Status :: 5 - Production/Stable
10 Classifier: Environment :: Win32 (MS Windows)
11 Classifier: Environment :: Console
12 Classifier: License :: OSI Approved :: zlib/libpng License
13 Classifier: Operating System :: Microsoft :: Windows
14 Classifier: Operating System :: POSIX
15 Classifier: Programming Language :: Python
16 Classifier: Programming Language :: Python :: 2.4
17 Classifier: Programming Language :: Python :: 2.5
18 Classifier: Programming Language :: Python :: 2.6
19 Classifier: Programming Language :: Python :: 2.7
20 Classifier: Programming Language :: Python :: 3
21 Classifier: Topic :: Communications :: File Sharing
22 Classifier: Topic :: Software Development :: Libraries :: Python Modules
23 Classifier: Topic :: System :: Networking
24 License-File: LICENSE
25
26 pysmb is an experimental SMB/CIFS library written in Python. It implements the client-side SMB/CIFS protocol which allows your Python application to access and transfer files to/from SMB/CIFS shared folders like your Windows file sharing and Samba folders.
0 CHANGELOG
1 LICENSE
2 MANIFEST.in
3 README.txt
4 setup.py
5 docs/doctrees/environment.pickle
6 docs/doctrees/extending.doctree
7 docs/doctrees/index.doctree
8 docs/doctrees/upgrading.doctree
9 docs/doctrees/api/nmb_NBNSProtocol.doctree
10 docs/doctrees/api/nmb_NetBIOS.doctree
11 docs/doctrees/api/smb_SMBConnection.doctree
12 docs/doctrees/api/smb_SMBHandler.doctree
13 docs/doctrees/api/smb_SMBProtocolFactory.doctree
14 docs/doctrees/api/smb_SharedDevice.doctree
15 docs/doctrees/api/smb_SharedFile.doctree
16 docs/doctrees/api/smb_exceptions.doctree
17 docs/doctrees/api/smb_security_descriptors.doctree
18 docs/html/.buildinfo
19 docs/html/extending.html
20 docs/html/genindex.html
21 docs/html/index.html
22 docs/html/objects.inv
23 docs/html/py-modindex.html
24 docs/html/search.html
25 docs/html/searchindex.js
26 docs/html/upgrading.html
27 docs/html/_modules/index.html
28 docs/html/_modules/nmb/NetBIOS.html
29 docs/html/_modules/nmb/NetBIOSProtocol.html
30 docs/html/_modules/smb/SMBConnection.html
31 docs/html/_modules/smb/SMBProtocol.html
32 docs/html/_modules/smb/base.html
33 docs/html/_modules/smb/security_descriptors.html
34 docs/html/_modules/smb/smb_structs.html
35 docs/html/_sources/extending.rst.txt
36 docs/html/_sources/extending.txt
37 docs/html/_sources/index.rst.txt
38 docs/html/_sources/index.txt
39 docs/html/_sources/upgrading.rst.txt
40 docs/html/_sources/upgrading.txt
41 docs/html/_sources/api/nmb_NBNSProtocol.rst.txt
42 docs/html/_sources/api/nmb_NBNSProtocol.txt
43 docs/html/_sources/api/nmb_NetBIOS.rst.txt
44 docs/html/_sources/api/nmb_NetBIOS.txt
45 docs/html/_sources/api/smb_SMBConnection.rst.txt
46 docs/html/_sources/api/smb_SMBConnection.txt
47 docs/html/_sources/api/smb_SMBHandler.rst.txt
48 docs/html/_sources/api/smb_SMBHandler.txt
49 docs/html/_sources/api/smb_SMBProtocolFactory.rst.txt
50 docs/html/_sources/api/smb_SMBProtocolFactory.txt
51 docs/html/_sources/api/smb_SharedDevice.rst.txt
52 docs/html/_sources/api/smb_SharedDevice.txt
53 docs/html/_sources/api/smb_SharedFile.rst.txt
54 docs/html/_sources/api/smb_SharedFile.txt
55 docs/html/_sources/api/smb_exceptions.rst.txt
56 docs/html/_sources/api/smb_exceptions.txt
57 docs/html/_sources/api/smb_security_descriptors.rst.txt
58 docs/html/_sources/api/smb_security_descriptors.txt
59 docs/html/_static/_sphinx_javascript_frameworks_compat.js
60 docs/html/_static/ajax-loader.gif
61 docs/html/_static/basic.css
62 docs/html/_static/comment-bright.png
63 docs/html/_static/comment-close.png
64 docs/html/_static/comment.png
65 docs/html/_static/contents.png
66 docs/html/_static/doctools.js
67 docs/html/_static/documentation_options.js
68 docs/html/_static/down-pressed.png
69 docs/html/_static/down.png
70 docs/html/_static/file.png
71 docs/html/_static/jquery-3.5.1.js
72 docs/html/_static/jquery-3.6.0.js
73 docs/html/_static/jquery.js
74 docs/html/_static/language_data.js
75 docs/html/_static/minus.png
76 docs/html/_static/navigation.png
77 docs/html/_static/plus.png
78 docs/html/_static/pygments.css
79 docs/html/_static/searchtools.js
80 docs/html/_static/sphinxdoc.css
81 docs/html/_static/underscore-1.13.1.js
82 docs/html/_static/underscore-1.3.1.js
83 docs/html/_static/underscore.js
84 docs/html/_static/up-pressed.png
85 docs/html/_static/up.png
86 docs/html/_static/websupport.js
87 docs/html/api/nmb_NBNSProtocol.html
88 docs/html/api/nmb_NetBIOS.html
89 docs/html/api/smb_SMBConnection.html
90 docs/html/api/smb_SMBHandler.html
91 docs/html/api/smb_SMBProtocolFactory.html
92 docs/html/api/smb_SharedDevice.html
93 docs/html/api/smb_SharedFile.html
94 docs/html/api/smb_exceptions.html
95 docs/html/api/smb_security_descriptors.html
96 python2/nmb/NetBIOS.py
97 python2/nmb/NetBIOSProtocol.py
98 python2/nmb/__init__.py
99 python2/nmb/base.py
100 python2/nmb/nmb_constants.py
101 python2/nmb/nmb_structs.py
102 python2/nmb/utils.py
103 python2/smb/SMBConnection.py
104 python2/smb/SMBHandler.py
105 python2/smb/SMBProtocol.py
106 python2/smb/__init__.py
107 python2/smb/base.py
108 python2/smb/ntlm.py
109 python2/smb/security_descriptors.py
110 python2/smb/securityblob.py
111 python2/smb/smb2_constants.py
112 python2/smb/smb2_structs.py
113 python2/smb/smb_constants.py
114 python2/smb/smb_structs.py
115 python2/smb/utils/README.txt
116 python2/smb/utils/U32.py
117 python2/smb/utils/__init__.py
118 python2/smb/utils/md4.py
119 python2/smb/utils/pyDes.py
120 python2/smb/utils/rc4.py
121 python2/smb/utils/sha256.py
122 python2/tests/README.md
123 python2/tests/__init__.py
124 python2/tests/connection.ini
125 python2/tests/test_ntlm.py
126 python2/tests/test_security_descriptors.py
127 python2/tests/test_securityblob.py
128 python2/tests/DirectSMBConnectionTests/__init__.py
129 python2/tests/DirectSMBConnectionTests/test_SMBHandler.py
130 python2/tests/DirectSMBConnectionTests/test_auth.py
131 python2/tests/DirectSMBConnectionTests/test_createdeletedirectory.py
132 python2/tests/DirectSMBConnectionTests/test_echo.py
133 python2/tests/DirectSMBConnectionTests/test_listpath.py
134 python2/tests/DirectSMBConnectionTests/test_listshares.py
135 python2/tests/DirectSMBConnectionTests/test_listsnapshots.py
136 python2/tests/DirectSMBConnectionTests/test_rename.py
137 python2/tests/DirectSMBConnectionTests/test_retrievefile.py
138 python2/tests/DirectSMBConnectionTests/test_storefile.py
139 python2/tests/DirectSMBConnectionTests/util.py
140 python2/tests/DirectSMBTwistedTests/test_auth.py
141 python2/tests/DirectSMBTwistedTests/test_createdeletedirectory.py
142 python2/tests/DirectSMBTwistedTests/test_echo.py
143 python2/tests/DirectSMBTwistedTests/test_listpath.py
144 python2/tests/DirectSMBTwistedTests/test_listshares.py
145 python2/tests/DirectSMBTwistedTests/test_listsnapshots.py
146 python2/tests/DirectSMBTwistedTests/test_rename.py
147 python2/tests/DirectSMBTwistedTests/test_retrievefile.py
148 python2/tests/DirectSMBTwistedTests/test_storefile.py
149 python2/tests/DirectSMBTwistedTests/util.py
150 python2/tests/NetBIOSTests/__init__.py
151 python2/tests/NetBIOSTests/test_queryname.py
152 python2/tests/NetBIOSTwistedTests/__init__.py
153 python2/tests/NetBIOSTwistedTests/test_queryname.py
154 python2/tests/SMBConnectionTests/__init__.py
155 python2/tests/SMBConnectionTests/test_SMBHandler.py
156 python2/tests/SMBConnectionTests/test_auth.py
157 python2/tests/SMBConnectionTests/test_createdeletedirectory.py
158 python2/tests/SMBConnectionTests/test_deletepattern.py
159 python2/tests/SMBConnectionTests/test_echo.py
160 python2/tests/SMBConnectionTests/test_getattributes.py
161 python2/tests/SMBConnectionTests/test_listpath.py
162 python2/tests/SMBConnectionTests/test_listshares.py
163 python2/tests/SMBConnectionTests/test_listsnapshots.py
164 python2/tests/SMBConnectionTests/test_rename.py
165 python2/tests/SMBConnectionTests/test_retrievefile.py
166 python2/tests/SMBConnectionTests/test_security.py
167 python2/tests/SMBConnectionTests/test_storefile.py
168 python2/tests/SMBConnectionTests/test_with_context.py
169 python2/tests/SMBConnectionTests/util.py
170 python2/tests/SMBTwistedTests/__init__.py
171 python2/tests/SMBTwistedTests/test_auth.py
172 python2/tests/SMBTwistedTests/test_createdeletedirectory.py
173 python2/tests/SMBTwistedTests/test_echo.py
174 python2/tests/SMBTwistedTests/test_getattributes.py
175 python2/tests/SMBTwistedTests/test_listpath.py
176 python2/tests/SMBTwistedTests/test_listshares.py
177 python2/tests/SMBTwistedTests/test_listsnapshots.py
178 python2/tests/SMBTwistedTests/test_rename.py
179 python2/tests/SMBTwistedTests/test_retrievefile.py
180 python2/tests/SMBTwistedTests/test_storefile.py
181 python2/tests/SMBTwistedTests/util.py
182 python2/tests/SupportFiles/binary.dat
183 python3/nmb/NetBIOS.py
184 python3/nmb/NetBIOSProtocol.py
185 python3/nmb/__init__.py
186 python3/nmb/base.py
187 python3/nmb/nmb_constants.py
188 python3/nmb/nmb_structs.py
189 python3/nmb/utils.py
190 python3/pysmb.egg-info/PKG-INFO
191 python3/pysmb.egg-info/SOURCES.txt
192 python3/pysmb.egg-info/dependency_links.txt
193 python3/pysmb.egg-info/requires.txt
194 python3/pysmb.egg-info/top_level.txt
195 python3/smb/SMBConnection.py
196 python3/smb/SMBHandler.py
197 python3/smb/SMBProtocol.py
198 python3/smb/__init__.py
199 python3/smb/base.py
200 python3/smb/ntlm.py
201 python3/smb/security_descriptors.py
202 python3/smb/securityblob.py
203 python3/smb/smb2_constants.py
204 python3/smb/smb2_structs.py
205 python3/smb/smb_constants.py
206 python3/smb/smb_structs.py
207 python3/smb/strategy.py
208 python3/smb/utils/U32.py
209 python3/smb/utils/__init__.py
210 python3/smb/utils/md4.py
211 python3/smb/utils/pyDes.py
212 python3/smb/utils/rc4.py
213 python3/smb/utils/sha256.py
214 python3/tests/README.md
215 python3/tests/__init__.py
216 python3/tests/connection.ini
217 python3/tests/test_md4.py
218 python3/tests/test_ntlm.py
219 python3/tests/test_security_descriptors.py
220 python3/tests/test_securityblob.py
221 python3/tests/DirectSMBConnectionTests/__init__.py
222 python3/tests/DirectSMBConnectionTests/test_auth.py
223 python3/tests/DirectSMBConnectionTests/test_createdeletedirectory.py
224 python3/tests/DirectSMBConnectionTests/test_echo.py
225 python3/tests/DirectSMBConnectionTests/test_listpath.py
226 python3/tests/DirectSMBConnectionTests/test_listshares.py
227 python3/tests/DirectSMBConnectionTests/test_listsnapshots.py
228 python3/tests/DirectSMBConnectionTests/test_rename.py
229 python3/tests/DirectSMBConnectionTests/test_retrievefile.py
230 python3/tests/DirectSMBConnectionTests/test_storefile.py
231 python3/tests/DirectSMBConnectionTests/util.py
232 python3/tests/NetBIOSTests/__init__.py
233 python3/tests/NetBIOSTests/test_queryname.py
234 python3/tests/SMBConnectionTests/__init__.py
235 python3/tests/SMBConnectionTests/test_SMBHandler.py
236 python3/tests/SMBConnectionTests/test_auth.py
237 python3/tests/SMBConnectionTests/test_createdeletedirectory.py
238 python3/tests/SMBConnectionTests/test_deletepattern.py
239 python3/tests/SMBConnectionTests/test_echo.py
240 python3/tests/SMBConnectionTests/test_getattributes.py
241 python3/tests/SMBConnectionTests/test_listpath.py
242 python3/tests/SMBConnectionTests/test_listshares.py
243 python3/tests/SMBConnectionTests/test_listsnapshots.py
244 python3/tests/SMBConnectionTests/test_rename.py
245 python3/tests/SMBConnectionTests/test_retrievefile.py
246 python3/tests/SMBConnectionTests/test_storefile.py
247 python3/tests/SMBConnectionTests/test_with_context.py
248 python3/tests/SMBConnectionTests/util.py
249 python3/tests/SupportFiles/binary.dat
250 sphinx/Makefile
251 sphinx/make.bat
252 sphinx/requirements.txt
253 sphinx/source/conf.py
254 sphinx/source/extending.rst
255 sphinx/source/index.rst
256 sphinx/source/upgrading.rst
257 sphinx/source/api/nmb_NBNSProtocol.rst
258 sphinx/source/api/nmb_NetBIOS.rst
259 sphinx/source/api/smb_SMBConnection.rst
260 sphinx/source/api/smb_SMBHandler.rst
261 sphinx/source/api/smb_SMBProtocolFactory.rst
262 sphinx/source/api/smb_SharedDevice.rst
263 sphinx/source/api/smb_SharedFile.rst
264 sphinx/source/api/smb_exceptions.rst
265 sphinx/source/api/smb_security_descriptors.rst
2020 Create a new SMBConnection instance.
2121
2222 *username* and *password* are the user credentials required to authenticate the underlying SMB connection with the remote server.
23 *password* can be a string or a callable returning a string.
2324 File operations can only be proceeded after the connection has been authenticated successfully.
2425
2526 Note that you need to call *connect* method to actually establish the SMB connection to the remote server and perform authentication.
2829 Some newer server installations might also support Direct hosting of SMB over TCP/IP; for these servers, the default TCP port is 445.
2930
3031 :param string my_name: The local NetBIOS machine name that will identify where this connection is originating from.
31 You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\/:*?";|+``
32 You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\\/:*?";|+``
3233 :param string remote_name: The NetBIOS machine name of the remote server.
3334 On windows, you can find out the machine name by right-clicking on the "My Computer" and selecting "Properties".
3435 This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.
7172 total_sent = total_sent + sent
7273
7374 #
75 # Support for "with" context
76 #
77 def __enter__(self):
78 return self
79
80 def __exit__(self, *args):
81 self.close()
82
83 #
7484 # Misc Properties
7585 #
7686
8494 # Public Methods
8595 #
8696
87 def connect(self, ip, port = 139, sock_family = socket.AF_INET, timeout = 60):
97 def connect(self, ip, port = 139, sock_family = None, timeout = 60):
8898 """
8999 Establish the SMB connection to the remote SMB/CIFS server.
90100
91101 You must call this method before attempting any of the file operations with the remote server.
92102 This method will block until the SMB connection has attempted at least one authentication.
93103
104 :param port: Defaults to 139. If you are using direct TCP mode (is_direct_tcp=true when creating this SMBConnection instance), use 445.
105 :param sock_family: In Python 3.x, use *None* as we can infer the socket family from the provided *ip*. In Python 2.x, it must be either *socket.AF_INET* or *socket.AF_INET6*.
94106 :return: A boolean value indicating the result of the authentication atttempt: True if authentication is successful; False, if otherwise.
95107 """
96108 if self.sock:
97109 self.sock.close()
98110
99111 self.auth_result = None
100 self.sock = socket.socket(sock_family)
101 self.sock.settimeout(timeout)
102 self.sock.connect(( ip, port ))
112 if sock_family:
113 self.sock = socket.socket(sock_family)
114 self.sock.settimeout(timeout)
115 self.sock.connect(( ip, port ))
116 else:
117 self.sock = socket.create_connection(( ip, port ))
103118
104119 self.is_busy = True
105120 try:
152167 return results
153168
154169 def listPath(self, service_name, path,
155 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE,
170 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL,
156171 pattern = '*', timeout = 30):
157172 """
158173 Retrieve a directory listing of files/folders at *path*
174
175 For simplicity, pysmb defines a "normal" file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.
176 It ignores other attributes like compression, indexed, sparse, temporary and encryption.
177
178 Note that the default search parameter will query for all read-only (SMB_FILE_ATTRIBUTE_READONLY), hidden (SMB_FILE_ATTRIBUTE_HIDDEN),
179 system (SMB_FILE_ATTRIBUTE_SYSTEM), archive (SMB_FILE_ATTRIBUTE_ARCHIVE), normal (SMB_FILE_ATTRIBUTE_INCL_NORMAL) files
180 and directories (SMB_FILE_ATTRIBUTE_DIRECTORY).
181 If you do not need to include "normal" files in the result, define your own search parameter without the SMB_FILE_ATTRIBUTE_INCL_NORMAL constant.
182 SMB_FILE_ATTRIBUTE_NORMAL should be used by itself and not be used with other bit constants.
159183
160184 :param string/unicode service_name: the name of the shared folder for the *path*
161185 :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders.
162186 :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py).
163 The default *search* value will query for all read-only, hidden, system, archive files and directories.
164187 :param string/unicode pattern: the filter to apply to the results before returning to the client.
165188 :return: A list of :doc:`smb.base.SharedFile<smb_SharedFile>` instances.
166189 """
244267 self.is_busy = True
245268 try:
246269 self._getAttributes(service_name, path, cb, eb, timeout)
270 while self.is_busy:
271 self._pollForNetBIOSPacket(timeout)
272 finally:
273 self.is_busy = False
274
275 return results[0]
276
277 def getSecurity(self, service_name, path, timeout = 30):
278 """
279 Retrieve the security descriptor of the file at *path* on the *service_name*.
280
281 :param string/unicode service_name: the name of the shared folder for the *path*
282 :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure<smb_exceptions>` will be raised.
283 :return: A :class:`smb.security_descriptors.SecurityDescriptor` instance containing the security information of the file.
284 """
285 if not self.sock:
286 raise NotConnectedError('Not connected to server')
287
288 results = [ ]
289
290 def cb(info):
291 self.is_busy = False
292 results.append(info)
293
294 def eb(failure):
295 self.is_busy = False
296 raise failure
297
298 self.is_busy = True
299 try:
300 self._getSecurity(service_name, path, cb, eb, timeout)
247301 while self.is_busy:
248302 self._pollForNetBIOSPacket(timeout)
249303 finally:
349403
350404 return results[0]
351405
352 def deleteFiles(self, service_name, path_file_pattern, timeout = 30):
406 def deleteFiles(self, service_name, path_file_pattern, delete_matching_folders = False, timeout = 30):
353407 """
354408 Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.
409
410 If delete_matching_folders is True, immediate sub-folders that match the path_file_pattern will be deleted recursively.
355411
356412 :param string/unicode service_name: Contains the name of the shared folder.
357413 :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.
371427
372428 self.is_busy = True
373429 try:
374 self._deleteFiles(service_name, path_file_pattern, cb, eb, timeout = timeout)
375 while self.is_busy:
376 self._pollForNetBIOSPacket(timeout)
377 finally:
378 self.is_busy = False
379
380 def resetFileAttributes(self, service_name, path_file_pattern, timeout = 30):
430 self._deleteFiles(service_name, path_file_pattern, delete_matching_folders, cb, eb, timeout = timeout)
431 while self.is_busy:
432 self._pollForNetBIOSPacket(timeout)
433 finally:
434 self.is_busy = False
435
436 def resetFileAttributes(self, service_name, path_file_pattern, file_attributes = ATTR_NORMAL, timeout = 30):
381437 """
382438 Reset file attributes of one or more regular files or folders.
383439 It supports the use of wildcards in file names, allowing for unlocking of multiple files/folders in a single request.
384440 This function is very helpful when deleting files/folders that are read-only.
385 Note: this function is currently only implemented for SMB2! Technically, it sets the FILE_ATTRIBUTE_NORMAL flag, therefore clearing all other flags. (See https://msdn.microsoft.com/en-us/library/cc232110.aspx for further information)
386
441 By default, it sets the ATTR_NORMAL flag, therefore clearing all other flags.
442 (See https://msdn.microsoft.com/en-us/library/cc232110.aspx for further information)
443
444 Note: this function is currently only implemented for SMB2!
445
387446 :param string/unicode service_name: Contains the name of the shared folder.
388447 :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.
389448 Wildcards may be used in the filename component of the path.
390449 If your path/filename contains non-English characters, you must pass in an unicode string.
450 :param int file_attributes: The desired file attributes to set. Defaults to `ATTR_NORMAL`.
391451 :return: None
392452 """
393453 if not self.sock:
402462
403463 self.is_busy = True
404464 try:
405 self._resetFileAttributes(service_name, path_file_pattern, cb, eb, timeout = timeout)
406 while self.is_busy:
407 self._pollForNetBIOSPacket(timeout)
408 finally:
409 self.is_busy = False
410
465 self._resetFileAttributes(service_name, path_file_pattern, cb, eb, file_attributes, timeout)
466 while self.is_busy:
467 self._pollForNetBIOSPacket(timeout)
468 finally:
469 self.is_busy = False
411470
412471 def createDirectory(self, service_name, path, timeout = 30):
413472 """
495554 """
496555 Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*.
497556
498 :param string data: Data to send to the remote server.
557 :param bytes data: Data to send to the remote server. Must be a bytes object.
499558 :return: The *data* parameter
500559 """
501560 if not self.sock:
0
10 import os, sys, socket, urllib.request, urllib.error, urllib.parse, mimetypes, email, tempfile
21 from urllib.parse import (unwrap, unquote, splittype, splithost, quote,
32 splitport, splittag, splitattr, splituser, splitpasswd, splitvalue)
2524 port = int(port)
2625
2726 # username/password handling
27
2828 user, host = splituser(host)
29
2930 if user:
3031 user, passwd = splitpasswd(user)
3132 else:
3233 passwd = None
34
3335 host = unquote(host)
3436 user = user or ''
3537
4042 passwd = passwd or ''
4143 myname = MACHINE_NAME or self.generateClientMachineName()
4244
43 n = NetBIOS()
44 names = n.queryIPForName(host)
45 if names:
46 server_name = names[0]
47 else:
48 raise urllib.error.URLError('SMB error: Hostname does not reply back with its machine name')
45 server_name,host = host.split(',') if ',' in host else [None,host]
46
47 if server_name is None:
48 n = NetBIOS()
49
50 names = n.queryIPForName(host)
51 if names:
52 server_name = names[0]
53 else:
54 raise urllib.error.URLError('SMB error: Hostname does not reply back with its machine name')
4955
5056 path, attrs = splitattr(req.selector)
5157 if path.startswith('/'):
177177 return d
178178
179179 def listPath(self, service_name, path,
180 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE,
180 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL,
181181 pattern = '*', timeout = 30):
182182 """
183183 Retrieve a directory listing of files/folders at *path*
184
185 For simplicity, pysmb defines a "normal" file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.
186 It ignores other attributes like compression, indexed, sparse, temporary and encryption.
187
188 Note that the default search parameter will query for all read-only (SMB_FILE_ATTRIBUTE_READONLY), hidden (SMB_FILE_ATTRIBUTE_HIDDEN),
189 system (SMB_FILE_ATTRIBUTE_SYSTEM), archive (SMB_FILE_ATTRIBUTE_ARCHIVE), normal (SMB_FILE_ATTRIBUTE_INCL_NORMAL) files
190 and directories (SMB_FILE_ATTRIBUTE_DIRECTORY).
191 If you do not need to include "normal" files in the result, define your own search parameter without the SMB_FILE_ATTRIBUTE_INCL_NORMAL constant.
192 SMB_FILE_ATTRIBUTE_NORMAL should be used by itself and not be used with other bit constants.
184193
185194 :param string/unicode service_name: the name of the shared folder for the *path*
186195 :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders.
187196 :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py).
188 The default *search* value will query for all read-only, hidden, system, archive files and directories.
189197 :param string/unicode pattern: the filter to apply to the results before returning to the client.
190198 :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.
191199 :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of :doc:`smb.base.SharedFile<smb_SharedFile>` instances.
294302 self.instance._storeFile(service_name, path, file_obj, d.callback, d.errback, timeout = timeout)
295303 return d
296304
297 def deleteFiles(self, service_name, path_file_pattern, timeout = 30):
305 def deleteFiles(self, service_name, path_file_pattern, delete_matching_folders = False, timeout = 30):
298306 """
299307 Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.
300308
309 If delete_matching_folders is True, immediate sub-folders that match the path_file_pattern will be deleted recursively.
310
301311 :param string/unicode service_name: Contains the name of the shared folder.
302312 :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.
303313 Wildcards may be used in th filename component of the path.
309319 raise NotConnectedError('Not connected to server')
310320
311321 d = defer.Deferred()
312 self.instance._deleteFiles(service_name, path_file_pattern, d.callback, d.errback, timeout = timeout)
322 self.instance._deleteFiles(service_name, path_file_pattern, delete_matching_folders, d.callback, d.errback, timeout = timeout)
313323 return d
314324
315325 def createDirectory(self, service_name, path):
368378 """
369379 Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*.
370380
371 :param string data: Data to send to the remote server.
381 :param bytes data: Data to send to the remote server. Must be a bytes object.
372382 :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.
373383 :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *data* parameter.
374384 """
44 from .smb2_constants import *
55 from .smb_structs import *
66 from .smb2_structs import *
7 from .security_descriptors import SecurityDescriptor
78 from nmb.base import NMBSession
89 from .utils import convertFILETIMEtoEpoch
910 from . import ntlm, securityblob
11 from .strategy import DataFaultToleranceStrategy
1012
1113 try:
1214 import hashlib
5254 def __init__(self, username, password, my_name, remote_name, domain = '', use_ntlm_v2 = True, sign_options = SIGN_WHEN_REQUIRED, is_direct_tcp = False):
5355 NMBSession.__init__(self, my_name, remote_name, is_direct_tcp = is_direct_tcp)
5456 self.username = username
55 self.password = password
57 self._password = password
5658 self.domain = domain
5759 self.sign_options = sign_options
5860 self.is_direct_tcp = is_direct_tcp
5961 self.use_ntlm_v2 = use_ntlm_v2 #: Similar to LMAuthenticationPolicy and NTAuthenticationPolicy as described in [MS-CIFS] 3.2.1.1
6062 self.smb_message = SMBMessage()
6163 self.is_using_smb2 = False #: Are we communicating using SMB2 protocol? self.smb_message will be a SMB2Message instance if this flag is True
64 self.async_requests = { } #: AsyncID mapped to _PendingRequest instance
6265 self.pending_requests = { } #: MID mapped to _PendingRequest instance
6366 self.connected_trees = { } #: Share name mapped to TID
6467 self.next_rpc_call_id = 1 #: Next RPC callID value. Not used directly in SMB message. Usually encapsulated in sub-commands under SMB_COM_TRANSACTION or SMB_COM_TRANSACTION2 messages
97100 (self.use_ntlm_v2 and 'v2') or 'v1',
98101 (SUPPORT_EXTENDED_SECURITY and 'with') or 'without')
99102
103 @property
104 def password(self):
105 if callable(self._password):
106 return self._password()
107 return self._password
100108
101109 #
102110 # NMBSession Methods
166174 self._listShares = self._listShares_SMB1
167175 self._listPath = self._listPath_SMB1
168176 self._listSnapshots = self._listSnapshots_SMB1
177 self._getSecurity = self._getSecurity_SMB1
169178 self._getAttributes = self._getAttributes_SMB1
170179 self._retrieveFile = self._retrieveFile_SMB1
171180 self._retrieveFileFromOffset = self._retrieveFileFromOffset_SMB1
188197 self._listShares = self._listShares_SMB2
189198 self._listPath = self._listPath_SMB2
190199 self._listSnapshots = self._listSnapshots_SMB2
200 self._getSecurity = self._getSecurity_SMB2
191201 self._getAttributes = self._getAttributes_SMB2
192202 self._retrieveFile = self._retrieveFile_SMB2
193203 self._retrieveFileFromOffset = self._retrieveFileFromOffset_SMB2
212222 if smb_message.mid == 0:
213223 smb_message.mid = self._getNextMID_SMB2()
214224
215 if smb_message.command != SMB2_COM_NEGOTIATE and smb_message.command != SMB2_COM_ECHO:
225 if smb_message.command != SMB2_COM_NEGOTIATE:
216226 smb_message.session_id = self.session_id
217227
218228 if self.is_signing_active:
249259 if result == securityblob.RESULT_ACCEPT_COMPLETED:
250260 self.has_authenticated = True
251261 self.log.info('Authentication (on SMB2) successful!')
262
263 # [MS-SMB2]: 3.2.5.3.1
264 # If the security subsystem indicates that the session was established by an anonymous user,
265 # Session.SigningRequired MUST be set to FALSE.
266 # If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags field of the
267 # SMB2 SESSION_SETUP Response and if Session.SigningRequired is TRUE, this indicates a SESSION_SETUP
268 # failure and the connection MUST be terminated. If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags
269 # field of the SMB2 SESSION_SETUP Response and if RequireMessageSigning is FALSE, Session.SigningRequired
270 # MUST be set to FALSE.
271 if message.payload.isGuestSession or message.payload.isAnonymousSession:
272 self.is_signing_active = False
273 self.log.info('Signing disabled because session is guest/anonymous')
274
252275 self.onAuthOK()
253276 else:
254277 raise ProtocolError('SMB2_COM_SESSION_SETUP status is 0 but security blob negResult value is %d' % result, message.raw_data, message)
262285 self._handleSessionChallenge(message, ntlm_token)
263286 except ( securityblob.BadSecurityBlobError, securityblob.UnsupportedSecurityProvider ) as ex:
264287 raise ProtocolError(str(ex), message.raw_data, message)
265 elif message.status == 0xc000006d: # STATUS_LOGON_FAILURE
288 elif (message.status == 0xc000006d # STATUS_LOGON_FAILURE
289 or message.status == 0xc0000064 # STATUS_NO_SUCH_USER
290 or message.status == 0xc000006a):# STATUS_WRONG_PASSWORD
266291 self.has_authenticated = False
267292 self.log.info('Authentication (on SMB2) failed. Please check username and password.')
268293 self.onAuthFailed()
294 elif (message.status == 0xc0000193 # STATUS_ACCOUNT_EXPIRED
295 or message.status == 0xC0000071): # STATUS_PASSWORD_EXPIRED
296 self.has_authenticated = False
297 self.log.info('Authentication (on SMB2) failed. Account or password has expired.')
298 self.onAuthFailed()
299 elif message.status == 0xc0000234: # STATUS_ACCOUNT_LOCKED_OUT
300 self.has_authenticated = False
301 self.log.info('Authentication (on SMB2) failed. Account has been locked due to too many invalid logon attempts.')
302 self.onAuthFailed()
303 elif message.status == 0xc0000072: # STATUS_ACCOUNT_DISABLED
304 self.has_authenticated = False
305 self.log.info('Authentication (on SMB2) failed. Account has been disabled.')
306 self.onAuthFailed()
307 elif (message.status == 0xc000006f # STATUS_INVALID_LOGON_HOURS
308 or message.status == 0xc000015b # STATUS_LOGON_TYPE_NOT_GRANTED
309 or message.status == 0xc0000070): # STATUS_INVALID_WORKSTATION
310 self.has_authenticated = False
311 self.log.info('Authentication (on SMB2) failed. Not allowed.')
312 self.onAuthFailed()
313 elif message.status == 0xc000018c: # STATUS_TRUSTED_DOMAIN_FAILURE
314 self.has_authenticated = False
315 self.log.info('Authentication (on SMB2) failed. Domain not trusted.')
316 self.onAuthFailed()
317 elif message.status == 0xc000018d: # STATUS_TRUSTED_RELATIONSHIP_FAILURE
318 self.has_authenticated = False
319 self.log.info('Authentication (on SMB2) failed. Workstation not trusted.')
320 self.onAuthFailed()
269321 else:
270322 raise ProtocolError('Unknown status value (0x%08X) in SMB_COM_SESSION_SETUP_ANDX (with extended security)' % message.status,
271323 message.raw_data, message)
272324
273 req = self.pending_requests.pop(message.mid, None)
274 if req:
275 req.callback(message, **req.kwargs)
276 return True
325 if message.isAsync:
326 if message.status == 0x00000103: # STATUS_PENDING
327 req = self.pending_requests.pop(message.mid, None)
328 if req:
329 self.async_requests[message.async_id] = req
330 else: # All other status including SUCCESS
331 req = self.async_requests.pop(message.async_id, None)
332 if req:
333 req.callback(message, **req.kwargs)
334 return True
335 else:
336 req = self.pending_requests.pop(message.mid, None)
337 if req:
338 req.callback(message, **req.kwargs)
339 return True
277340
278341
279342 def _updateServerInfo_SMB2(self, payload):
308371 self.log.info('Performing NTLMv1 authentication (on SMB2) with server challenge "%s"', binascii.hexlify(server_challenge))
309372 nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(self.password, server_challenge, True)
310373
311 ntlm_data = ntlm.generateAuthenticateMessage(server_flags,
312 nt_challenge_response,
313 lm_challenge_response,
314 session_key,
315 self.username,
316 self.domain)
374 ntlm_data, session_signing_key = ntlm.generateAuthenticateMessage(server_flags,
375 nt_challenge_response,
376 lm_challenge_response,
377 session_key,
378 self.username,
379 self.domain,
380 self.my_name)
317381
318382 if self.log.isEnabledFor(logging.DEBUG):
319383 self.log.debug('NT challenge response is "%s" (%d bytes)', binascii.hexlify(nt_challenge_response), len(nt_challenge_response))
333397
334398 if self.is_signing_active:
335399 self.log.info("SMB signing activated. All SMB messages will be signed.")
336 self.signing_session_key = (session_key + b'\0'*16)[:16]
400 self.signing_session_key = session_signing_key
401 if self.log.isEnabledFor(logging.DEBUG):
402 self.log.info("SMB signing key is %s", binascii.hexlify(self.signing_session_key))
403
337404 if self.capabilities & CAP_EXTENDED_SECURITY:
338405 self.signing_challenge_response = None
339406 else:
362429
363430 m.tid = tid
364431 self._sendSMBMessage(m)
365 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectSrvSvcCB, errback)
432 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectSrvSvcCB, errback, tid = tid)
366433 messages_history.append(m)
367434
368435 def connectSrvSvcCB(create_message, **kwargs):
384451 01 00 00 00
385452 """.replace(b' ', b'').replace(b'\n', b''))
386453 m = SMB2Message(SMB2WriteRequest(create_message.payload.fid, data_bytes, 0))
387 m.tid = create_message.tid
454 m.tid = kwargs['tid']
388455 self._sendSMBMessage(m)
389 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, rpcBindCB, errback, fid = create_message.payload.fid)
456 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, rpcBindCB, errback, tid = kwargs['tid'], fid = create_message.payload.fid)
390457 messages_history.append(m)
391458 else:
392459 errback(OperationFailure('Failed to list shares: Unable to locate Server Service RPC endpoint', messages_history))
395462 messages_history.append(trans_message)
396463 if trans_message.status == 0:
397464 m = SMB2Message(SMB2ReadRequest(kwargs['fid'], read_len = 1024, read_offset = 0))
398 m.tid = trans_message.tid
465 m.tid = kwargs['tid']
399466 self._sendSMBMessage(m)
400 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, rpcReadCB, errback, fid = kwargs['fid'])
467 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, rpcReadCB, errback, tid = kwargs['tid'], fid = kwargs['fid'])
401468 messages_history.append(m)
402469 else:
403 closeFid(trans_message.tid, kwargs['fid'], error = 'Failed to list shares: Unable to read from Server Service RPC endpoint')
470 closeFid(kwargs['tid'], kwargs['fid'], error = 'Failed to list shares: Unable to read from Server Service RPC endpoint')
404471
405472 def rpcReadCB(read_message, **kwargs):
406473 messages_history.append(read_message)
428495 00 00 00 00 ff ff ff ff 08 00 02 00 00 00 00 00
429496 """.replace(b' ', b'').replace(b'\n', b''))
430497 m = SMB2Message(SMB2IoctlRequest(kwargs['fid'], 0x0011C017, flags = 0x01, max_out_size = 8196, in_data = data_bytes))
431 m.tid = read_message.tid
498 m.tid = kwargs['tid']
432499 self._sendSMBMessage(m)
433 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, listShareResultsCB, errback, fid = kwargs['fid'])
500 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, listShareResultsCB, errback, tid = kwargs['tid'], fid = kwargs['fid'])
434501 messages_history.append(m)
435502 else:
436 closeFid(read_message.tid, kwargs['fid'], error = 'Failed to list shares: Unable to bind to Server Service RPC endpoint')
503 closeFid(kwargs['tid'], kwargs['fid'], error = 'Failed to list shares: Unable to bind to Server Service RPC endpoint')
437504
438505 def listShareResultsCB(result_message, **kwargs):
439506 messages_history.append(result_message)
442509 data_bytes = result_message.payload.out_data
443510
444511 if data_bytes[3] & 0x02 == 0:
445 sendReadRequest(result_message.tid, kwargs['fid'], data_bytes)
446 else:
447 decodeResults(result_message.tid, kwargs['fid'], data_bytes)
448 elif result_message.status == 0x0103: # STATUS_PENDING
449 self.pending_requests[result_message.mid] = _PendingRequest(result_message.mid, expiry_time, listShareResultsCB, errback, fid = kwargs['fid'])
450 else:
451 closeFid(result_message.tid, kwargs['fid'])
512 sendReadRequest(kwargs['tid'], kwargs['fid'], data_bytes)
513 else:
514 decodeResults(kwargs['tid'], kwargs['fid'], data_bytes)
515 else:
516 closeFid(kwargs['tid'], kwargs['fid'])
452517 errback(OperationFailure('Failed to list shares: Unable to retrieve shared device list', messages_history))
453518
454519 def decodeResults(tid, fid, data_bytes):
462527 for i in range(0, shares_count):
463528 max_length, _, length = struct.unpack('<III', data_bytes[offset:offset+12])
464529 offset += 12
465 results[i].name = data_bytes[offset:offset+length*2-2].decode('UTF-16LE')
530 results[i].name = DataFaultToleranceStrategy.data_bytes_decode(data_bytes[offset:offset+length*2-2])
466531
467532 if length % 2 != 0:
468533 offset += (length * 2 + 2)
471536
472537 max_length, _, length = struct.unpack('<III', data_bytes[offset:offset+12])
473538 offset += 12
474 results[i].comments = data_bytes[offset:offset+length*2-2].decode('UTF-16LE')
539 results[i].comments = DataFaultToleranceStrategy.data_bytes_decode(data_bytes[offset:offset+length*2-2])
475540
476541 if length % 2 != 0:
477542 offset += (length * 2 + 2)
487552 m.tid = tid
488553 self._sendSMBMessage(m)
489554 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, readCB, errback,
490 fid = fid, data_bytes = data_bytes)
555 tid = tid, fid = fid, data_bytes = data_bytes)
491556
492557 def readCB(read_message, **kwargs):
493558 messages_history.append(read_message)
494559 if read_message.status == 0:
495 data_len = read_message.payload.data_length
496560 data_bytes = read_message.payload.data
497561
498562 if data_bytes[3] & 0x02 == 0:
499 sendReadRequest(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:data_len-24])
500 else:
501 decodeResults(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:data_len-24])
502 else:
503 closeFid(read_message.tid, kwargs['fid'])
563 sendReadRequest(kwargs['tid'], kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:])
564 else:
565 decodeResults(kwargs['tid'], kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:])
566 else:
567 closeFid(kwargs['tid'], kwargs['fid'])
504568 errback(OperationFailure('Failed to list shares: Unable to retrieve shared device list', messages_history))
505569
506570 def closeFid(tid, fid, results = None, error = None):
556620 """.replace(b' ', b'').replace(b'\n', b''))
557621 m = SMB2Message(SMB2CreateRequest(path,
558622 file_attributes = 0,
559 access_mask = FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
623 access_mask = FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
560624 share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
561625 oplock = SMB2_OPLOCK_LEVEL_NONE,
562626 impersonation = SEC_IMPERSONATE,
565629 create_context_data = create_context_data))
566630 m.tid = tid
567631 self._sendSMBMessage(m)
568 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback)
632 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback, tid = tid)
569633 messages_history.append(m)
570634
571635 def createCB(create_message, **kwargs):
572636 messages_history.append(create_message)
573637 if create_message.status == 0:
574 sendQuery(create_message.tid, create_message.payload.fid, b'')
638 sendQuery(kwargs['tid'], create_message.payload.fid, b'')
639 elif create_message.status == 0xC0000034: # [MS-ERREF]: STATUS_OBJECT_NAME_INVALID
640 errback(OperationFailure('Failed to list %s on %s: Path not found' % ( path, service_name ), messages_history))
575641 else:
576642 errback(OperationFailure('Failed to list %s on %s: Unable to open directory' % ( path, service_name ), messages_history))
577643
578644 def sendQuery(tid, fid, data_buf):
579645 m = SMB2Message(SMB2QueryDirectoryRequest(fid, pattern,
580 info_class = 0x03, # FileBothDirectoryInformation
646 info_class = 0x25, # FileIdBothDirectoryInformation
581647 flags = 0,
582648 output_buf_len = self.max_transact_size))
583649 m.tid = tid
584650 self._sendSMBMessage(m)
585 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, queryCB, errback, fid = fid, data_buf = data_buf)
651 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, queryCB, errback, tid = tid, fid = fid, data_buf = data_buf)
586652 messages_history.append(m)
587653
588654 def queryCB(query_message, **kwargs):
589655 messages_history.append(query_message)
590656 if query_message.status == 0:
591657 data_buf = decodeQueryStruct(kwargs['data_buf'] + query_message.payload.data)
592 sendQuery(query_message.tid, kwargs['fid'], data_buf)
658 sendQuery(kwargs['tid'], kwargs['fid'], data_buf)
659 elif query_message.status == 0xC000000F: # [MS-ERREF]: STATUS_NO_SUCH_FILE
660 # If there are no matching files, we just treat as success instead of failing
661 closeFid(kwargs['tid'], kwargs['fid'], results = results)
593662 elif query_message.status == 0x80000006: # STATUS_NO_MORE_FILES
594 closeFid(query_message.tid, kwargs['fid'], results = results)
595 else:
596 closeFid(query_message.tid, kwargs['fid'], error = query_message.status)
663 closeFid(kwargs['tid'], kwargs['fid'], results = results)
664 else:
665 closeFid(kwargs['tid'], kwargs['fid'], error = query_message.status)
597666
598667 def decodeQueryStruct(data_bytes):
599 # SMB_FIND_FILE_BOTH_DIRECTORY_INFO structure. See [MS-CIFS]: 2.2.8.1.7 and [MS-SMB]: 2.2.8.1.1
600 info_format = '<IIQQQQQQIIIBB24s'
668 # FileIdBothDirectoryInformation structure. See [MS-SMB]: 2.2.8.1.3 and [MS-FSCC]: 2.4.17
669 info_format = '<IIQQQQQQIIIBB24sHQ'
601670 info_size = struct.calcsize(info_format)
602671
603672 data_length = len(data_bytes)
609678 next_offset, _, \
610679 create_time, last_access_time, last_write_time, last_attr_change_time, \
611680 file_size, alloc_size, file_attributes, filename_length, ea_size, \
612 short_name_length, _, short_name = struct.unpack(info_format, data_bytes[offset:offset+info_size])
681 short_name_length, _, short_name, _, file_id = struct.unpack(info_format, data_bytes[offset:offset+info_size])
613682
614683 offset2 = offset + info_size
615684 if offset2 + filename_length > data_length:
616685 return data_bytes[offset:]
617686
618 filename = data_bytes[offset2:offset2+filename_length].decode('UTF-16LE')
619 short_name = short_name.decode('UTF-16LE')
620 results.append(SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time),
621 convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
622 file_size, alloc_size, file_attributes, short_name, filename))
687 filename = DataFaultToleranceStrategy.data_bytes_decode(data_bytes[offset2:offset2+filename_length])
688 short_name = DataFaultToleranceStrategy.data_bytes_decode(short_name[:short_name_length])
689
690 accept_result = False
691 if (file_attributes & 0xff) in ( 0x00, ATTR_NORMAL ): # Only the first 8-bits are compared. We ignore other bits like temp, compressed, encryption, sparse, indexed, etc
692 accept_result = (search == SMB_FILE_ATTRIBUTE_NORMAL) or (search & SMB_FILE_ATTRIBUTE_INCL_NORMAL)
693 else:
694 accept_result = (file_attributes & search) > 0
695 if accept_result:
696 results.append(SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time),
697 convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
698 file_size, alloc_size, file_attributes, short_name, filename, file_id))
623699
624700 if next_offset:
625701 offset += next_offset
638714 if kwargs['results'] is not None:
639715 callback(kwargs['results'])
640716 elif kwargs['error'] is not None:
641 errback(OperationFailure('Failed to list %s on %s: Query failed with errorcode 0x%08x' % ( path, service_name, kwargs['error'] ), messages_history))
717 if kwargs['error'] == 0xC000000F: # [MS-ERREF]: STATUS_NO_SUCH_FILE
718 # Remote server returns STATUS_NO_SUCH_FILE error so we assume that the search returns no matching files
719 callback([ ])
720 else:
721 errback(OperationFailure('Failed to list %s on %s: Query failed with errorcode 0x%08x' % ( path, service_name, kwargs['error'] ), messages_history))
642722
643723 if service_name not in self.connected_trees:
644724 def connectCB(connect_message, **kwargs):
688768 create_context_data = create_context_data))
689769 m.tid = tid
690770 self._sendSMBMessage(m)
691 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback)
771 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback, tid = tid)
692772 messages_history.append(m)
693773
694774 def createCB(create_message, **kwargs):
695775 messages_history.append(create_message)
696776 if create_message.status == 0:
697777 p = create_message.payload
778 filename = self._extractLastPathComponent(path)
698779 info = SharedFile(p.create_time, p.lastaccess_time, p.lastwrite_time, p.change_time,
699780 p.file_size, p.allocation_size, p.file_attributes,
700 path, path)
701 closeFid(create_message.tid, p.fid, info = info)
781 filename, filename)
782 closeFid(kwargs['tid'], p.fid, info = info)
702783 else:
703784 errback(OperationFailure('Failed to get attributes for %s on %s: Unable to open remote file object' % ( path, service_name ), messages_history))
704785
723804 sendCreate(connect_message.tid)
724805 else:
725806 errback(OperationFailure('Failed to get attributes for %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
807
808 m = SMB2Message(SMB2TreeConnectRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name )))
809 self._sendSMBMessage(m)
810 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = service_name)
811 messages_history.append(m)
812 else:
813 sendCreate(self.connected_trees[service_name])
814
815 def _getSecurity_SMB2(self, service_name, path, callback, errback, timeout = 30):
816 if not self.has_authenticated:
817 raise NotReadyError('SMB connection not authenticated')
818
819 expiry_time = time.time() + timeout
820 path = path.replace('/', '\\')
821 if path.startswith('\\'):
822 path = path[1:]
823 if path.endswith('\\'):
824 path = path[:-1]
825 messages_history = [ ]
826 results = [ ]
827
828 def sendCreate(tid):
829 m = SMB2Message(SMB2CreateRequest(path,
830 file_attributes = 0,
831 access_mask = FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | READ_CONTROL | SYNCHRONIZE,
832 share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
833 oplock = SMB2_OPLOCK_LEVEL_NONE,
834 impersonation = SEC_IMPERSONATE,
835 create_options = 0,
836 create_disp = FILE_OPEN))
837 m.tid = tid
838 self._sendSMBMessage(m)
839 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, createCB, errback, tid = tid)
840 messages_history.append(m)
841
842 def createCB(create_message, **kwargs):
843 messages_history.append(create_message)
844 if create_message.status == 0:
845 m = SMB2Message(SMB2QueryInfoRequest(create_message.payload.fid,
846 flags = 0,
847 additional_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
848 info_type = SMB2_INFO_SECURITY,
849 file_info_class = 0, # [MS-SMB2] 2.2.37, 3.2.4.12
850 input_buf = '',
851 output_buf_len = self.max_transact_size))
852 m.tid = kwargs['tid']
853 self._sendSMBMessage(m)
854 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, queryCB, errback, tid = kwargs['tid'], fid = create_message.payload.fid)
855 messages_history.append(m)
856 else:
857 errback(OperationFailure('Failed to get the security descriptor of %s on %s: Unable to open file or directory' % ( path, service_name ), messages_history))
858
859 def queryCB(query_message, **kwargs):
860 messages_history.append(query_message)
861 if query_message.status == 0:
862 security = SecurityDescriptor.from_bytes(query_message.payload.data)
863 closeFid(kwargs['tid'], kwargs['fid'], result = security)
864 else:
865 closeFid(kwargs['tid'], kwargs['fid'], error = query_message.status)
866
867 def closeFid(tid, fid, result = None, error = None):
868 m = SMB2Message(SMB2CloseRequest(fid))
869 m.tid = tid
870 self._sendSMBMessage(m)
871 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, closeCB, errback, result = result, error = error)
872 messages_history.append(m)
873
874 def closeCB(close_message, **kwargs):
875 if kwargs['result'] is not None:
876 callback(kwargs['result'])
877 elif kwargs['error'] is not None:
878 errback(OperationFailure('Failed to get the security descriptor of %s on %s: Query failed with errorcode 0x%08x' % ( path, service_name, kwargs['error'] ), messages_history))
879
880 if service_name not in self.connected_trees:
881 def connectCB(connect_message, **kwargs):
882 messages_history.append(connect_message)
883 if connect_message.status == 0:
884 self.connected_trees[service_name] = connect_message.tid
885 sendCreate(connect_message.tid)
886 else:
887 errback(OperationFailure('Failed to get the security descriptor of %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
726888
727889 m = SMB2Message(SMB2TreeConnectRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name )))
728890 self._sendSMBMessage(m)
759921 m = SMB2Message(SMB2CreateRequest(path,
760922 file_attributes = 0,
761923 access_mask = FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | READ_CONTROL | SYNCHRONIZE,
762 share_access = FILE_SHARE_READ,
924 share_access = FILE_SHARE_READ | FILE_SHARE_WRITE,
763925 oplock = SMB2_OPLOCK_LEVEL_NONE,
764926 impersonation = SEC_IMPERSONATE,
765927 create_options = FILE_SEQUENTIAL_ONLY | FILE_NON_DIRECTORY_FILE,
777939 flags = 0,
778940 additional_info = 0,
779941 info_type = SMB2_INFO_FILE,
780 file_info_class = 0x16, # FileStreamInformation [MS-FSCC] 2.4
942 file_info_class = 0x05, # FileStandardInformation [MS-FSCC] 2.4
781943 input_buf = b'',
782944 output_buf_len = 4096))
783 m.tid = create_message.tid
945 m.tid = kwargs['tid']
784946 self._sendSMBMessage(m)
785947 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, infoCB, errback,
786 fid = create_message.payload.fid, file_attributes = create_message.payload.file_attributes)
948 tid = kwargs['tid'],
949 fid = create_message.payload.fid,
950 file_attributes = create_message.payload.file_attributes)
787951 messages_history.append(m)
788952 else:
789 errback(OperationFailure('Failed to list %s on %s: Unable to open file' % ( path, service_name ), messages_history))
953 errback(OperationFailure('Failed to retrieve %s on %s: Unable to open file' % ( path, service_name ), messages_history))
790954
791955 def infoCB(info_message, **kwargs):
792956 messages_history.append(info_message)
801965 remaining_len = file_len
802966 if starting_offset + remaining_len > file_len:
803967 remaining_len = file_len - starting_offset
804 sendRead(info_message.tid, kwargs['fid'], starting_offset, remaining_len, 0, kwargs['file_attributes'])
805 else:
806 errback(OperationFailure('Failed to list %s on %s: Unable to retrieve information on file' % ( path, service_name ), messages_history))
968 sendRead(kwargs['tid'], kwargs['fid'], starting_offset, remaining_len, 0, kwargs['file_attributes'])
969 else:
970 errback(OperationFailure('Failed to retrieve %s on %s: Unable to retrieve information on file' % ( path, service_name ), messages_history))
807971
808972 def sendRead(tid, fid, offset, remaining_len, read_len, file_attributes):
809973 read_count = min(self.max_read_size, remaining_len)
811975 m.tid = tid
812976 self._sendSMBMessage(m)
813977 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, readCB, errback,
814 fid = fid, offset = offset,
978 tid = tid, fid = fid, offset = offset,
815979 remaining_len = remaining_len,
816980 read_len = read_len,
817981 file_attributes = file_attributes)
825989 remaining_len = kwargs['remaining_len'] - data_len
826990
827991 if remaining_len > 0:
828 sendRead(read_message.tid, kwargs['fid'], kwargs['offset'] + data_len, remaining_len, kwargs['read_len'] + data_len, kwargs['file_attributes'])
829 else:
830 closeFid(read_message.tid, kwargs['fid'], ret = ( file_obj, kwargs['file_attributes'], kwargs['read_len'] + data_len ))
992 sendRead(kwargs['tid'], kwargs['fid'], kwargs['offset'] + data_len, remaining_len, kwargs['read_len'] + data_len, kwargs['file_attributes'])
993 else:
994 closeFid(kwargs['tid'], kwargs['fid'], ret = ( file_obj, kwargs['file_attributes'], kwargs['read_len'] + data_len ))
831995 else:
832996 messages_history.append(read_message)
833 closeFid(read_message.tid, kwargs['fid'], error = read_message.status)
997 closeFid(kwargs['tid'], kwargs['fid'], error = read_message.status)
834998
835999 def closeFid(tid, fid, ret = None, error = None):
8361000 m = SMB2Message(SMB2CloseRequest(fid))
9061070 messages_history.append(create_message)
9071071 if create_message.status == 0:
9081072 sendWrite(create_message.tid, create_message.payload.fid, starting_offset)
909 elif create_message.status == 0x0103: # STATUS_PENDING
910 self.pending_requests[create_message.mid] = _PendingRequest(create_message.mid, expiry_time,
911 createCB, errback,
912 tid=kwargs['tid'])
9131073 else:
9141074 errback(OperationFailure('Failed to store %s on %s: Unable to open file' % ( path, service_name ), messages_history))
9151075
9211081 m = SMB2Message(SMB2WriteRequest(fid, data, offset))
9221082 m.tid = tid
9231083 self._sendSMBMessage(m)
924 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, writeCB, errback, fid = fid, offset = offset+data_len)
1084 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, writeCB, errback, tid = tid, fid = fid, offset = offset+data_len)
9251085 else:
9261086 closeFid(tid, fid, offset = offset)
9271087
9281088 def writeCB(write_message, **kwargs):
9291089 # To avoid crazy memory usage when saving large files, we do not save every write_message in messages_history.
9301090 if write_message.status == 0:
931 sendWrite(write_message.tid, kwargs['fid'], kwargs['offset'])
1091 sendWrite(kwargs['tid'], kwargs['fid'], kwargs['offset'])
9321092 else:
9331093 messages_history.append(write_message)
934 closeFid(write_message.tid, kwargs['fid'])
1094 closeFid(kwargs['tid'], kwargs['fid'])
9351095 errback(OperationFailure('Failed to store %s on %s: Write failed' % ( path, service_name ), messages_history))
9361096
9371097 def closeFid(tid, fid, error = None, offset = None):
9641124 sendCreate(self.connected_trees[service_name])
9651125
9661126
967 def _deleteFiles_SMB2(self, service_name, path_file_pattern, callback, errback, timeout = 30):
1127 def _deleteFiles_SMB2(self, service_name, path_file_pattern, delete_matching_folders, callback, errback, timeout = 30):
1128 if not self.has_authenticated:
1129 raise NotReadyError('SMB connection not authenticated')
1130
1131 expiry_time = time.time() + timeout
1132 pattern = None
1133 path = path_file_pattern.replace('/', '\\')
1134 if path.startswith('\\'):
1135 path = path[1:]
1136 if path.endswith('\\'):
1137 path = path[:-1]
1138 else:
1139 path_components = path.split('\\')
1140 if path_components[-1].find('*') > -1 or path_components[-1].find('?') > -1:
1141 path = '\\'.join(path_components[:-1])
1142 pattern = path_components[-1]
1143 messages_history, files_queue = [ ], [ ]
1144
1145 if pattern is None:
1146 path_components = path.split('\\')
1147 if len(path_components) > 1:
1148 files_queue.append(( '\\'.join(path_components[:-1]), path_components[-1] ))
1149 else:
1150 files_queue.append(( '', path ))
1151
1152 def deleteCB(path):
1153 if files_queue:
1154 p, filename = files_queue.pop(0)
1155 if filename:
1156 if p:
1157 filename = p + '\\' + filename
1158 self._deleteFiles_SMB2__del(service_name, self.connected_trees[service_name], filename, deleteCB, errback, timeout)
1159 else:
1160 self._deleteDirectory_SMB2(service_name, p, deleteCB, errback, timeout)
1161 else:
1162 callback(path_file_pattern)
1163
1164 def listCB(files_list):
1165 files_queue.extend(files_list)
1166 deleteCB(None)
1167
1168 if service_name not in self.connected_trees:
1169 def connectCB(connect_message, **kwargs):
1170 messages_history.append(connect_message)
1171 if connect_message.status == 0:
1172 self.connected_trees[service_name] = connect_message.tid
1173 if files_queue:
1174 deleteCB(None)
1175 else:
1176 self._deleteFiles_SMB2__list(service_name, path, pattern, delete_matching_folders, listCB, errback, timeout)
1177 else:
1178 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
1179
1180 m = SMB2Message(SMB2TreeConnectRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name )))
1181 self._sendSMBMessage(m)
1182 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = service_name)
1183 messages_history.append(m)
1184 else:
1185 if files_queue:
1186 deleteCB(None)
1187 else:
1188 self._deleteFiles_SMB2__list(service_name, path, pattern, delete_matching_folders, listCB, errback, timeout)
1189
1190 def _deleteFiles_SMB2__list(self, service_name, path, pattern, delete_matching_folders, callback, errback, timeout = 30):
1191 folder_queue = [ ]
1192 files_list = [ ]
1193 current_path = [ path ]
1194 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL
1195
1196 def listCB(results):
1197 files = [ ]
1198 for f in filter(lambda x: x.filename not in [ '.', '..' ], results):
1199 if f.isDirectory:
1200 if delete_matching_folders:
1201 folder_queue.append(current_path[0]+'\\'+f.filename)
1202 else:
1203 files.append(( current_path[0], f.filename ))
1204 if current_path[0]!=path and delete_matching_folders:
1205 files.append(( current_path[0], None ))
1206
1207 if files:
1208 files_list[0:0] = files
1209
1210 if folder_queue:
1211 p = folder_queue.pop()
1212 current_path[0] = p
1213 self._listPath_SMB2(service_name, current_path[0], listCB, errback, search = search, pattern = '*', timeout = 30)
1214 else:
1215 callback(files_list)
1216
1217 self._listPath_SMB2(service_name, path, listCB, errback, search = search, pattern = pattern, timeout = timeout)
1218
1219 def _deleteFiles_SMB2__del(self, service_name, tid, path, callback, errback, timeout = 30):
1220 messages_history = [ ]
1221
1222 def sendCreate(tid):
1223 create_context_data = binascii.unhexlify(b"""
1224 28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00
1225 44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00
1226 00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00
1227 00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00
1228 00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00
1229 51 46 69 64 00 00 00 00
1230 """.replace(b' ', b'').replace(b'\n', b''))
1231 m = SMB2Message(SMB2CreateRequest(path,
1232 file_attributes = 0,
1233 access_mask = DELETE | FILE_READ_ATTRIBUTES,
1234 share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1235 oplock = SMB2_OPLOCK_LEVEL_NONE,
1236 impersonation = SEC_IMPERSONATE,
1237 create_options = FILE_NON_DIRECTORY_FILE,
1238 create_disp = FILE_OPEN,
1239 create_context_data = create_context_data))
1240 m.tid = tid
1241 self._sendSMBMessage(m)
1242 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback, tid = tid)
1243 messages_history.append(m)
1244
1245 def createCB(open_message, **kwargs):
1246 open_message.tid = kwargs['tid']
1247 messages_history.append(open_message)
1248 if open_message.status == 0:
1249 sendDelete(open_message.tid, open_message.payload.fid)
1250 elif open_message.status == 0xc0000034: # STATUS_OBJECT_NAME_NOT_FOUND
1251 callback(path)
1252 elif open_message.status == 0xC00000BA: # [MS-ERREF]: STATUS_FILE_IS_A_DIRECTORY
1253 errback(OperationFailure('Failed to delete %s on %s: Cannot delete a folder. Please use deleteDirectory() method or append "/*" to your path if you wish to delete all files in the folder.' % ( path, service_name ), messages_history))
1254 else:
1255 errback(OperationFailure('Failed to delete %s on %s: Unable to open file' % ( path, service_name ), messages_history))
1256
1257 def sendDelete(tid, fid):
1258 m = SMB2Message(SMB2SetInfoRequest(fid,
1259 additional_info = 0,
1260 info_type = SMB2_INFO_FILE,
1261 file_info_class = 0x0d, # SMB2_FILE_DISPOSITION_INFO
1262 data = b'\x01'))
1263 # [MS-SMB2]: 2.2.39, [MS-FSCC]: 2.4.11
1264 m.tid = tid
1265 self._sendSMBMessage(m)
1266 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback, tid = tid, fid = fid)
1267 messages_history.append(m)
1268
1269 def deleteCB(delete_message, **kwargs):
1270 messages_history.append(delete_message)
1271 if delete_message.status == 0:
1272 closeFid(kwargs['tid'], kwargs['fid'], status = 0)
1273 else:
1274 closeFid(kwargs['tid'], kwargs['fid'], status = delete_message.status)
1275
1276 def closeFid(tid, fid, status = None):
1277 m = SMB2Message(SMB2CloseRequest(fid))
1278 m.tid = tid
1279 self._sendSMBMessage(m)
1280 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, closeCB, errback, status = status)
1281 messages_history.append(m)
1282
1283 def closeCB(close_message, **kwargs):
1284 if kwargs['status'] == 0:
1285 callback(path)
1286 else:
1287 errback(OperationFailure('Failed to delete %s on %s: Delete failed' % ( path, service_name ), messages_history))
1288
1289 sendCreate(tid)
1290
1291 def _resetFileAttributes_SMB2(self, service_name, path_file_pattern, callback, errback, file_attributes = ATTR_NORMAL, timeout = 30):
9681292 if not self.has_authenticated:
9691293 raise NotReadyError('SMB connection not authenticated')
9701294
9851309 00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00
9861310 51 46 69 64 00 00 00 00
9871311 """.replace(b' ', b'').replace(b'\n', b''))
988 m = SMB2Message(SMB2CreateRequest(path,
989 file_attributes = 0,
990 access_mask = DELETE | FILE_READ_ATTRIBUTES,
991 share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
992 oplock = SMB2_OPLOCK_LEVEL_NONE,
993 impersonation = SEC_IMPERSONATE,
994 create_options = FILE_NON_DIRECTORY_FILE,
995 create_disp = FILE_OPEN,
996 create_context_data = create_context_data))
997 m.tid = tid
998 self._sendSMBMessage(m)
999 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback, tid = tid)
1000 messages_history.append(m)
1001
1002 def createCB(open_message, **kwargs):
1003 open_message.tid = kwargs['tid']
1004 messages_history.append(open_message)
1005 if open_message.status == 0:
1006 sendDelete(open_message.tid, open_message.payload.fid)
1007 elif open_message.status == 0x0103: # STATUS_PENDING
1008 self.pending_requests[open_message.mid] = _PendingRequest(open_message.mid, expiry_time,
1009 createCB, errback,
1010 tid=kwargs['tid'])
1011 else:
1012 errback(OperationFailure('Failed to delete %s on %s: Unable to open file' % ( path, service_name ), messages_history))
1013
1014 def sendDelete(tid, fid):
1015 m = SMB2Message(SMB2SetInfoRequest(fid,
1016 additional_info = 0,
1017 info_type = SMB2_INFO_FILE,
1018 file_info_class = 0x0d, # SMB2_FILE_DISPOSITION_INFO
1019 data = b'\x01'))
1020 '''
1021 Resources:
1022 https://msdn.microsoft.com/en-us/library/cc246560.aspx
1023 https://msdn.microsoft.com/en-us/library/cc232098.aspx
1024 '''
1025 m.tid = tid
1026 self._sendSMBMessage(m)
1027 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback, fid = fid)
1028 messages_history.append(m)
1029
1030 def deleteCB(delete_message, **kwargs):
1031 messages_history.append(delete_message)
1032 if delete_message.status == 0:
1033 closeFid(delete_message.tid, kwargs['fid'], status = 0)
1034 else:
1035 closeFid(delete_message.tid, kwargs['fid'], status = delete_message.status)
1036
1037 def closeFid(tid, fid, status = None):
1038 m = SMB2Message(SMB2CloseRequest(fid))
1039 m.tid = tid
1040 self._sendSMBMessage(m)
1041 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, closeCB, errback, status = status)
1042 messages_history.append(m)
1043
1044 def closeCB(close_message, **kwargs):
1045 if kwargs['status'] == 0:
1046 callback(path_file_pattern)
1047 else:
1048 errback(OperationFailure('Failed to delete %s on %s: Delete failed' % ( path, service_name ), messages_history))
1049
1050 if service_name not in self.connected_trees:
1051 def connectCB(connect_message, **kwargs):
1052 messages_history.append(connect_message)
1053 if connect_message.status == 0:
1054 self.connected_trees[service_name] = connect_message.tid
1055 sendCreate(connect_message.tid)
1056 else:
1057 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
1058
1059 m = SMB2Message(SMB2TreeConnectRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name )))
1060 self._sendSMBMessage(m)
1061 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = service_name)
1062 messages_history.append(m)
1063 else:
1064 sendCreate(self.connected_trees[service_name])
1065
1066 def _resetFileAttributes_SMB2(self, service_name, path_file_pattern, callback, errback, timeout = 30):
1067 if not self.has_authenticated:
1068 raise NotReadyError('SMB connection not authenticated')
1069
1070 expiry_time = time.time() + timeout
1071 path = path_file_pattern.replace('/', '\\')
1072 if path.startswith('\\'):
1073 path = path[1:]
1074 if path.endswith('\\'):
1075 path = path[:-1]
1076 messages_history = [ ]
1077
1078 def sendCreate(tid):
1079 create_context_data = binascii.unhexlify("""
1080 28 00 00 00 10 00 04 00 00 00 18 00 10 00 00 00
1081 44 48 6e 51 00 00 00 00 00 00 00 00 00 00 00 00
1082 00 00 00 00 00 00 00 00 18 00 00 00 10 00 04 00
1083 00 00 18 00 00 00 00 00 4d 78 41 63 00 00 00 00
1084 00 00 00 00 10 00 04 00 00 00 18 00 00 00 00 00
1085 51 46 69 64 00 00 00 00
1086 """.replace(' ', '').replace('\n', ''))
10871312
10881313 m = SMB2Message(SMB2CreateRequest(path,
10891314 file_attributes = 0,
11021327 def createCB(open_message, **kwargs):
11031328 messages_history.append(open_message)
11041329 if open_message.status == 0:
1105 sendReset(open_message.tid, open_message.payload.fid)
1330 sendReset(kwargs['tid'], open_message.payload.fid)
11061331 else:
11071332 errback(OperationFailure('Failed to reset attributes of %s on %s: Unable to open file' % ( path, service_name ), messages_history))
11081333
11111336 additional_info = 0,
11121337 info_type = SMB2_INFO_FILE,
11131338 file_info_class = 4, # FileBasicInformation
1114 data = struct.pack('qqqqii',0,0,0,0,0x80,0))) # FILE_ATTRIBUTE_NORMAL
1115 '''
1116 Resources:
1117 https://msdn.microsoft.com/en-us/library/cc246560.aspx
1118 https://msdn.microsoft.com/en-us/library/cc232064.aspx
1119 https://msdn.microsoft.com/en-us/library/cc232094.aspx
1120 https://msdn.microsoft.com/en-us/library/cc232110.aspx
1121 '''
1122 m.tid = tid
1123 self._sendSMBMessage(m)
1124 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, resetCB, errback, fid = fid)
1339 data = struct.pack('qqqqii', 0, 0, 0, 0, file_attributes, 0)))
1340 # [MS-SMB2]: 2.2.39, [MS-FSCC]: 2.4, [MS-FSCC]: 2.4.7, [MS-FSCC]: 2.6
1341 m.tid = tid
1342 self._sendSMBMessage(m)
1343 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, resetCB, errback, tid = tid, fid = fid)
11251344 messages_history.append(m)
11261345
11271346 def resetCB(reset_message, **kwargs):
11281347 messages_history.append(reset_message)
11291348 if reset_message.status == 0:
1130 closeFid(reset_message.tid, kwargs['fid'], status = 0)
1131 else:
1132 closeFid(reset_message.tid, kwargs['fid'], status = reset_message.status)
1349 closeFid(kwargs['tid'], kwargs['fid'], status = 0)
1350 else:
1351 closeFid(kwargs['tid'], kwargs['fid'], status = reset_message.status)
11331352
11341353 def closeFid(tid, fid, status = None):
11351354 m = SMB2Message(SMB2CloseRequest(fid))
11591378 messages_history.append(m)
11601379 else:
11611380 sendCreate(self.connected_trees[service_name])
1162
1163
11641381
11651382 def _createDirectory_SMB2(self, service_name, path, callback, errback, timeout = 30):
11661383 if not self.has_authenticated:
11941411 create_context_data = create_context_data))
11951412 m.tid = tid
11961413 self._sendSMBMessage(m)
1197 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback)
1414 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback, tid = tid)
11981415 messages_history.append(m)
11991416
12001417 def createCB(create_message, **kwargs):
12011418 messages_history.append(create_message)
12021419 if create_message.status == 0:
1203 closeFid(create_message.tid, create_message.payload.fid)
1420 closeFid(kwargs['tid'], create_message.payload.fid)
12041421 else:
12051422 errback(OperationFailure('Failed to create directory %s on %s: Create failed' % ( path, service_name ), messages_history))
12061423
12681485 def createCB(open_message, **kwargs):
12691486 messages_history.append(open_message)
12701487 if open_message.status == 0:
1271 sendDelete(open_message.tid, open_message.payload.fid)
1488 sendDelete(kwargs['tid'], open_message.payload.fid)
12721489 else:
12731490 errback(OperationFailure('Failed to delete %s on %s: Unable to open directory' % ( path, service_name ), messages_history))
12741491
12801497 data = b'\x01'))
12811498 m.tid = tid
12821499 self._sendSMBMessage(m)
1283 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback, fid = fid)
1500 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback, tid = tid, fid = fid)
12841501 messages_history.append(m)
12851502
12861503 def deleteCB(delete_message, **kwargs):
12871504 messages_history.append(delete_message)
12881505 if delete_message.status == 0:
1289 closeFid(delete_message.tid, kwargs['fid'], status = 0)
1290 else:
1291 closeFid(delete_message.tid, kwargs['fid'], status = delete_message.status)
1506 closeFid(kwargs['tid'], kwargs['fid'], status = 0)
1507 else:
1508 closeFid(kwargs['tid'], kwargs['fid'], status = delete_message.status)
12921509
12931510 def closeFid(tid, fid, status = None):
12941511 m = SMB2Message(SMB2CloseRequest(fid))
13641581 def createCB(create_message, **kwargs):
13651582 messages_history.append(create_message)
13661583 if create_message.status == 0:
1367 sendRename(create_message.tid, create_message.payload.fid)
1584 sendRename(kwargs['tid'], create_message.payload.fid)
13681585 else:
13691586 errback(OperationFailure('Failed to rename %s on %s: Unable to open file/directory' % ( old_path, service_name ), messages_history))
13701587
13771594 data = data))
13781595 m.tid = tid
13791596 self._sendSMBMessage(m)
1380 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, renameCB, errback, fid = fid)
1597 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, renameCB, errback, tid = tid, fid = fid)
13811598 messages_history.append(m)
13821599
13831600 def renameCB(rename_message, **kwargs):
13841601 messages_history.append(rename_message)
13851602 if rename_message.status == 0:
1386 closeFid(rename_message.tid, kwargs['fid'], status = 0)
1387 else:
1388 closeFid(rename_message.tid, kwargs['fid'], status = rename_message.status)
1603 closeFid(kwargs['tid'], kwargs['fid'], status = 0)
1604 else:
1605 closeFid(kwargs['tid'], kwargs['fid'], status = rename_message.status)
13891606
13901607 def closeFid(tid, fid, status = None):
13911608 m = SMB2Message(SMB2CloseRequest(fid))
14521669 def createCB(create_message, **kwargs):
14531670 messages_history.append(create_message)
14541671 if create_message.status == 0:
1455 sendEnumSnapshots(create_message.tid, create_message.payload.fid)
1672 sendEnumSnapshots(kwargs['tid'], create_message.payload.fid)
14561673 else:
14571674 errback(OperationFailure('Failed to list snapshots %s on %s: Unable to open file/directory' % ( old_path, service_name ), messages_history))
14581675
14721689 results = [ ]
14731690 snapshots_count = struct.unpack('<I', enum_message.payload.out_data[4:8])[0]
14741691 for i in range(0, snapshots_count):
1475 s = enum_message.payload.out_data[12+i*50:12+48+i*50].decode('UTF-16LE')
1692 s = DataFaultToleranceStrategy.data_bytes_decode(enum_message.payload.out_data[12+i*50:12+48+i*50])
14761693 results.append(datetime(*list(map(int, ( s[5:9], s[10:12], s[13:15], s[16:18], s[19:21], s[22:24] )))))
14771694 closeFid(kwargs['tid'], kwargs['fid'], results = results)
14781695 else:
15931810 self._handleSessionChallenge(message, ntlm_token)
15941811 except ( securityblob.BadSecurityBlobError, securityblob.UnsupportedSecurityProvider ) as ex:
15951812 raise ProtocolError(str(ex), message.raw_data, message)
1596 elif message.status.internal_value == 0xc000006d: # STATUS_LOGON_FAILURE
1813 elif (message.status.internal_value == 0xc000006d # STATUS_LOGON_FAILURE
1814 or message.status.internal_value == 0xc0000064 # STATUS_NO_SUCH_USER
1815 or message.status.internal_value == 0xc000006a): # STATUS_WRONG_PASSWORD
15971816 self.has_authenticated = False
1598 self.log.info('Authentication (with extended security) failed. Please check username and password. You may need to enable/disable NTLMv2 authentication.')
1817 self.log.info('Authentication (with extended security) failed. Please check username and password.')
1818 self.onAuthFailed()
1819 elif (message.status.internal_value == 0xc0000193 # STATUS_ACCOUNT_EXPIRED
1820 or message.status.internal_value == 0xC0000071): # STATUS_PASSWORD_EXPIRED
1821 self.has_authenticated = False
1822 self.log.info('Authentication (with extended security) failed. Account or password has expired.')
1823 self.onAuthFailed()
1824 elif message.status.internal_value == 0xc0000234: # STATUS_ACCOUNT_LOCKED_OUT
1825 self.has_authenticated = False
1826 self.log.info('Authentication (with extended security) failed. Account has been locked due to too many invalid logon attempts.')
1827 self.onAuthFailed()
1828 elif message.status.internal_value == 0xc0000072: # STATUS_ACCOUNT_DISABLED
1829 self.has_authenticated = False
1830 self.log.info('Authentication (with extended security) failed. Account has been disabled.')
1831 self.onAuthFailed()
1832 elif (message.status.internal_value == 0xc000006f # STATUS_INVALID_LOGON_HOURS
1833 or message.status.internal_value == 0xc000015b # STATUS_LOGON_TYPE_NOT_GRANTED
1834 or message.status.internal_value == 0xc0000070): # STATUS_INVALID_WORKSTATION
1835 self.has_authenticated = False
1836 self.log.info('Authentication (with extended security) failed. Not allowed.')
1837 self.onAuthFailed()
1838 elif message.status.internal_value == 0xc000018c: # STATUS_TRUSTED_DOMAIN_FAILURE
1839 self.has_authenticated = False
1840 self.log.info('Authentication (with extended security) failed. Domain not trusted.')
1841 self.onAuthFailed()
1842 elif message.status.internal_value == 0xc000018d: # STATUS_TRUSTED_RELATIONSHIP_FAILURE
1843 self.has_authenticated = False
1844 self.log.info('Authentication (with extended security) failed. Workstation not trusted.')
15991845 self.onAuthFailed()
16001846 else:
16011847 raise ProtocolError('Unknown status value (0x%08X) in SMB_COM_SESSION_SETUP_ANDX (with extended security)' % message.status.internal_value,
16571903 self.log.info('Performing NTLMv1 authentication (with extended security) with server challenge "%s"', binascii.hexlify(server_challenge))
16581904 nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(self.password, server_challenge, True)
16591905
1660 ntlm_data = ntlm.generateAuthenticateMessage(server_flags,
1661 nt_challenge_response,
1662 lm_challenge_response,
1663 session_key,
1664 self.username,
1665 self.domain)
1906 ntlm_data, signing_session_key = ntlm.generateAuthenticateMessage(server_flags,
1907 nt_challenge_response,
1908 lm_challenge_response,
1909 session_key,
1910 self.username,
1911 self.domain,
1912 self.my_name)
16661913
16671914 if self.log.isEnabledFor(logging.DEBUG):
16681915 self.log.debug('NT challenge response is "%s" (%d bytes)', binascii.hexlify(nt_challenge_response), len(nt_challenge_response))
16821929
16831930 if self.is_signing_active:
16841931 self.log.info("SMB signing activated. All SMB messages will be signed.")
1685 self.signing_session_key = session_key
1932 self.signing_session_key = signing_session_key
16861933 if self.capabilities & CAP_EXTENDED_SECURITY:
16871934 self.signing_challenge_response = None
16881935 else:
18242071 for i in range(0, shares_count):
18252072 max_length, _, length = struct.unpack('<III', data_bytes[offset:offset+12])
18262073 offset += 12
1827 results[i].name = data_bytes[offset:offset+length*2-2].decode('UTF-16LE')
2074 results[i].name = DataFaultToleranceStrategy.data_bytes_decode(data_bytes[offset:offset+length*2-2])
18282075
18292076 if length % 2 != 0:
18302077 offset += (length * 2 + 2)
18332080
18342081 max_length, _, length = struct.unpack('<III', data_bytes[offset:offset+12])
18352082 offset += 12
1836 results[i].comments = data_bytes[offset:offset+length*2-2].decode('UTF-16LE')
2083 results[i].comments = DataFaultToleranceStrategy.data_bytes_decode(data_bytes[offset:offset+length*2-2])
18372084
18382085 if length % 2 != 0:
18392086 offset += (length * 2 + 2)
18562103 def readCB(read_message, **kwargs):
18572104 messages_history.append(read_message)
18582105 if not read_message.status.hasError:
1859 data_len = read_message.payload.data_length
18602106 data_bytes = read_message.payload.data
18612107
18622108 if data_bytes[3] & 0x02 == 0:
1863 sendReadRequest(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:data_len-24])
1864 else:
1865 decodeResults(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:data_len-24])
2109 sendReadRequest(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:])
2110 else:
2111 decodeResults(read_message.tid, kwargs['fid'], kwargs['data_bytes'] + data_bytes[24:])
18662112 else:
18672113 closeFid(read_message.tid, kwargs['fid'])
18682114 errback(OperationFailure('Failed to list shares: Unable to retrieve shared device list', messages_history))
19012147 setup_bytes = struct.pack('<H', 0x0001) # TRANS2_FIND_FIRST2 sub-command. See [MS-CIFS]: 2.2.6.2.1
19022148 params_bytes = \
19032149 struct.pack('<HHHHI',
1904 search, # SearchAttributes
2150 search & 0xFFFF, # SearchAttributes (need to restrict the values due to introduction of SMB_FILE_ATTRIBUTE_INCL_NORMAL)
19052151 100, # SearchCount
19062152 0x0006, # Flags: SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS
19072153 0x0104, # InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO
1908 0x0000) # SearchStorageType
2154 0x0000) # SearchStorageType (seems to be ignored by Windows)
19092155 if support_dfs:
19102156 params_bytes += ("\\" + self.remote_name + "\\" + service_name + path + pattern + '\0').encode('UTF-16LE')
19112157 else:
1912 params_bytes += (path + pattern).encode('UTF-16LE')
2158 params_bytes += (path + pattern + '\0').encode('UTF-16LE')
19132159
19142160 m = SMBMessage(ComTransaction2Request(max_params_count = 10,
19152161 max_data_count = 16644,
19432189 if offset2 + filename_length > data_length:
19442190 return data_bytes[offset:]
19452191
1946 filename = data_bytes[offset2:offset2+filename_length].decode('UTF-16LE')
1947 short_name = short_name.decode('UTF-16LE')
1948 results.append(SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time),
1949 convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
1950 file_size, alloc_size, file_attributes, short_name, filename))
2192 filename = DataFaultToleranceStrategy.data_bytes_decode(data_bytes[offset2:offset2+filename_length])
2193 short_name = DataFaultToleranceStrategy.data_bytes_decode(short_name)
2194
2195 accept_result = False
2196 if (file_attributes & 0xff) in ( 0x00, ATTR_NORMAL ): # Only the first 8-bits are compared. We ignore other bits like temp, compressed, encryption, sparse, indexed, etc
2197 accept_result = (search == SMB_FILE_ATTRIBUTE_NORMAL) or (search & SMB_FILE_ATTRIBUTE_INCL_NORMAL)
2198 else:
2199 accept_result = (file_attributes & search) > 0
2200 if accept_result:
2201 results.append(SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time),
2202 convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
2203 file_size, alloc_size, file_attributes, short_name, filename))
19512204
19522205 if next_offset:
19532206 offset += next_offset
19872240 elif end_of_search:
19882241 callback(results)
19892242 else:
1990 sendFindNext(find_message.tid, sid, last_name_offset, kwargs.get('support_dfs', False))
1991 else:
1992 errback(OperationFailure('Failed to list %s on %s: Unable to retrieve file list' % ( path, service_name ), messages_history))
1993
1994 def sendFindNext(tid, sid, resume_key, support_dfs=False):
2243 sendFindNext(find_message.tid, sid, 0, results[-1].filename, kwargs.get('support_dfs', False))
2244 else:
2245 if find_message.status.internal_value == 0xC000000F: # [MS-ERREF]: STATUS_NO_SUCH_FILE
2246 # Remote server returns STATUS_NO_SUCH_FILE error so we assume that the search returns no matching files
2247 callback([ ])
2248 else:
2249 errback(OperationFailure('Failed to list %s on %s: Unable to retrieve file list' % ( path, service_name ), messages_history))
2250
2251 def sendFindNext(tid, sid, resume_key, resume_file, support_dfs):
19952252 setup_bytes = struct.pack('<H', 0x0002) # TRANS2_FIND_NEXT2 sub-command. See [MS-CIFS]: 2.2.6.3.1
19962253 params_bytes = \
19972254 struct.pack('<HHHIH',
19992256 100, # SearchCount
20002257 0x0104, # InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO
20012258 resume_key, # ResumeKey
2002 0x000a) # Flags: SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS
2003 if support_dfs:
2004 params_bytes += ("\\" + self.remote_name + "\\" + service_name + path + pattern + '\0').encode('UTF-16LE')
2005 else:
2006 params_bytes += (path + pattern).encode('UTF-16LE')
2259 0x0006) # Flags: SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS
2260 params_bytes += (resume_file+'\0').encode('UTF-16LE')
20072261
20082262 m = SMBMessage(ComTransaction2Request(max_params_count = 10,
20092263 max_data_count = 16644,
20492303 elif end_of_search:
20502304 callback(results)
20512305 else:
2052 sendFindNext(find_message.tid, kwargs['sid'], last_name_offset, kwargs.get('support_dfs', False))
2306 sendFindNext(find_message.tid, kwargs['sid'], 0, results[-1].filename, kwargs.get('support_dfs', False))
20532307 else:
20542308 errback(OperationFailure('Failed to list %s on %s: Unable to retrieve file list' % ( path, service_name ), messages_history))
20552309
21272381 info_size = struct.calcsize(info_format)
21282382 create_time, last_access_time, last_write_time, last_attr_change_time, \
21292383 file_attributes, _, alloc_size, file_size = struct.unpack(info_format, query_message.payload.data_bytes[:info_size])
2130
2131 info = SharedFile(create_time, last_access_time, last_write_time, last_attr_change_time,
2132 file_size, alloc_size, file_attributes, path, path)
2384 filename = self._extractLastPathComponent(path)
2385
2386 info = SharedFile(convertFILETIMEtoEpoch(create_time), convertFILETIMEtoEpoch(last_access_time), convertFILETIMEtoEpoch(last_write_time), convertFILETIMEtoEpoch(last_attr_change_time),
2387 file_size, alloc_size, file_attributes, filename, filename)
21332388 callback(info)
21342389 else:
21352390 errback(OperationFailure('Failed to get attributes for %s on %s: Read failed' % ( path, service_name ), messages_history))
21492404 messages_history.append(m)
21502405 else:
21512406 sendQuery(self.connected_trees[service_name])
2407
2408 def _getSecurity_SMB1(self, service_name, path_file_pattern, callback, errback, timeout = 30):
2409 raise NotReadyError('getSecurity is not yet implemented for SMB1')
21522410
21532411 def _retrieveFile_SMB1(self, service_name, path, file_obj, callback, errback, timeout = 30):
21542412 return self._retrieveFileFromOffset(service_name, path, file_obj, callback, errback, 0, -1, timeout)
22732531 errback(OperationFailure('Failed to store %s on %s: Unable to open file' % ( path, service_name ), messages_history))
22742532
22752533 def sendWrite(tid, fid, offset):
2276 # For message signing, the total SMB message size must be not exceed the max_buffer_size. Non-message signing does not have this limitation
2277 write_count = min((self.is_signing_active and (self.max_buffer_size-64)) or self.max_raw_size, 0xFFFF-1) # Need to minus 1 byte from 0xFFFF because of the first NULL byte in the ComWriteAndxRequest message data
2534 # [MS-SMB] 2.2.4.5.2.2: The total SMB message size (inclusive of SMB header) must be not exceed the max_buffer_size.
2535 write_count = min(self.max_buffer_size-64, 0xFFFF-64) # SMB header is 32-bytes. We factor in another 32-bytes for the message parameter block
22782536 data_bytes = file_obj.read(write_count)
22792537 data_len = len(data_bytes)
22802538 if data_len > 0:
23172575 else:
23182576 sendOpen(self.connected_trees[service_name])
23192577
2320 def _deleteFiles_SMB1(self, service_name, path_file_pattern, callback, errback, timeout = 30):
2578 def _deleteFiles_SMB1(self, service_name, path_file_pattern, delete_matching_folders, callback, errback, timeout = 30):
23212579 if not self.has_authenticated:
23222580 raise NotReadyError('SMB connection not authenticated')
23232581
2582 expiry_time = time.time() + timeout
2583 pattern = None
23242584 path = path_file_pattern.replace('/', '\\')
2585 if path.startswith('\\'):
2586 path = path[1:]
2587 if path.endswith('\\'):
2588 path = path[:-1]
2589 else:
2590 path_components = path.split('\\')
2591 if path_components[-1].find('*') > -1 or path_components[-1].find('?') > -1:
2592 path = '\\'.join(path_components[:-1])
2593 pattern = path_components[-1]
2594 messages_history, files_queue = [ ], [ ]
2595
2596 if pattern is None:
2597 path_components = path.split('\\')
2598 if len(path_components) > 1:
2599 files_queue.append(( '\\'.join(path_components[:-1]), path_components[-1] ))
2600 else:
2601 files_queue.append(( '', path ))
2602
2603 def deleteCB(path):
2604 if files_queue:
2605 p, filename = files_queue.pop(0)
2606 if filename:
2607 if p:
2608 filename = p + '\\' + filename
2609 self._deleteFiles_SMB1__del(service_name, self.connected_trees[service_name], filename, deleteCB, errback, timeout)
2610 else:
2611 self._deleteDirectory_SMB1(service_name, p, deleteCB, errback, timeout = 30)
2612 else:
2613 callback(path_file_pattern)
2614
2615 def listCB(files_list):
2616 files_queue.extend(files_list)
2617 deleteCB(None)
2618
2619 if service_name not in self.connected_trees:
2620 def connectCB(connect_message, **kwargs):
2621 messages_history.append(connect_message)
2622 if not connect_message.status.hasError:
2623 self.connected_trees[service_name] = connect_message.tid
2624 if files_queue:
2625 deleteCB(None)
2626 else:
2627 self._deleteFiles_SMB1__list(service_name, path, pattern, delete_matching_folders, listCB, errback, timeout)
2628 else:
2629 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2630
2631 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
2632 self._sendSMBMessage(m)
2633 self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = service_name)
2634 messages_history.append(m)
2635 else:
2636 if files_queue:
2637 deleteCB(None)
2638 else:
2639 self._deleteFiles_SMB1__list(service_name, path, pattern, delete_matching_folders, listCB, errback, timeout)
2640
2641 def _deleteFiles_SMB1__list(self, service_name, path, pattern, delete_matching_folders, callback, errback, timeout = 30):
2642 folder_queue = [ ]
2643 files_list = [ ]
2644 current_path = [ path ]
2645 search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL
2646
2647 def listCB(results):
2648 files = [ ]
2649 for f in filter(lambda x: x.filename not in [ '.', '..' ], results):
2650 if f.isDirectory:
2651 if delete_matching_folders:
2652 folder_queue.append(current_path[0]+'\\'+f.filename)
2653 else:
2654 files.append(( current_path[0], f.filename ))
2655 if current_path[0]!=path and delete_matching_folders:
2656 files.append(( current_path[0], None ))
2657
2658 if files:
2659 files_list[0:0] = files
2660
2661 if folder_queue:
2662 p = folder_queue.pop()
2663 current_path[0] = p
2664 self._listPath_SMB1(service_name, current_path[0], listCB, errback, search = search, pattern = '*', timeout = 30)
2665 else:
2666 callback(files_list)
2667
2668 self._listPath_SMB1(service_name, path, listCB, errback, search = search, pattern = pattern, timeout = timeout)
2669
2670 def _deleteFiles_SMB1__del(self, service_name, tid, path, callback, errback, timeout = 30):
23252671 messages_history = [ ]
23262672
23272673 def sendDelete(tid):
23352681 def deleteCB(delete_message, **kwargs):
23362682 messages_history.append(delete_message)
23372683 if not delete_message.status.hasError:
2684 callback(path)
2685 elif delete_message.status.internal_value == 0xC000000F: # [MS-ERREF]: STATUS_NO_SUCH_FILE
2686 # If there are no matching files, we just treat as success instead of failing
23382687 callback(path_file_pattern)
2339 else:
2340 errback(OperationFailure('Failed to store %s on %s: Delete failed' % ( path, service_name ), messages_history))
2688 elif delete_message.status.internal_value == 0xC00000BA: # [MS-ERREF]: STATUS_FILE_IS_A_DIRECTORY
2689 errback(OperationFailure('Failed to delete %s on %s: Cannot delete a folder. Please use deleteDirectory() method or append "/*" to your path if you wish to delete all files in the folder.' % ( path, service_name ), messages_history))
2690 elif delete_message.status.internal_value == 0xC0000034: # [MS-ERREF]: STATUS_OBJECT_NAME_INVALID
2691 errback(OperationFailure('Failed to delete %s on %s: Path not found' % ( path, service_name ), messages_history))
2692 else:
2693 errback(OperationFailure('Failed to delete %s on %s: Delete failed' % ( path, service_name ), messages_history))
2694
2695 sendDelete(tid)
2696
2697 def _resetFileAttributes_SMB1(self, service_name, path_file_pattern, callback, errback, file_attributes=ATTR_NORMAL, timeout = 30):
2698 raise NotReadyError('resetFileAttributes is not yet implemented for SMB1')
2699
2700 def _createDirectory_SMB1(self, service_name, path, callback, errback, timeout = 30):
2701 if not self.has_authenticated:
2702 raise NotReadyError('SMB connection not authenticated')
2703
2704 path = path.replace('/', '\\')
2705 messages_history = [ ]
2706
2707 def sendCreate(tid):
2708 m = SMBMessage(ComCreateDirectoryRequest(path))
2709 m.tid = tid
2710 self._sendSMBMessage(m)
2711 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback)
2712 messages_history.append(m)
2713
2714 def createCB(create_message, **kwargs):
2715 messages_history.append(create_message)
2716 if not create_message.status.hasError:
2717 callback(path)
2718 else:
2719 errback(OperationFailure('Failed to create directory %s on %s: Create failed' % ( path, service_name ), messages_history))
2720
2721 if service_name not in self.connected_trees:
2722 def connectCB(connect_message, **kwargs):
2723 messages_history.append(connect_message)
2724 if not connect_message.status.hasError:
2725 self.connected_trees[service_name] = connect_message.tid
2726 sendCreate(connect_message.tid)
2727 else:
2728 errback(OperationFailure('Failed to create directory %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2729
2730 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
2731 self._sendSMBMessage(m)
2732 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name)
2733 messages_history.append(m)
2734 else:
2735 sendCreate(self.connected_trees[service_name])
2736
2737 def _deleteDirectory_SMB1(self, service_name, path, callback, errback, timeout = 30):
2738 if not self.has_authenticated:
2739 raise NotReadyError('SMB connection not authenticated')
2740
2741 path = path.replace('/', '\\')
2742 messages_history = [ ]
2743
2744 def sendDelete(tid):
2745 m = SMBMessage(ComDeleteDirectoryRequest(path))
2746 m.tid = tid
2747 self._sendSMBMessage(m)
2748 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback)
2749 messages_history.append(m)
2750
2751 def deleteCB(delete_message, **kwargs):
2752 messages_history.append(delete_message)
2753 if not delete_message.status.hasError:
2754 callback(path)
2755 else:
2756 errback(OperationFailure('Failed to delete directory %s on %s: Delete failed' % ( path, service_name ), messages_history))
23412757
23422758 if service_name not in self.connected_trees:
23432759 def connectCB(connect_message, **kwargs):
23462762 self.connected_trees[service_name] = connect_message.tid
23472763 sendDelete(connect_message.tid)
23482764 else:
2349 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2350
2351 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
2352 self._sendSMBMessage(m)
2353 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name)
2354 messages_history.append(m)
2355 else:
2356 sendDelete(self.connected_trees[service_name])
2357
2358 def _resetFileAttributes_SMB1(self, service_name, path_file_pattern, callback, errback, timeout = 30):
2359 raise NotReadyError('resetFileAttributes is not yet implemented for SMB1')
2360
2361 def _createDirectory_SMB1(self, service_name, path, callback, errback, timeout = 30):
2362 if not self.has_authenticated:
2363 raise NotReadyError('SMB connection not authenticated')
2364
2365 path = path.replace('/', '\\')
2366 messages_history = [ ]
2367
2368 def sendCreate(tid):
2369 m = SMBMessage(ComCreateDirectoryRequest(path))
2370 m.tid = tid
2371 self._sendSMBMessage(m)
2372 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback)
2373 messages_history.append(m)
2374
2375 def createCB(create_message, **kwargs):
2376 messages_history.append(create_message)
2377 if not create_message.status.hasError:
2378 callback(path)
2379 else:
2380 errback(OperationFailure('Failed to create directory %s on %s: Create failed' % ( path, service_name ), messages_history))
2381
2382 if service_name not in self.connected_trees:
2383 def connectCB(connect_message, **kwargs):
2384 messages_history.append(connect_message)
2385 if not connect_message.status.hasError:
2386 self.connected_trees[service_name] = connect_message.tid
2387 sendCreate(connect_message.tid)
2388 else:
2389 errback(OperationFailure('Failed to create directory %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2390
2391 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
2392 self._sendSMBMessage(m)
2393 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name)
2394 messages_history.append(m)
2395 else:
2396 sendCreate(self.connected_trees[service_name])
2397
2398 def _deleteDirectory_SMB1(self, service_name, path, callback, errback, timeout = 30):
2399 if not self.has_authenticated:
2400 raise NotReadyError('SMB connection not authenticated')
2401
2402 path = path.replace('/', '\\')
2403 messages_history = [ ]
2404
2405 def sendDelete(tid):
2406 m = SMBMessage(ComDeleteDirectoryRequest(path))
2407 m.tid = tid
2408 self._sendSMBMessage(m)
2409 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback)
2410 messages_history.append(m)
2411
2412 def deleteCB(delete_message, **kwargs):
2413 messages_history.append(delete_message)
2414 if not delete_message.status.hasError:
2415 callback(path)
2416 else:
2417 errback(OperationFailure('Failed to delete directory %s on %s: Delete failed' % ( path, service_name ), messages_history))
2418
2419 if service_name not in self.connected_trees:
2420 def connectCB(connect_message, **kwargs):
2421 messages_history.append(connect_message)
2422 if not connect_message.status.hasError:
2423 self.connected_trees[service_name] = connect_message.tid
2424 sendDelete(connect_message.tid)
2425 else:
2426 errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
2765 errback(OperationFailure('Failed to delete directory %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history))
24272766
24282767 m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, ''))
24292768 self._sendSMBMessage(m)
25252864 results = [ ]
25262865 snapshots_count = struct.unpack('<I', enum_message.payload.data_bytes[4:8])[0]
25272866 for i in range(0, snapshots_count):
2528 s = enum_message.payload.data_bytes[12+i*50:12+48+i*50].decode('UTF-16LE')
2867 s = DataFaultToleranceStrategy.data_bytes_decode(enum_message.payload.data_bytes[12+i*50:12+48+i*50])
25292868 results.append(datetime(*list(map(int, ( s[5:9], s[10:12], s[13:15], s[16:18], s[19:21], s[22:24] )))))
25302869 closeFid(kwargs['tid'], kwargs['fid'])
25312870 callback(results)
25582897 def _echo_SMB1(self, data, callback, errback, timeout = 30):
25592898 messages_history = [ ]
25602899
2900 if not isinstance(data, type(b'')):
2901 raise TypeError('Echo data must be %s not %s' % (type(b'').__name__, type(data).__name__))
2902
25612903 def echoCB(echo_message, **kwargs):
25622904 messages_history.append(echo_message)
25632905 if not echo_message.status.hasError:
25702912 self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, echoCB, errback)
25712913 messages_history.append(m)
25722914
2915 def _extractLastPathComponent(self, path):
2916 return path.replace('\\', '/').split('/')[-1]
2917
25732918
25742919 class SharedDevice:
25752920 """
25762921 Contains information about a single shared device on the remote server.
2922
2923 The following attributes are available:
2924
2925 * name : An unicode string containing the name of the shared device
2926 * comments : An unicode string containing the user description of the shared device
25772927 """
25782928
25792929 # The following constants are taken from [MS-SRVS]: 2.2.2.4
26282978
26292979 If you encounter *SharedFile* instance where its short_name attribute is empty but the filename attribute contains a short name which does not correspond
26302980 to any files/folders on your remote shared device, it could be that the original filename on the file/folder entry on the shared device contains
2631 one of these prohibited characters: "\/[]:+|<>=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).
2981 one of these prohibited characters: "\\/[]:+|<>=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).
2982
2983 The following attributes are available:
2984
2985 * create_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server
2986 * last_access_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server
2987 * last_write_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server
2988 * last_attr_change_time : Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server
2989 * file_size : File size in number of bytes
2990 * alloc_size : Total number of bytes allocated to store this file
2991 * file_attributes : A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3. You can perform bit-wise tests to determine the status of the file using the ATTR_xxx constants in smb_constants.py.
2992 * short_name : Unicode string containing the short name of this file (usually in 8.3 notation)
2993 * filename : Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.
2994 * file_id : Long value representing the file reference number for the file. If the remote system does not support this field, this field will be None or 0. See [MS-FSCC]: 2.4.17
26322995 """
26332996
2634 def __init__(self, create_time, last_access_time, last_write_time, last_attr_change_time, file_size, alloc_size, file_attributes, short_name, filename):
2997 def __init__(self, create_time, last_access_time, last_write_time, last_attr_change_time, file_size, alloc_size, file_attributes, short_name, filename, file_id=None):
26352998 self.create_time = create_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server
26362999 self.last_access_time = last_access_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server
26373000 self.last_write_time = last_write_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server
26383001 self.last_attr_change_time = last_attr_change_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server
26393002 self.file_size = file_size #: File size in number of bytes
26403003 self.alloc_size = alloc_size #: Total number of bytes allocated to store this file
2641 self.file_attributes = file_attributes #: A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3
3004 self.file_attributes = file_attributes #: A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3. You can perform bit-wise tests to determine the status of the file using the ATTR_xxx constants in smb_constants.py.
26423005 self.short_name = short_name #: Unicode string containing the short name of this file (usually in 8.3 notation)
26433006 self.filename = filename #: Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.
3007 self.file_id = file_id #: Long value representing the file reference number for the file. If the remote system does not support this field, this field will be None or 0. See [MS-FSCC]: 2.4.17
26443008
26453009 @property
26463010 def isDirectory(self):
26513015 def isReadOnly(self):
26523016 """A convenient property to return True if this file resource is read-only on the remote server"""
26533017 return bool(self.file_attributes & ATTR_READONLY)
3018
3019 @property
3020 def isNormal(self):
3021 """
3022 A convenient property to return True if this is a normal file.
3023
3024 Note that pysmb defines a normal file as a file entry that is not read-only, not hidden, not system, not archive and not a directory.
3025 It ignores other attributes like compression, indexed, sparse, temporary and encryption.
3026 """
3027 return (self.file_attributes==ATTR_NORMAL) or ((self.file_attributes & 0xff)==0)
26543028
26553029 def __unicode__(self):
26563030 return 'Shared file: %s (FileSize:%d bytes, isDirectory:%s)' % ( self.filename, self.file_size, self.isDirectory )
00
1 import types, hmac, binascii, struct, random
1 import types, hmac, binascii, struct, random, string
2 from .utils.rc4 import RC4_encrypt
23 from .utils.pyDes import des
34
45 try:
5758
5859 NTLM_FLAGS = NTLM_NegotiateUnicode | \
5960 NTLM_RequestTarget | \
61 NTLM_NegotiateSign | \
6062 NTLM_NegotiateNTLM | \
6163 NTLM_NegotiateAlwaysSign | \
6264 NTLM_NegotiateExtendedSecurity | \
6365 NTLM_NegotiateTargetInfo | \
6466 NTLM_NegotiateVersion | \
6567 NTLM_Negotiate128 | \
66 NTLM_NegotiateKeyExchange | \
67 NTLM_Negotiate56
68 NTLM_NegotiateKeyExchange
6869
6970 def generateNegotiateMessage():
7071 """
8081 return s
8182
8283
83 def generateAuthenticateMessage(challenge_flags, nt_response, lm_response, session_key, user, domain = 'WORKGROUP', workstation = 'LOCALHOST'):
84 def generateAuthenticateMessage(challenge_flags, nt_response, lm_response, request_session_key, user, domain = 'WORKGROUP', workstation = 'LOCALHOST'):
8485 """
8586 References:
8687 ===========
8889 """
8990 FORMAT = '<8sIHHIHHIHHIHHIHHIHHII'
9091 FORMAT_SIZE = struct.calcsize(FORMAT)
92
93 # [MS-NLMP]: 3.1.5.1.2
94 # http://grutz.jingojango.net/exploits/davenport-ntlm.html
95 session_key = session_signing_key = request_session_key
96 if challenge_flags & NTLM_NegotiateKeyExchange:
97 session_signing_key = "".join([ random.choice(string.digits+string.ascii_letters) for _ in range(16) ]).encode('ascii')
98 session_key = RC4_encrypt(request_session_key, session_signing_key)
9199
92100 lm_response_length = len(lm_response)
93101 lm_response_offset = FORMAT_SIZE
124132 session_key_length, session_key_length, session_key_offset,
125133 auth_flags)
126134
127 return s + lm_response + nt_response + padding + domain_unicode + user_unicode + workstation_unicode + session_key
135 return s + lm_response + nt_response + padding + domain_unicode + user_unicode + workstation_unicode + session_key, session_signing_key
128136
129137
130138 def decodeChallengeMessage(ntlm_data):
160168 d = MD4()
161169 d.update(password.encode('UTF-16LE'))
162170 ntlm_hash = d.digest() # The NT password hash
163 response_key = hmac.new(ntlm_hash, (user.upper() + domain).encode('UTF-16LE')).digest() # The NTLMv2 password hash. In [MS-NLMP], this is the result of NTOWFv2 and LMOWFv2 functions
171 response_key = hmac.new(ntlm_hash, (user.upper() + domain).encode('UTF-16LE'), 'md5').digest() # The NTLMv2 password hash. In [MS-NLMP], this is the result of NTOWFv2 and LMOWFv2 functions
164172 temp = b'\x01\x01' + b'\0'*6 + client_timestamp + client_challenge + b'\0'*4 + server_info
165 ntproofstr = hmac.new(response_key, server_challenge + temp).digest()
173 ntproofstr = hmac.new(response_key, server_challenge + temp, 'md5').digest()
166174
167175 nt_challenge_response = ntproofstr + temp
168 lm_challenge_response = hmac.new(response_key, server_challenge + client_challenge).digest() + client_challenge
169 session_key = hmac.new(response_key, ntproofstr).digest()
176 lm_challenge_response = hmac.new(response_key, server_challenge + client_challenge, 'md5').digest() + client_challenge
177 session_key = hmac.new(response_key, ntproofstr, 'md5').digest()
170178
171179 return nt_challenge_response, lm_challenge_response, session_key
172180
0 """
1 This module implements security descriptors, and the partial structures
2 used in them, as specified in [MS-DTYP].
3 """
4
5 import struct
6
7
8 # Security descriptor control flags
9 # [MS-DTYP]: 2.4.6
10 SECURITY_DESCRIPTOR_OWNER_DEFAULTED = 0x0001
11 SECURITY_DESCRIPTOR_GROUP_DEFAULTED = 0x0002
12 SECURITY_DESCRIPTOR_DACL_PRESENT = 0x0004
13 SECURITY_DESCRIPTOR_DACL_DEFAULTED = 0x0008
14 SECURITY_DESCRIPTOR_SACL_PRESENT = 0x0010
15 SECURITY_DESCRIPTOR_SACL_DEFAULTED = 0x0020
16 SECURITY_DESCRIPTOR_SERVER_SECURITY = 0x0040
17 SECURITY_DESCRIPTOR_DACL_TRUSTED = 0x0080
18 SECURITY_DESCRIPTOR_DACL_COMPUTED_INHERITANCE_REQUIRED = 0x0100
19 SECURITY_DESCRIPTOR_SACL_COMPUTED_INHERITANCE_REQUIRED = 0x0200
20 SECURITY_DESCRIPTOR_DACL_AUTO_INHERITED = 0x0400
21 SECURITY_DESCRIPTOR_SACL_AUTO_INHERITED = 0x0800
22 SECURITY_DESCRIPTOR_DACL_PROTECTED = 0x1000
23 SECURITY_DESCRIPTOR_SACL_PROTECTED = 0x2000
24 SECURITY_DESCRIPTOR_RM_CONTROL_VALID = 0x4000
25 SECURITY_DESCRIPTOR_SELF_RELATIVE = 0x8000
26
27 # ACE types
28 # [MS-DTYP]: 2.4.4.1
29 ACE_TYPE_ACCESS_ALLOWED = 0x00
30 ACE_TYPE_ACCESS_DENIED = 0x01
31 ACE_TYPE_SYSTEM_AUDIT = 0x02
32 ACE_TYPE_SYSTEM_ALARM = 0x03
33 ACE_TYPE_ACCESS_ALLOWED_COMPOUND = 0x04
34 ACE_TYPE_ACCESS_ALLOWED_OBJECT = 0x05
35 ACE_TYPE_ACCESS_DENIED_OBJECT = 0x06
36 ACE_TYPE_SYSTEM_AUDIT_OBJECT = 0x07
37 ACE_TYPE_SYSTEM_ALARM_OBJECT = 0x08
38 ACE_TYPE_ACCESS_ALLOWED_CALLBACK = 0x09
39 ACE_TYPE_ACCESS_DENIED_CALLBACK = 0x0A
40 ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT = 0x0B
41 ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT = 0x0C
42 ACE_TYPE_SYSTEM_AUDIT_CALLBACK = 0x0D
43 ACE_TYPE_SYSTEM_ALARM_CALLBACK = 0x0E
44 ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT = 0x0F
45 ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT = 0x10
46 ACE_TYPE_SYSTEM_MANDATORY_LABEL = 0x11
47 ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE = 0x12
48 ACE_TYPE_SYSTEM_SCOPED_POLICY_ID = 0x13
49
50 # ACE flags
51 # [MS-DTYP]: 2.4.4.1
52 ACE_FLAG_OBJECT_INHERIT = 0x01
53 ACE_FLAG_CONTAINER_INHERIT = 0x02
54 ACE_FLAG_NO_PROPAGATE_INHERIT = 0x04
55 ACE_FLAG_INHERIT_ONLY = 0x08
56 ACE_FLAG_INHERITED = 0x10
57 ACE_FLAG_SUCCESSFUL_ACCESS = 0x40
58 ACE_FLAG_FAILED_ACCESS = 0x80
59
60 # Pre-defined well-known SIDs
61 # [MS-DTYP]: 2.4.2.4
62 SID_NULL = "S-1-0-0"
63 SID_EVERYONE = "S-1-1-0"
64 SID_LOCAL = "S-1-2-0"
65 SID_CONSOLE_LOGON = "S-1-2-1"
66 SID_CREATOR_OWNER = "S-1-3-0"
67 SID_CREATOR_GROUP = "S-1-3-1"
68 SID_OWNER_SERVER = "S-1-3-2"
69 SID_GROUP_SERVER = "S-1-3-3"
70 SID_OWNER_RIGHTS = "S-1-3-4"
71 SID_NT_AUTHORITY = "S-1-5"
72 SID_DIALUP = "S-1-5-1"
73 SID_NETWORK = "S-1-5-2"
74 SID_BATCH = "S-1-5-3"
75 SID_INTERACTIVE = "S-1-5-4"
76 SID_SERVICE = "S-1-5-6"
77 SID_ANONYMOUS = "S-1-5-7"
78 SID_PROXY = "S-1-5-8"
79 SID_ENTERPRISE_DOMAIN_CONTROLLERS = "S-1-5-9"
80 SID_PRINCIPAL_SELF = "S-1-5-10"
81 SID_AUTHENTICATED_USERS = "S-1-5-11"
82 SID_RESTRICTED_CODE = "S-1-5-12"
83 SID_TERMINAL_SERVER_USER = "S-1-5-13"
84 SID_REMOTE_INTERACTIVE_LOGON = "S-1-5-14"
85 SID_THIS_ORGANIZATION = "S-1-5-15"
86 SID_IUSR = "S-1-5-17"
87 SID_LOCAL_SYSTEM = "S-1-5-18"
88 SID_LOCAL_SERVICE = "S-1-5-19"
89 SID_NETWORK_SERVICE = "S-1-5-20"
90 SID_COMPOUNDED_AUTHENTICATION = "S-1-5-21-0-0-0-496"
91 SID_CLAIMS_VALID = "S-1-5-21-0-0-0-497"
92 SID_BUILTIN_ADMINISTRATORS = "S-1-5-32-544"
93 SID_BUILTIN_USERS = "S-1-5-32-545"
94 SID_BUILTIN_GUESTS = "S-1-5-32-546"
95 SID_POWER_USERS = "S-1-5-32-547"
96 SID_ACCOUNT_OPERATORS = "S-1-5-32-548"
97 SID_SERVER_OPERATORS = "S-1-5-32-549"
98 SID_PRINTER_OPERATORS = "S-1-5-32-550"
99 SID_BACKUP_OPERATORS = "S-1-5-32-551"
100 SID_REPLICATOR = "S-1-5-32-552"
101 SID_ALIAS_PREW2KCOMPACC = "S-1-5-32-554"
102 SID_REMOTE_DESKTOP = "S-1-5-32-555"
103 SID_NETWORK_CONFIGURATION_OPS = "S-1-5-32-556"
104 SID_INCOMING_FOREST_TRUST_BUILDERS = "S-1-5-32-557"
105 SID_PERFMON_USERS = "S-1-5-32-558"
106 SID_PERFLOG_USERS = "S-1-5-32-559"
107 SID_WINDOWS_AUTHORIZATION_ACCESS_GROUP = "S-1-5-32-560"
108 SID_TERMINAL_SERVER_LICENSE_SERVERS = "S-1-5-32-561"
109 SID_DISTRIBUTED_COM_USERS = "S-1-5-32-562"
110 SID_IIS_IUSRS = "S-1-5-32-568"
111 SID_CRYPTOGRAPHIC_OPERATORS = "S-1-5-32-569"
112 SID_EVENT_LOG_READERS = "S-1-5-32-573"
113 SID_CERTIFICATE_SERVICE_DCOM_ACCESS = "S-1-5-32-574"
114 SID_RDS_REMOTE_ACCESS_SERVERS = "S-1-5-32-575"
115 SID_RDS_ENDPOINT_SERVERS = "S-1-5-32-576"
116 SID_RDS_MANAGEMENT_SERVERS = "S-1-5-32-577"
117 SID_HYPER_V_ADMINS = "S-1-5-32-578"
118 SID_ACCESS_CONTROL_ASSISTANCE_OPS = "S-1-5-32-579"
119 SID_REMOTE_MANAGEMENT_USERS = "S-1-5-32-580"
120 SID_WRITE_RESTRICTED_CODE = "S-1-5-33"
121 SID_NTLM_AUTHENTICATION = "S-1-5-64-10"
122 SID_SCHANNEL_AUTHENTICATION = "S-1-5-64-14"
123 SID_DIGEST_AUTHENTICATION = "S-1-5-64-21"
124 SID_THIS_ORGANIZATION_CERTIFICATE = "S-1-5-65-1"
125 SID_NT_SERVICE = "S-1-5-80"
126 SID_USER_MODE_DRIVERS = "S-1-5-84-0-0-0-0-0"
127 SID_LOCAL_ACCOUNT = "S-1-5-113"
128 SID_LOCAL_ACCOUNT_AND_MEMBER_OF_ADMINISTRATORS_GROUP = "S-1-5-114"
129 SID_OTHER_ORGANIZATION = "S-1-5-1000"
130 SID_ALL_APP_PACKAGES = "S-1-15-2-1"
131 SID_ML_UNTRUSTED = "S-1-16-0"
132 SID_ML_LOW = "S-1-16-4096"
133 SID_ML_MEDIUM = "S-1-16-8192"
134 SID_ML_MEDIUM_PLUS = "S-1-16-8448"
135 SID_ML_HIGH = "S-1-16-12288"
136 SID_ML_SYSTEM = "S-1-16-16384"
137 SID_ML_PROTECTED_PROCESS = "S-1-16-20480"
138 SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = "S-1-18-1"
139 SID_SERVICE_ASSERTED_IDENTITY = "S-1-18-2"
140 SID_FRESH_PUBLIC_KEY_IDENTITY = "S-1-18-3"
141 SID_KEY_TRUST_IDENTITY = "S-1-18-4"
142 SID_KEY_PROPERTY_MFA = "S-1-18-5"
143 SID_KEY_PROPERTY_ATTESTATION = "S-1-18-6"
144
145
146 class SID(object):
147 """
148 A Windows security identifier. Represents a single principal, such a
149 user or a group, as a sequence of numbers consisting of the revision,
150 identifier authority, and a variable-length list of subauthorities.
151
152 See [MS-DTYP]: 2.4.2
153 """
154 def __init__(self, revision, identifier_authority, subauthorities):
155 #: Revision, should always be 1.
156 self.revision = revision
157 #: An integer representing the identifier authority.
158 self.identifier_authority = identifier_authority
159 #: A list of integers representing all subauthorities.
160 self.subauthorities = subauthorities
161
162 def __str__(self):
163 """
164 String representation, as specified in [MS-DTYP]: 2.4.2.1
165 """
166 if self.identifier_authority >= 2**32:
167 id_auth = '%#x' % (self.identifier_authority,)
168 else:
169 id_auth = self.identifier_authority
170 auths = [self.revision, id_auth] + self.subauthorities
171 return 'S-' + '-'.join(str(subauth) for subauth in auths)
172
173 def __repr__(self):
174 return 'SID(%r)' % (str(self),)
175
176 @classmethod
177 def from_bytes(cls, data, return_tail=False):
178 revision, subauth_count = struct.unpack('<BB', data[:2])
179 identifier_authority = struct.unpack('>Q', b'\x00\x00' + data[2:8])[0]
180 subauth_data = data[8:]
181 subauthorities = [struct.unpack('<L', subauth_data[4 * i : 4 * (i+1)])[0]
182 for i in range(subauth_count)]
183 sid = cls(revision, identifier_authority, subauthorities)
184 if return_tail:
185 return sid, subauth_data[4 * subauth_count :]
186 return sid
187
188
189 class ACE(object):
190 """
191 Represents a single access control entry.
192
193 See [MS-DTYP]: 2.4.4
194 """
195 HEADER_FORMAT = '<BBH'
196
197 def __init__(self, type_, flags, mask, sid, additional_data):
198 #: An integer representing the type of the ACE. One of the
199 #: ``ACE_TYPE_*`` constants. Corresponds to the ``AceType`` field
200 #: from [MS-DTYP] 2.4.4.1.
201 self.type = type_
202 #: An integer bitmask with ACE flags, corresponds to the
203 #: ``AceFlags`` field.
204 self.flags = flags
205 #: An integer representing the ``ACCESS_MASK`` as specified in
206 #: [MS-DTYP] 2.4.3.
207 self.mask = mask
208 #: The :class:`SID` of a trustee.
209 self.sid = sid
210 #: A dictionary of additional fields present in the ACE, depending
211 #: on the type. The following fields can be present:
212 #:
213 #: * ``flags``
214 #: * ``object_type``
215 #: * ``inherited_object_type``
216 #: * ``application_data``
217 #: * ``attribute_data``
218 self.additional_data = additional_data
219
220 def __repr__(self):
221 return "ACE(type=%#04x, flags=%#04x, mask=%#010x, sid=%s)" % (
222 self.type, self.flags, self.mask, self.sid,
223 )
224
225 @property
226 def isInheritOnly(self):
227 """Convenience property which indicates if this ACE is inherit
228 only, meaning that it doesn't apply to the object itself."""
229 return bool(self.flags & ACE_FLAG_INHERIT_ONLY)
230
231 @classmethod
232 def from_bytes(cls, data):
233 header_size = struct.calcsize(cls.HEADER_FORMAT)
234 header = data[:header_size]
235 type_, flags, size = struct.unpack(cls.HEADER_FORMAT, header)
236
237 assert len(data) >= size
238
239 body = data[header_size:size]
240 additional_data = {}
241
242 # In all ACE types, the mask immediately follows the header.
243 mask = struct.unpack('<I', body[:4])[0]
244 body = body[4:]
245
246 # All OBJECT-type ACEs contain additional flags, and two GUIDs as
247 # the following fields.
248 if type_ in (ACE_TYPE_ACCESS_ALLOWED_OBJECT,
249 ACE_TYPE_ACCESS_DENIED_OBJECT,
250 ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT,
251 ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT,
252 ACE_TYPE_SYSTEM_AUDIT_OBJECT,
253 ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT):
254 additional_data['flags'] = struct.unpack('<I', body[:4])[0]
255 additional_data['object_type'] = body[4:20]
256 additional_data['inherited_object_type'] = body[20:36]
257 body = body[36:]
258
259 # Then the SID in all types.
260 sid, body = SID.from_bytes(body, return_tail=True)
261
262 # CALLBACK-type ACEs (and for some obscure reason,
263 # SYSTEM_AUDIT_OBJECT) have a final tail of application data.
264 if type_ in (ACE_TYPE_ACCESS_ALLOWED_CALLBACK,
265 ACE_TYPE_ACCESS_DENIED_CALLBACK,
266 ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT,
267 ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT,
268 ACE_TYPE_SYSTEM_AUDIT_OBJECT,
269 ACE_TYPE_SYSTEM_AUDIT_CALLBACK,
270 ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT):
271 additional_data['application_data'] = body
272
273 # SYSTEM_RESOURCE_ATTRIBUTE ACEs have a tail of attribute data.
274 if type_ == ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE:
275 additional_data['attribute_data'] = body
276
277 return cls(type_, flags, mask, sid, additional_data)
278
279
280 class ACL(object):
281 """
282 Access control list, encapsulating a sequence of access control
283 entries.
284
285 See [MS-DTYP]: 2.4.5
286 """
287 HEADER_FORMAT = '<BBHHH'
288
289 def __init__(self, revision, aces):
290 #: Integer value of the revision.
291 self.revision = revision
292 #: List of :class:`ACE` instances.
293 self.aces = aces
294
295 def __repr__(self):
296 return "ACL(%r)" % (self.aces,)
297
298 @classmethod
299 def from_bytes(cls, data):
300 revision = None
301 aces = []
302
303 header_size = struct.calcsize(cls.HEADER_FORMAT)
304 header, remaining = data[:header_size], data[header_size:]
305 revision, sbz1, size, count, sbz2 = struct.unpack(cls.HEADER_FORMAT, header)
306
307 assert len(data) >= size
308
309 for i in range(count):
310 ace_size = struct.unpack('<H', remaining[2:4])[0]
311 ace_data, remaining = remaining[:ace_size], remaining[ace_size:]
312 aces.append(ACE.from_bytes(ace_data))
313
314 return cls(revision, aces)
315
316
317 class SecurityDescriptor(object):
318 """
319 Represents a security descriptor.
320
321 See [MS-DTYP]: 2.4.6
322 """
323
324 HEADER_FORMAT = '<BBHIIII'
325
326 def __init__(self, flags, owner, group, dacl, sacl):
327 #: Integer bitmask of control flags. Corresponds to the
328 #: ``Control`` field in [MS-DTYP] 2.4.6.
329 self.flags = flags
330 #: Instance of :class:`SID` representing the owner user.
331 self.owner = owner
332 #: Instance of :class:`SID` representing the owner group.
333 self.group = group
334 #: Instance of :class:`ACL` representing the discretionary access
335 #: control list, which specifies access restrictions of an object.
336 self.dacl = dacl
337 #: Instance of :class:`ACL` representing the system access control
338 #: list, which specifies audit logging of an object.
339 self.sacl = sacl
340
341 @classmethod
342 def from_bytes(cls, data):
343 owner = None
344 group = None
345 dacl = None
346 sacl = None
347
348 header = data[:struct.calcsize(cls.HEADER_FORMAT)]
349 (revision, sbz1, flags, owner_offset, group_offset, sacl_offset,
350 dacl_offset) = struct.unpack(cls.HEADER_FORMAT, header)
351
352 assert revision == 1
353 assert flags & SECURITY_DESCRIPTOR_SELF_RELATIVE
354 for offset in (owner_offset, group_offset, sacl_offset, dacl_offset):
355 assert 0 <= offset < len(data)
356
357 if owner_offset:
358 owner = SID.from_bytes(data[owner_offset:])
359 if group_offset:
360 group = SID.from_bytes(data[group_offset:])
361 if dacl_offset:
362 dacl = ACL.from_bytes(data[dacl_offset:])
363 if sacl_offset:
364 sacl = ACL.from_bytes(data[sacl_offset:])
365
366 return cls(flags, owner, group, dacl, sacl)
269269 STRUCTURE_FORMAT = "<HHHH"
270270 STRUCTURE_SIZE = struct.calcsize(STRUCTURE_FORMAT)
271271
272 @property
273 def isGuestSession(self):
274 return (self.session_flags & 0x0001) > 0 # SMB2_SESSION_FLAG_IS_GUEST
275
276 @property
277 def isAnonymousSession(self):
278 return (self.session_flags & 0x0002) > 0 # SMB2_SESSION_FLAG_IS_NULL
279
272280 def decode(self, message):
273281 assert message.command == SMB2_COM_SESSION_SETUP
274282
361369
362370 def prepare(self, message):
363371 buf = self.filename.encode('UTF-16LE')
372 filename_len = len(buf)
364373 if self.create_context_data:
365374 n = SMB2Message.HEADER_SIZE + self.STRUCTURE_SIZE + len(buf)
366375 if n % 8 != 0:
388397 self.create_disp,
389398 self.create_options,
390399 SMB2Message.HEADER_SIZE + self.STRUCTURE_SIZE, # NameOffset
391 len(self.filename)*2, # NameLength in bytes
400 filename_len, # Length of encoded filename in bytes
392401 create_context_offset, # CreateContextOffset
393402 len(self.create_context_data) # CreateContextLength
394403 ) + buf
114114 FILE_READ_EA = 0x08
115115 FILE_WRITE_EA = 0x10
116116 FILE_EXECUTE = 0x20
117 FILE_DELETE_CHILD = 0x40
117118 FILE_READ_ATTRIBUTES = 0x80
118119 FILE_WRITE_ATTRIBUTES = 0x0100
119120 DELETE = 0x010000
224225 SMB_FILE_ATTRIBUTE_READONLY = 0x01
225226 SMB_FILE_ATTRIBUTE_HIDDEN = 0x02
226227 SMB_FILE_ATTRIBUTE_SYSTEM = 0x04
227 SMB_FILE_ATTRIBUTE_VOLUME = 0x08
228 SMB_FILE_ATTRIBUTE_VOLUME = 0x08 # Unsupported for listPath() operations
228229 SMB_FILE_ATTRIBUTE_DIRECTORY = 0x10
229230 SMB_FILE_ATTRIBUTE_ARCHIVE = 0x20
231 # SMB_FILE_ATTRIBUTE_INCL_NORMAL is a special placeholder to include normal files
232 # with other search attributes for listPath() operations. It is not defined in the MS-CIFS specs.
233 SMB_FILE_ATTRIBUTE_INCL_NORMAL = 0x10000
234 # Do not use the following values for listPath() operations as they are not supported for SMB2
230235 SMB_SEARCH_ATTRIBUTE_READONLY = 0x0100
231236 SMB_SEARCH_ATTRIBUTE_HIDDEN = 0x0200
232237 SMB_SEARCH_ATTRIBUTE_SYSTEM = 0x0400
236241 # Bitmask for OptionalSupport field in SMB_COM_TREE_CONNECT_ANDX response
237242 SMB_TREE_CONNECTX_SUPPORT_SEARCH = 0x0001
238243 SMB_TREE_CONNECTX_SUPPORT_DFS = 0x0002
244
245 # Bitmask for security information fields, specified as
246 # AdditionalInformation in SMB2
247 # [MS-SMB]: 2.2.7.4
248 # [MS-SMB2]: 2.2.37
249 OWNER_SECURITY_INFORMATION = 0x00000001
250 GROUP_SECURITY_INFORMATION = 0x00000002
251 DACL_SECURITY_INFORMATION = 0x00000004
252 SACL_SECURITY_INFORMATION = 0x00000008
253 LABEL_SECURITY_INFORMATION = 0x00000010
254 ATTRIBUTE_SECURITY_INFORMATION = 0x00000020
255 SCOPE_SECURITY_INFORMATION = 0x00000040
256 BACKUP_SECURITY_INFORMATION = 0x00010000
11 import os, sys, struct, types, logging, binascii, time
22 from io import StringIO
33 from .smb_constants import *
4
4 from .strategy import DataFaultToleranceStrategy
55
66 # Set to True if you want to enable support for extended security. Required for Windows Vista and later
77 SUPPORT_EXTENDED_SECURITY = True
141141 self.parameters_data = b''
142142 self.data = b''
143143 self.payload = None
144
145 @property
146 def isAsync(self):
147 return bool(self.flags & SMB2_FLAGS_ASYNC_COMMAND)
144148
145149 @property
146150 def isReply(self):
370374 while offset < data_len:
371375 _s = message.data[offset:offset+2]
372376 if _s == b'\0\0':
373 self.domain = s.decode('UTF-16LE')
377 self.domain = DataFaultToleranceStrategy.data_bytes_decode(s)#.decode('UTF-16LE')
374378 break
375379 else:
376380 s += _s
12781282 - [MS-CIFS]: 2.2.4.39.1
12791283 """
12801284
1281 def __init__(self, echo_data = '', echo_count = 1):
1285 def __init__(self, echo_data = b'', echo_count = 1):
12821286 self.echo_count = echo_count
12831287 self.echo_data = echo_data
12841288
0 class DataStrategyBase():
1 DATABYTES_CODEC = 'UTF-16LE'
2
3
4 class DataFaultToleranceStrategy():
5 @staticmethod
6 def data_bytes_decode(databytes):
7 return databytes.decode(DataStrategyBase.DATABYTES_CODEC, 'ignore')
8
9
10 class DataStrategy():
11 @staticmethod
12 def data_bytes_decode(databytes):
13 return databytes.decode(DataStrategyBase.DATABYTES_CODEC)
14
4646
4747 #--------------------------------------------------------------------
4848 def __int__(self): return int(norm(self.v))
49
50 __index__ = __int__
4951
5052 #--------------------------------------------------------------------
5153 def __chr__(self): return chr(norm(self.v))
2222 #
2323 #====================================================================
2424
25 # MD4 validation data
26
27 md4_test= [
28 ('', 0x31d6cfe0d16ae931b73c59d7e0c089c0),
29 ("a", 0xbde52cb31de33e46245e05fbdbd6fb24),
30 ("abc", 0xa448017aaf21d8525fc10ae87aa6729d),
31 ("message digest", 0xd9130a8164549fe818874806e1c7014b),
32 ("abcdefghijklmnopqrstuvwxyz", 0xd79e1c308aa5bbcdeea8ed63df412da9),
33 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
34 0x043f8582f241db351ce627e153e7f0e4),
35 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
36 0xe33b4ddc9c38f2199c3e7b164fcc0536),
37 ]
3825
3926 #====================================================================
4027 from .U32 import U32
8168 dest.C = self.C
8269 dest.D = self.D
8370 dest.count = self.count
84 for i in range(self.count):
71 for i in range(int(self.count)):
8572 dest.buf[i] = self.buf[i]
8673
8774 return dest
8875
8976 #-----------------------------------------------------
9077 def update(self, str):
91
92 buf = []
93 for i in str: buf.append(ord(i))
78 if isinstance(str, bytes):
79 buf = list(str)
80 else:
81 buf = [ord(i) for i in str]
82
9483 ilen = U32(len(buf))
9584
9685 # check if the first length is out of range
197186 if (56 <= int(self.count)): padlen = U32(56 - int(self.count) + 64)
198187 else: padlen = U32(56 - int(self.count))
199188
200 temp.update(int_array2str(padding[:int(padlen)]))
189 temp.update(bytes(padding[:int(padlen)]))
201190
202191 s[0]= (oldlen1) & U32(0xFF)
203192 s[1]=((oldlen1) >> 8) & U32(0xFF)
207196 s[5]=((oldlen2) >> 8) & U32(0xFF)
208197 s[6]=((oldlen2) >> 16) & U32(0xFF)
209198 s[7]=((oldlen2) >> 24) & U32(0xFF)
210 temp.update(int_array2str(s))
199 temp.update(bytes(s))
211200
212201 res[ 0]= temp.A & U32(0xFF)
213202 res[ 1]=(temp.A >> 8) & U32(0xFF)
226215 res[14]=(temp.D >> 16) & U32(0xFF)
227216 res[15]=(temp.D >> 24) & U32(0xFF)
228217
229 return int_array2str(res)
218 return bytes(res)
230219
231220 #====================================================================
232221 # helpers
241230 def f3(a, b, c, d, k, s, X): return ROL(a + H(b, c, d) + X[k] + U32(0x6ed9eba1), s)
242231
243232 #--------------------------------------------------------------------
244 # helper function
245 def int_array2str(array):
246 str = ''
247 for i in array:
248 str = str + chr(i)
249 return str
250
251 #--------------------------------------------------------------------
252233 # To be able to use md4.new() instead of md4.MD4()
253234 new = MD4
0
1 def RC4_encrypt(key, data):
2 S = list(range(256))
3 j = 0
4
5 key_len = len(key)
6 for i in list(range(256)):
7 j = (j + S[i] + key[i % key_len]) % 256
8 S[i], S[j] = S[j], S[i]
9
10 j = 0
11 y = 0
12 out = []
13
14 for char in data:
15 j = (j + 1) % 256
16 y = (y + S[j]) % 256
17 S[j], S[y] = S[y], S[j]
18
19 out.append(char ^ S[(S[j] + S[y]) % 256])
20
21 return bytes(out)
0 #!/usr/bin/python
10 __author__ = 'Thomas Dixon'
21 __license__ = 'MIT'
32
00
1 from nose2.tools.decorators import with_teardown
12 from smb.SMBConnection import SMBConnection
3 from smb import smb_structs
24 from .util import getConnectionInfo
3 from nose.tools import with_setup
4 from smb import smb_structs
55
6 conn = None
6 conn, conn2, conn3 = None, None, None
77
88 def teardown_func():
9 global conn
10 conn.close()
9 global conn, conn2, conn3
10 if conn:
11 conn.close()
12 if conn2:
13 conn2.close()
14 if conn3:
15 conn3.close();
1116
12 @with_setup(teardown = teardown_func)
17 @with_teardown(teardown_func)
1318 def test_NTLMv1_auth_SMB1():
14 global conn
19 global conn, conn2, conn3
1520 smb_structs.SUPPORT_SMB2 = False
1621 info = getConnectionInfo()
17 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False)
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
1823 assert conn.connect(info['server_ip'], info['server_port'])
1924
20 @with_setup(teardown = teardown_func)
21 def test_NTLMv2_auth_SMB1():
22 global conn
25 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
26 assert not conn2.connect(info['server_ip'], info['server_port'])
27
28 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
29 assert not conn3.connect(info['server_ip'], info['server_port'])
30
31 @with_teardown(teardown_func)
32 def test_NTLMv1_auth_SMB1_callable_password():
33 global conn, conn2, conn3
2334 smb_structs.SUPPORT_SMB2 = False
2435 info = getConnectionInfo()
25 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
36 conn = SMBConnection(info['user'], lambda: info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
2637 assert conn.connect(info['server_ip'], info['server_port'])
2738
28 @with_setup(teardown = teardown_func)
39 conn2 = SMBConnection(info['user'], lambda: 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
40 assert not conn2.connect(info['server_ip'], info['server_port'])
41
42 conn3 = SMBConnection('INVALIDUSER', lambda: 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
43 assert not conn3.connect(info['server_ip'], info['server_port'])
44
45 @with_teardown(teardown_func)
46 def test_NTLMv2_auth_SMB1():
47 global conn, conn2, conn3
48 smb_structs.SUPPORT_SMB2 = False
49 info = getConnectionInfo()
50 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
51 assert conn.connect(info['server_ip'], info['server_port'])
52
53 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
54 assert not conn2.connect(info['server_ip'], info['server_port'])
55
56 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
57 assert not conn3.connect(info['server_ip'], info['server_port'])
58
59 @with_teardown(teardown_func)
2960 def test_NTLMv1_auth_SMB2():
30 global conn
61 global conn, conn2, conn3
3162 smb_structs.SUPPORT_SMB2 = True
3263 info = getConnectionInfo()
33 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False)
64 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
3465 assert conn.connect(info['server_ip'], info['server_port'])
3566
36 @with_setup(teardown = teardown_func)
67 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
68 assert not conn2.connect(info['server_ip'], info['server_port'])
69
70 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True)
71 assert not conn3.connect(info['server_ip'], info['server_port'])
72
73 @with_teardown(teardown_func)
3774 def test_NTLMv2_auth_SMB2():
38 global conn
75 global conn, conn2, conn3
3976 smb_structs.SUPPORT_SMB2 = True
4077 info = getConnectionInfo()
41 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
78 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
4279 assert conn.connect(info['server_ip'], info['server_port'])
80
81 conn2 = SMBConnection(info['user'], 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
82 assert not conn2.connect(info['server_ip'], info['server_port'])
83
84 conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
85 assert not conn3.connect(info['server_ip'], info['server_port'])
00 # -*- coding: utf-8 -*-
11
22 import os, time, random
3 from nose2.tools.decorators import with_setup, with_teardown
34 from smb.SMBConnection import SMBConnection
5 from smb import smb_structs
46 from .util import getConnectionInfo
5 from nose.tools import with_setup
6 from smb import smb_structs
77
88 conn = None
99
1212 smb_structs.SUPPORT_SMB2 = False
1313
1414 info = getConnectionInfo()
15 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
15 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1616 assert conn.connect(info['server_ip'], info['server_port'])
1717
1818 def setup_func_SMB2():
2020 smb_structs.SUPPORT_SMB2 = True
2121
2222 info = getConnectionInfo()
23 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
23 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2424 assert conn.connect(info['server_ip'], info['server_port'])
2525
2626 def teardown_func():
2727 global conn
2828 conn.close()
2929
30 @with_setup(setup_func_SMB1, teardown_func)
30 @with_setup(setup_func_SMB1)
31 @with_teardown(teardown_func)
3132 def test_english_directory_SMB1():
3233 global conn
3334
4445 names = [e.filename for e in entries]
4546 assert os.path.basename(path.replace('/', os.sep)) not in names
4647
47 @with_setup(setup_func_SMB2, teardown_func)
48 @with_setup(setup_func_SMB2)
49 @with_teardown(teardown_func)
4850 def test_english_directory_SMB2():
4951 global conn
5052
6163 names = [e.filename for e in entries]
6264 assert os.path.basename(path.replace('/', os.sep)) not in names
6365
64 @with_setup(setup_func_SMB1, teardown_func)
66 @with_setup(setup_func_SMB1)
67 @with_teardown(teardown_func)
6568 def test_unicode_directory_SMB1():
6669 global conn
6770
7881 names = [e.filename for e in entries]
7982 assert os.path.basename(path.replace('/', os.sep)) not in names
8083
81 @with_setup(setup_func_SMB2, teardown_func)
84 @with_setup(setup_func_SMB2)
85 @with_teardown(teardown_func)
8286 def test_unicode_directory_SMB2():
8387 global conn
8488
00
11 import random
2 from nose2.tools.decorators import with_setup, with_teardown
23 from smb.SMBConnection import SMBConnection
34 from .util import getConnectionInfo
4 from nose.tools import with_setup
55
66 conn = None
77
88 def setup_func():
99 global conn
1010 info = getConnectionInfo()
11 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
11 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1212 assert conn.connect(info['server_ip'], info['server_port'])
1313
1414 def teardown_func():
1515 global conn
1616 conn.close()
1717
18 @with_setup(setup_func, teardown_func)
18 @with_setup(setup_func)
19 @with_teardown(teardown_func)
1920 def test_echo():
2021 global conn
2122
00 # -*- coding: utf-8 -*-
11
2 from nose2.tools.decorators import with_setup, with_teardown
23 from smb.SMBConnection import SMBConnection
4 from smb.smb_constants import *
5 from smb import smb_structs
36 from .util import getConnectionInfo
4 from nose.tools import with_setup
5 from smb import smb_structs
67
78 conn = None
89
1011 global conn
1112 smb_structs.SUPPORT_SMB2 = False
1213 info = getConnectionInfo()
13 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
14 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1415 assert conn.connect(info['server_ip'], info['server_port'])
1516
1617 def setup_func_SMB2():
1718 global conn
1819 smb_structs.SUPPORT_SMB2 = True
1920 info = getConnectionInfo()
20 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
21 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2122 assert conn.connect(info['server_ip'], info['server_port'])
2223
2324 def teardown_func():
2425 global conn
2526 conn.close()
2627
27 @with_setup(setup_func_SMB1, teardown_func)
28 @with_setup(setup_func_SMB1)
29 @with_teardown(teardown_func)
2830 def test_listPath_SMB1():
2931 global conn
3032 results = conn.listPath('smbtest', '/')
3537 assert ( 'Implementing CIFS - SMB.html', False ) in filenames # Test long English file names
3638 assert ( 'rfc1001.txt', False ) in filenames # Test short English file names
3739
38 @with_setup(setup_func_SMB1, teardown_func)
40 @with_setup(setup_func_SMB1)
41 @with_teardown(teardown_func)
3942 def test_listSubPath_SMB1():
4043 global conn
4144 results = conn.listPath('smbtest', '/Test Folder with Long Name/')
4447 assert ( 'Test Folder', True ) in filenames
4548 assert ( '子文件夹', True ) in filenames
4649
47 @with_setup(setup_func_SMB2, teardown_func)
50 @with_setup(setup_func_SMB1)
51 @with_teardown(teardown_func)
52 def test_listPathWithManyFiles_SMB1():
53 global conn
54 results = conn.listPath('smbtest', '/RFC Archive/')
55 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
56 assert len(list(filenames))==999
57
58 @with_setup(setup_func_SMB2)
59 @with_teardown(teardown_func)
4860 def test_listPath_SMB2():
4961 global conn
5062 results = conn.listPath('smbtest', '/')
5567 assert ( 'Implementing CIFS - SMB.html', False ) in filenames # Test long English file names
5668 assert ( 'rfc1001.txt', False ) in filenames # Test short English file names
5769
58 @with_setup(setup_func_SMB2, teardown_func)
70 @with_setup(setup_func_SMB2)
71 @with_teardown(teardown_func)
5972 def test_listSubPath_SMB2():
6073 global conn
6174 results = conn.listPath('smbtest', '/Test Folder with Long Name/')
6376 assert ( 'Test File.txt', False ) in filenames
6477 assert ( 'Test Folder', True ) in filenames
6578 assert ( '子文件夹', True ) in filenames
79
80 @with_setup(setup_func_SMB2)
81 @with_teardown(teardown_func)
82 def test_listPathWithManyFiles_SMB2():
83 global conn
84 results = conn.listPath('smbtest', '/RFC Archive/')
85 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
86 assert len(list(filenames))==999
87
88 @with_setup(setup_func_SMB1)
89 @with_teardown(teardown_func)
90 def test_listPathFilterForDirectory_SMB1():
91 global conn
92 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_DIRECTORY)
93 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
94 assert len(list(filenames)) > 0
95 for f, isDirectory in filenames:
96 assert isDirectory
97
98 @with_setup(setup_func_SMB2)
99 @with_teardown(teardown_func)
100 def test_listPathFilterForDirectory_SMB2():
101 global conn
102 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_DIRECTORY)
103 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
104 assert len(list(filenames)) > 0
105 for f, isDirectory in filenames:
106 assert isDirectory
107
108 @with_setup(setup_func_SMB1)
109 @with_teardown(teardown_func)
110 def test_listPathFilterForFiles_SMB1():
111 global conn
112 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL)
113 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
114 assert len(list(filenames)) > 0
115 for f, isDirectory in filenames:
116 assert not isDirectory
117
118 @with_setup(setup_func_SMB2)
119 @with_teardown(teardown_func)
120 def test_listPathFilterForFiles_SMB2():
121 global conn
122 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL)
123 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
124 assert len(list(filenames)) > 0
125 for f, isDirectory in filenames:
126 assert not isDirectory
127
128
129 @with_setup(setup_func_SMB1)
130 @with_teardown(teardown_func)
131 def test_listPathFilterPattern_SMB1():
132 global conn
133 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = 'Test*')
134 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
135 assert len(filenames) == 2
136 assert ( u'Test File.txt', False ) in filenames
137 assert ( u'Test Folder', True ) in filenames
138 assert ( u'子文件夹', True ) not in filenames
139
140 @with_setup(setup_func_SMB2)
141 @with_teardown(teardown_func)
142 def test_listPathFilterPattern_SMB2():
143 global conn
144 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = 'Test*')
145 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
146 assert len(filenames) == 2
147 assert ( u'Test File.txt', False ) in filenames
148 assert ( u'Test Folder', True ) in filenames
149 assert ( u'子文件夹', True ) not in filenames
150
151 @with_setup(setup_func_SMB1)
152 @with_teardown(teardown_func)
153 def test_listPathFilterUnicodePattern_SMB1():
154 global conn
155 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = u'*件夹')
156 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
157 assert len(filenames) == 1
158 assert ( u'Test File.txt', False ) not in filenames
159 assert ( u'Test Folder', True ) not in filenames
160 assert ( u'子文件夹', True ) in filenames
161
162 @with_setup(setup_func_SMB2)
163 @with_teardown(teardown_func)
164 def test_listPathFilterUnicodePattern_SMB2():
165 global conn
166 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = u'*件夹')
167 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
168 assert len(filenames) == 1
169 assert ( u'Test File.txt', False ) not in filenames
170 assert ( u'Test Folder', True ) not in filenames
171 assert ( u'子文件夹', True ) in filenames
00
1 from nose2.tools.decorators import with_setup, with_teardown
12 from smb.SMBConnection import SMBConnection
3 from smb import smb_structs
24 from .util import getConnectionInfo
3 from nose.tools import with_setup
4 from smb import smb_structs
55
66 conn = None
77
99 global conn
1010 smb_structs.SUPPORT_SMB2 = False
1111 info = getConnectionInfo()
12 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
12 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1313 assert conn.connect(info['server_ip'], info['server_port'])
1414
1515 def setup_func_SMB2():
1616 global conn
1717 smb_structs.SUPPORT_SMB2 = True
1818 info = getConnectionInfo()
19 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
19 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2020 assert conn.connect(info['server_ip'], info['server_port'])
2121
2222 def teardown_func():
2323 global conn
2424 conn.close()
2525
26 @with_setup(setup_func_SMB1, teardown_func)
26 @with_setup(setup_func_SMB1)
27 @with_teardown(teardown_func)
2728 def test_listshares_SMB1():
2829 global conn
2930 results = conn.listShares()
3031 assert 'smbtest' in [r.name.lower() for r in results]
3132
32 @with_setup(setup_func_SMB2, teardown_func)
33 @with_setup(setup_func_SMB2)
34 @with_teardown(teardown_func)
3335 def test_listshares_SMB2():
3436 global conn
3537 results = conn.listShares()
00
1 from nose2.tools.decorators import with_setup, with_teardown
12 from smb.SMBConnection import SMBConnection
3 from smb import smb_structs
24 from .util import getConnectionInfo
3 from nose.tools import with_setup
4 from smb import smb_structs
55
66 conn = None
77
99 global conn
1010 smb_structs.SUPPORT_SMB2 = False
1111 info = getConnectionInfo()
12 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
12 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1313 assert conn.connect(info['server_ip'], info['server_port'])
1414
1515 def setup_func_SMB2():
1616 global conn
1717 smb_structs.SUPPORT_SMB2 = True
1818 info = getConnectionInfo()
19 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
19 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2020 assert conn.connect(info['server_ip'], info['server_port'])
2121
2222 def teardown_func():
2323 global conn
2424 conn.close()
2525
26 @with_setup(setup_func_SMB1, teardown_func)
26 @with_setup(setup_func_SMB1)
27 @with_teardown(teardown_func)
2728 def test_listsnapshots_SMB1():
2829 global conn
2930 results = conn.listSnapshots('smbtest', '/rfc1001.txt')
3031 assert len(results) > 0
3132
32 @with_setup(setup_func_SMB2, teardown_func)
33 @with_setup(setup_func_SMB2)
34 @with_teardown(teardown_func)
3335 def test_listsnapshots_SMB2():
3436 global conn
3537 results = conn.listSnapshots('smbtest', '/rfc1001.txt')
11
22 import os, time, random
33 from io import BytesIO
4 from nose2.tools.decorators import with_setup, with_teardown
45 from smb.SMBConnection import SMBConnection
6 from smb import smb_structs
57 from .util import getConnectionInfo
6 from nose.tools import with_setup
7 from smb import smb_structs
88
99 conn = None
1010
1212 global conn
1313 smb_structs.SUPPORT_SMB2 = False
1414 info = getConnectionInfo()
15 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
15 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
1616 assert conn.connect(info['server_ip'], info['server_port'])
1717
1818 def setup_func_SMB2():
1919 global conn
2020 smb_structs.SUPPORT_SMB2 = True
2121 info = getConnectionInfo()
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2323 assert conn.connect(info['server_ip'], info['server_port'])
2424
2525 def teardown_func():
2626 global conn
2727 conn.close()
2828
29 @with_setup(setup_func_SMB1, teardown_func)
29 @with_setup(setup_func_SMB1)
30 @with_teardown(teardown_func)
3031 def test_rename_english_file_SMB1():
3132 global conn
3233
4950
5051 conn.deleteFiles('smbtest', new_path)
5152
52 @with_setup(setup_func_SMB2, teardown_func)
53 @with_setup(setup_func_SMB2)
54 @with_teardown(teardown_func)
5355 def test_rename_english_file_SMB2():
5456 global conn
5557
7274
7375 conn.deleteFiles('smbtest', new_path)
7476
75 @with_setup(setup_func_SMB1, teardown_func)
77 @with_setup(setup_func_SMB1)
78 @with_teardown(teardown_func)
7679 def test_rename_unicode_file_SMB1():
7780 global conn
7881
9598
9699 conn.deleteFiles('smbtest', new_path)
97100
98 @with_setup(setup_func_SMB2, teardown_func)
101 @with_setup(setup_func_SMB2)
102 @with_teardown(teardown_func)
99103 def test_rename_unicode_file_SMB2():
100104 global conn
101105
118122
119123 conn.deleteFiles('smbtest', new_path)
120124
121 @with_setup(setup_func_SMB1, teardown_func)
125 @with_setup(setup_func_SMB1)
126 @with_teardown(teardown_func)
122127 def test_rename_english_directory_SMB1():
123128 global conn
124129
141146
142147 conn.deleteDirectory('smbtest', new_path)
143148
144 @with_setup(setup_func_SMB2, teardown_func)
149 @with_setup(setup_func_SMB2)
150 @with_teardown(teardown_func)
145151 def test_rename_english_directory_SMB2():
146152 global conn
147153
164170
165171 conn.deleteDirectory('smbtest', new_path)
166172
167 @with_setup(setup_func_SMB1, teardown_func)
173 @with_setup(setup_func_SMB1)
174 @with_teardown(teardown_func)
168175 def test_rename_unicode_directory_SMB1():
169176 global conn
170177
187194
188195 conn.deleteDirectory('smbtest', new_path)
189196
190 @with_setup(setup_func_SMB2, teardown_func)
197 @with_setup(setup_func_SMB2)
198 @with_teardown(teardown_func)
191199 def test_rename_unicode_directory_SMB2():
192200 global conn
193201
11
22 import os, tempfile
33 from io import BytesIO
4 from nose2.tools.decorators import with_setup, with_teardown
45 from smb.SMBConnection import SMBConnection
6 from smb import smb_structs
57 from .util import getConnectionInfo
6 from nose.tools import with_setup
7 from smb import smb_structs
88
99 try:
1010 import hashlib
1919 global conn
2020 smb_structs.SUPPORT_SMB2 = False
2121 info = getConnectionInfo()
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
22 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2323 assert conn.connect(info['server_ip'], info['server_port'])
2424
2525 def setup_func_SMB2():
2626 global conn
2727 smb_structs.SUPPORT_SMB2 = True
2828 info = getConnectionInfo()
29 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
29 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
3030 assert conn.connect(info['server_ip'], info['server_port'])
3131
3232 def teardown_func():
3333 global conn
3434 conn.close()
3535
36 @with_setup(setup_func_SMB1, teardown_func)
36 @with_setup(setup_func_SMB1)
37 @with_teardown(teardown_func)
3738 def test_retr_multiplereads_SMB1():
3839 # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes)
3940 global conn
4748
4849 temp_fh.close()
4950
50 @with_setup(setup_func_SMB2, teardown_func)
51 @with_setup(setup_func_SMB2)
52 @with_teardown(teardown_func)
5153 def test_retr_multiplereads_SMB2():
5254 # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes)
5355 global conn
6163
6264 temp_fh.close()
6365
64 @with_setup(setup_func_SMB1, teardown_func)
66 @with_setup(setup_func_SMB1)
67 @with_teardown(teardown_func)
6568 def test_retr_longfilename_SMB1():
6669 # Test file retrieval that has a long English filename
6770 global conn
7578
7679 temp_fh.close()
7780
78 @with_setup(setup_func_SMB2, teardown_func)
81 @with_setup(setup_func_SMB2)
82 @with_teardown(teardown_func)
7983 def test_retr_longfilename_SMB2():
8084 # Test file retrieval that has a long English filename
8185 global conn
8993
9094 temp_fh.close()
9195
92 @with_setup(setup_func_SMB1, teardown_func)
96 @with_setup(setup_func_SMB1)
97 @with_teardown(teardown_func)
9398 def test_retr_unicodefilename_SMB1():
9499 # Test file retrieval that has a long non-English filename inside a folder with a non-English name
95100 global conn
103108
104109 temp_fh.close()
105110
106 @with_setup(setup_func_SMB2, teardown_func)
111 @with_setup(setup_func_SMB2)
112 @with_teardown(teardown_func)
107113 def test_retr_unicodefilename_SMB2():
108114 # Test file retrieval that has a long non-English filename inside a folder with a non-English name
109115 global conn
117123
118124 temp_fh.close()
119125
120 @with_setup(setup_func_SMB1, teardown_func)
126 @with_setup(setup_func_SMB1)
127 @with_teardown(teardown_func)
121128 def test_retr_offset_SMB1():
122129 # Test file retrieval from offset to EOF
123130 global conn
131138
132139 temp_fh.close()
133140
134 @with_setup(setup_func_SMB2, teardown_func)
141 @with_setup(setup_func_SMB2)
142 @with_teardown(teardown_func)
135143 def test_retr_offset_SMB2():
136144 # Test file retrieval from offset to EOF
137145 global conn
145153
146154 temp_fh.close()
147155
148 @with_setup(setup_func_SMB1, teardown_func)
156 @with_setup(setup_func_SMB1)
157 @with_teardown(teardown_func)
149158 def test_retr_offset_and_biglimit_SMB1():
150159 # Test file retrieval from offset with a big max_length
151160 global conn
159168
160169 temp_fh.close()
161170
162 @with_setup(setup_func_SMB2, teardown_func)
171 @with_setup(setup_func_SMB2)
172 @with_teardown(teardown_func)
163173 def test_retr_offset_and_biglimit_SMB2():
164174 # Test file retrieval from offset with a big max_length
165175 global conn
173183
174184 temp_fh.close()
175185
176 @with_setup(setup_func_SMB1, teardown_func)
186 @with_setup(setup_func_SMB1)
187 @with_teardown(teardown_func)
177188 def test_retr_offset_and_smalllimit_SMB1():
178189 # Test file retrieval from offset with a small max_length
179190 global conn
187198
188199 temp_fh.close()
189200
190 @with_setup(setup_func_SMB2, teardown_func)
201 @with_setup(setup_func_SMB2)
202 @with_teardown(teardown_func)
191203 def test_retr_offset_and_smalllimit_SMB2():
192204 # Test file retrieval from offset with a small max_length
193205 global conn
201213
202214 temp_fh.close()
203215
204 @with_setup(setup_func_SMB1, teardown_func)
216 @with_setup(setup_func_SMB1)
217 @with_teardown(teardown_func)
205218 def test_retr_offset_and_zerolimit_SMB1():
206219 # Test file retrieval from offset to EOF with max_length=0
207220 global conn
215228
216229 temp_fh.close()
217230
218 @with_setup(setup_func_SMB2, teardown_func)
231 @with_setup(setup_func_SMB2)
232 @with_teardown(teardown_func)
219233 def test_retr_offset_and_zerolimit_SMB2():
220234 # Test file retrieval from offset to EOF with max_length=0
221235 global conn
11
22 import os, tempfile, random, time
33 from io import BytesIO
4 from nose2.tools.decorators import with_setup, with_teardown
45 from smb.SMBConnection import SMBConnection
6 from smb import smb_structs
57 from .util import getConnectionInfo
6 from nose.tools import with_setup
7 from smb import smb_structs
88
99 try:
1010 import hashlib
2424 smb_structs.SUPPORT_SMB2 = False
2525
2626 info = getConnectionInfo()
27 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
27 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
2828 assert conn.connect(info['server_ip'], info['server_port'])
2929
3030 def setup_func_SMB2():
3232 smb_structs.SUPPORT_SMB2 = True
3333
3434 info = getConnectionInfo()
35 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
35 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True, is_direct_tcp = True)
3636 assert conn.connect(info['server_ip'], info['server_port'])
3737
3838 def teardown_func():
4040 conn.close()
4141
4242
43 @with_setup(setup_func_SMB1, teardown_func)
43 @with_setup(setup_func_SMB1)
44 @with_teardown(teardown_func)
4445 def test_store_long_filename_SMB1():
4546 filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
4647
6364 conn.deleteFiles('smbtest', filename)
6465
6566
66 @with_setup(setup_func_SMB2, teardown_func)
67 @with_setup(setup_func_SMB2)
68 @with_teardown(teardown_func)
6769 def test_store_long_filename_SMB2():
6870 filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
6971
8688 conn.deleteFiles('smbtest', filename)
8789
8890
89 @with_setup(setup_func_SMB1, teardown_func)
91 @with_setup(setup_func_SMB1)
92 @with_teardown(teardown_func)
9093 def test_store_unicode_filename_SMB1():
9194 filename = os.sep + '上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
9295
109112 conn.deleteFiles('smbtest', filename)
110113
111114
112 @with_setup(setup_func_SMB2, teardown_func)
115 @with_setup(setup_func_SMB2)
116 @with_teardown(teardown_func)
113117 def test_store_unicode_filename_SMB2():
114118 filename = os.sep + '上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
115119
+0
-77
python3/tests/DirectSMBTwistedTests/test_auth.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from smb import smb_structs
5 from .util import getConnectionInfo
6
7
8 class AuthFactory(SMBProtocolFactory):
9
10 def __init__(self, *args, **kwargs):
11 SMBProtocolFactory.__init__(self, *args, **kwargs)
12 self.d = defer.Deferred()
13 self.d.addBoth(self.testDone)
14
15 def testDone(self, r):
16 if self.instance:
17 self.instance.transport.loseConnection()
18 return r
19
20 def onAuthOK(self):
21 self.d.callback(True)
22
23 def onAuthFailed(self):
24 self.d.callback(False)
25
26
27 @deferred(timeout=5.0)
28 def test_NTLMv1_auth_SMB1():
29 def result(auth_passed):
30 assert auth_passed
31
32 smb_structs.SUPPORT_SMB2 = False
33 info = getConnectionInfo()
34 factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False)
35 factory.d.addCallback(result)
36 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
37 return factory.d
38
39
40 @deferred(timeout=5.0)
41 def test_NTLMv2_auth_SMB1():
42 def result(auth_passed):
43 assert auth_passed
44
45 smb_structs.SUPPORT_SMB2 = False
46 info = getConnectionInfo()
47 factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
48 factory.d.addCallback(result)
49 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
50 return factory.d
51
52
53 @deferred(timeout=5.0)
54 def test_NTLMv1_auth_SMB2():
55 def result(auth_passed):
56 assert auth_passed
57
58 smb_structs.SUPPORT_SMB2 = True
59 info = getConnectionInfo()
60 factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False)
61 factory.d.addCallback(result)
62 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
63 return factory.d
64
65
66 @deferred(timeout=5.0)
67 def test_NTLMv2_auth_SMB2():
68 def result(auth_passed):
69 assert auth_passed
70
71 smb_structs.SUPPORT_SMB2 = True
72 info = getConnectionInfo()
73 factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
74 factory.d.addCallback(result)
75 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
76 return factory.d
+0
-99
python3/tests/DirectSMBTwistedTests/test_createdeletedirectory.py less more
0 # -*- coding: utf-8 -*-
1
2 import os, random, time
3 from nose.twistedtools import reactor, deferred
4 from twisted.internet import defer
5 from smb.SMBProtocol import SMBProtocolFactory
6 from smb import smb_structs
7 from .util import getConnectionInfo
8
9
10 class DirectoryFactory(SMBProtocolFactory):
11
12 def __init__(self, *args, **kwargs):
13 SMBProtocolFactory.__init__(self, *args, **kwargs)
14 self.d = defer.Deferred()
15 self.d.addBoth(self.testDone)
16 self.service_name = ''
17 self.path = ''
18
19 def testDone(self, r):
20 if self.instance:
21 self.instance.transport.loseConnection()
22 return r
23
24 def createDone(self, result):
25 d = self.listPath(self.service_name, os.path.dirname(self.path.replace('/', os.sep)))
26 d.addCallback(self.listComplete)
27 d.addErrback(self.d.errback)
28
29 def listComplete(self, entries):
30 names = [e.filename for e in entries]
31 assert os.path.basename(self.path.replace('/', os.sep)) in names
32
33 d = self.deleteDirectory(self.service_name, self.path)
34 d.addCallback(self.deleteDone)
35 d.addErrback(self.d.errback)
36
37 def deleteDone(self, result):
38 d = self.listPath(self.service_name, os.path.dirname(self.path.replace('/', os.sep)))
39 d.addCallback(self.list2Complete)
40 d.addErrback(self.d.errback)
41
42 def list2Complete(self, entries):
43 names = [e.filename for e in entries]
44 assert os.path.basename(self.path.replace('/', os.sep)) not in names
45 self.d.callback(True)
46
47 def onAuthOK(self):
48 d = self.createDirectory(self.service_name, self.path)
49 d.addCallback(self.createDone)
50 d.addErrback(self.d.errback)
51
52 def onAuthFailed(self):
53 self.d.errback('Auth failed')
54
55
56 @deferred(timeout=15.0)
57 def test_english_directory_SMB1():
58 info = getConnectionInfo()
59 smb_structs.SUPPORT_SMB2 = False
60
61 factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
62 factory.service_name = 'smbtest'
63 factory.path = os.sep + 'TestDir %d-%d' % ( time.time(), random.randint(0, 1000) )
64 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
65 return factory.d
66
67 @deferred(timeout=15.0)
68 def test_english_directory_SMB2():
69 info = getConnectionInfo()
70 smb_structs.SUPPORT_SMB2 = True
71
72 factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
73 factory.service_name = 'smbtest'
74 factory.path = os.sep + 'TestDir %d-%d' % ( time.time(), random.randint(0, 1000) )
75 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
76 return factory.d
77
78 @deferred(timeout=15.0)
79 def test_unicode_directory_SMB1():
80 info = getConnectionInfo()
81 smb_structs.SUPPORT_SMB2 = False
82
83 factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
84 factory.service_name = 'smbtest'
85 factory.path = os.sep + '文件夹创建 %d-%d' % ( time.time(), random.randint(0, 1000) )
86 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
87 return factory.d
88
89 @deferred(timeout=15.0)
90 def test_unicode_directory_SMB2():
91 info = getConnectionInfo()
92 smb_structs.SUPPORT_SMB2 = True
93
94 factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
95 factory.service_name = 'smbtest'
96 factory.path = os.sep + '文件夹创建 %d-%d' % ( time.time(), random.randint(0, 1000) )
97 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
98 return factory.d
+0
-39
python3/tests/DirectSMBTwistedTests/test_echo.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from .util import getConnectionInfo
5
6
7 class EchoFactory(SMBProtocolFactory):
8
9 def __init__(self, *args, **kwargs):
10 SMBProtocolFactory.__init__(self, *args, **kwargs)
11 self.d = defer.Deferred()
12 self.d.addBoth(self.testDone)
13 self.echo_data = 'This is an echo test'
14
15 def testDone(self, r):
16 if self.instance:
17 self.instance.transport.loseConnection()
18 return r
19
20 def onAuthOK(self):
21 def cb(data):
22 assert data == self.echo_data
23 self.d.callback(True)
24
25 d = self.echo(self.echo_data)
26 d.addCallback(cb)
27 d.addErrback(self.d.errback)
28
29 def onAuthFailed(self):
30 self.d.errback('Auth failed')
31
32
33 @deferred(timeout=15.0)
34 def test_echo():
35 info = getConnectionInfo()
36 factory = EchoFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
37 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
38 return factory.d
+0
-56
python3/tests/DirectSMBTwistedTests/test_listpath.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from smb import smb_structs
5 from .util import getConnectionInfo
6
7
8 class ListPathFactory(SMBProtocolFactory):
9
10 def __init__(self, *args, **kwargs):
11 SMBProtocolFactory.__init__(self, *args, **kwargs)
12 self.d = defer.Deferred()
13 self.d.addBoth(self.testDone)
14
15 def testDone(self, r):
16 if self.instance:
17 self.instance.transport.loseConnection()
18 return r
19
20 def onAuthOK(self):
21 def cb(results):
22 filenames = [( r.filename, r.isDirectory ) for r in results]
23 assert ( '\u6d4b\u8bd5\u6587\u4ef6\u5939', True ) in filenames # Test non-English folder names
24 assert ( 'Test Folder with Long Name', True ) in filenames # Test long English folder names
25 assert ( 'TestDir1', True ) in filenames # Test short English folder names
26 assert ( 'Implementing CIFS - SMB.html', False ) in filenames # Test long English file names
27 assert ( 'rfc1001.txt', False ) in filenames # Test short English file names
28
29 self.d.callback(True)
30
31 d = self.listPath('smbtest', '/', timeout = 15)
32 d.addCallback(cb)
33 d.addErrback(self.d.errback)
34
35 def onAuthFailed(self):
36 self.d.errback('Auth failed')
37
38
39 @deferred(timeout=15.0)
40 def test_listPath_SMB1():
41 info = getConnectionInfo()
42 smb_structs.SUPPORT_SMB2 = False
43
44 factory = ListPathFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
45 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
46 return factory.d
47
48 @deferred(timeout=15.0)
49 def test_listPath_SMB2():
50 info = getConnectionInfo()
51 smb_structs.SUPPORT_SMB2 = True
52
53 factory = ListPathFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
54 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
55 return factory.d
+0
-51
python3/tests/DirectSMBTwistedTests/test_listshares.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from smb import smb_structs
5 from .util import getConnectionInfo
6
7
8 class ListSharesFactory(SMBProtocolFactory):
9
10 def __init__(self, *args, **kwargs):
11 SMBProtocolFactory.__init__(self, *args, **kwargs)
12 self.d = defer.Deferred()
13 self.d.addBoth(self.testDone)
14
15 def testDone(self, r):
16 if self.instance:
17 self.instance.transport.loseConnection()
18 return r
19
20 def onAuthOK(self):
21 def cb(results):
22 assert 'smbtest' in [r.name.lower() for r in results]
23 self.d.callback(True)
24 self.instance.transport.loseConnection()
25
26 d = self.listShares(timeout = 15)
27 d.addCallback(cb)
28 d.addErrback(self.d.errback)
29
30 def onAuthFailed(self):
31 self.d.errback('Auth failed')
32
33
34 @deferred(timeout=15.0)
35 def test_listshares_SMB1():
36 info = getConnectionInfo()
37 smb_structs.SUPPORT_SMB2 = False
38
39 factory = ListSharesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
40 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
41 return factory.d
42
43 @deferred(timeout=15.0)
44 def test_listshares_SMB2():
45 info = getConnectionInfo()
46 smb_structs.SUPPORT_SMB2 = True
47
48 factory = ListSharesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
49 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
50 return factory.d
+0
-57
python3/tests/DirectSMBTwistedTests/test_listsnapshots.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from smb import smb_structs
5 from .util import getConnectionInfo
6
7
8 class ListSnapshotsFactory(SMBProtocolFactory):
9
10 def __init__(self, *args, **kwargs):
11 SMBProtocolFactory.__init__(self, *args, **kwargs)
12 self.d = defer.Deferred()
13 self.d.addBoth(self.testDone)
14 self.service_name = None
15 self.path = None
16
17 def testDone(self, r):
18 if self.instance:
19 self.instance.transport.loseConnection()
20 return r
21
22 def onAuthOK(self):
23 def cb(results):
24 assert len(results) > 0
25 self.d.callback(True)
26 self.instance.transport.loseConnection()
27
28 d = self.listSnapshots(self.service_name, self.path, timeout = 15)
29 d.addCallback(cb)
30 d.addErrback(self.d.errback)
31
32 def onAuthFailed(self):
33 self.d.errback('Auth failed')
34
35
36 @deferred(timeout=15.0)
37 def test_listshares_SMB1():
38 info = getConnectionInfo()
39 smb_structs.SUPPORT_SMB2 = False
40
41 factory = ListSnapshotsFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
42 factory.service_name = 'smbtest'
43 factory.path = '/rfc1001.txt'
44 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
45 return factory.d
46
47 @deferred(timeout=15.0)
48 def test_listshares_SMB2():
49 info = getConnectionInfo()
50 smb_structs.SUPPORT_SMB2 = True
51
52 factory = ListSnapshotsFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
53 factory.service_name = 'smbtest'
54 factory.path = '/rfc1001.txt'
55 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
56 return factory.d
+0
-174
python3/tests/DirectSMBTwistedTests/test_rename.py less more
0 # -*- coding: utf-8 -*-
1
2 import os, random, time
3 from io import StringIO
4 from nose.twistedtools import reactor, deferred
5 from twisted.internet import defer
6 from smb.SMBProtocol import SMBProtocolFactory
7 from smb import smb_structs
8 from .util import getConnectionInfo
9
10
11 class RenameFactory(SMBProtocolFactory):
12
13 def __init__(self, *args, **kwargs):
14 SMBProtocolFactory.__init__(self, *args, **kwargs)
15 self.d = defer.Deferred()
16 self.d.addBoth(self.testDone)
17 self.service = ''
18 self.new_path = ''
19 self.old_path = ''
20
21 def testDone(self, r):
22 if self.instance:
23 self.instance.transport.loseConnection()
24 return r
25
26 def pathCreated(self, result):
27 d = self.listPath(self.service, os.path.dirname(self.old_path.replace('/', os.sep)))
28 d.addCallback(self.listComplete)
29 d.addErrback(self.d.errback)
30
31 def listComplete(self, entries):
32 filenames = [e.filename for e in entries]
33 assert os.path.basename(self.old_path.replace('/', os.sep)) in filenames
34 assert os.path.basename(self.new_path.replace('/', os.sep)) not in filenames
35
36 d = self.rename(self.service, self.old_path, self.new_path)
37 d.addCallback(self.renameComplete)
38 d.addErrback(self.d.errback)
39
40 def renameComplete(self, result):
41 d = self.listPath(self.service, os.path.dirname(self.new_path.replace('/', os.sep)))
42 d.addCallback(self.list2Complete)
43 d.addErrback(self.d.errback)
44
45 def list2Complete(self, entries):
46 filenames = [e.filename for e in entries]
47 assert os.path.basename(self.new_path.replace('/', os.sep)) in filenames
48 assert os.path.basename(self.old_path.replace('/', os.sep)) not in filenames
49 self.cleanup()
50
51 def onAuthFailed(self):
52 self.d.errback('Auth failed')
53
54
55 class RenameFileFactory(RenameFactory):
56
57 def onAuthOK(self):
58 d = self.storeFile(self.service, self.old_path, StringIO('Rename file test'))
59 d.addCallback(self.pathCreated)
60 d.addErrback(self.d.errback)
61
62 def cleanup(self):
63 d = self.deleteFiles(self.service, self.new_path)
64 d.chainDeferred(self.d)
65
66
67 class RenameDirectoryFactory(RenameFactory):
68
69 def onAuthOK(self):
70 d = self.createDirectory(self.service, self.old_path)
71 d.addCallback(self.pathCreated)
72 d.addErrback(self.d.errback)
73
74 def cleanup(self):
75 d = self.deleteDirectory(self.service, self.new_path)
76 d.chainDeferred(self.d)
77
78
79 @deferred(timeout=30.0)
80 def test_rename_english_file_SMB1():
81 info = getConnectionInfo()
82 smb_structs.SUPPORT_SMB2 = False
83
84 factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
85 factory.service = 'smbtest'
86 factory.old_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
87 factory.new_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
88 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
89 return factory.d
90
91 @deferred(timeout=30.0)
92 def test_rename_english_file_SMB2():
93 info = getConnectionInfo()
94 smb_structs.SUPPORT_SMB2 = True
95
96 factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
97 factory.service = 'smbtest'
98 factory.old_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
99 factory.new_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
100 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
101 return factory.d
102
103 @deferred(timeout=30.0)
104 def test_rename_unicode_file_SMB1():
105 info = getConnectionInfo()
106 smb_structs.SUPPORT_SMB2 = False
107
108 factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
109 factory.service = 'smbtest'
110 factory.old_path = '/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
111 factory.new_path = '/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
112 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
113 return factory.d
114
115 @deferred(timeout=30.0)
116 def test_rename_unicode_file_SMB2():
117 info = getConnectionInfo()
118 smb_structs.SUPPORT_SMB2 = True
119
120 factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
121 factory.service = 'smbtest'
122 factory.old_path = '/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
123 factory.new_path = '/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
124 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
125 return factory.d
126
127 @deferred(timeout=30.0)
128 def test_rename_english_directory_SMB1():
129 info = getConnectionInfo()
130 smb_structs.SUPPORT_SMB2 = False
131
132 factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
133 factory.service = 'smbtest'
134 factory.old_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) )
135 factory.new_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) )
136 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
137 return factory.d
138
139 @deferred(timeout=30.0)
140 def test_rename_english_directory_SMB2():
141 info = getConnectionInfo()
142 smb_structs.SUPPORT_SMB2 = True
143
144 factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
145 factory.service = 'smbtest'
146 factory.old_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) )
147 factory.new_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) )
148 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
149 return factory.d
150
151 @deferred(timeout=30.0)
152 def test_rename_unicode_directory_SMB1():
153 info = getConnectionInfo()
154 smb_structs.SUPPORT_SMB2 = False
155
156 factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
157 factory.service = 'smbtest'
158 factory.old_path = '/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) )
159 factory.new_path = '/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) )
160 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
161 return factory.d
162
163 @deferred(timeout=30.0)
164 def test_rename_unicode_directory_SMB2():
165 info = getConnectionInfo()
166 smb_structs.SUPPORT_SMB2 = True
167
168 factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
169 factory.service = 'smbtest'
170 factory.old_path = '/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) )
171 factory.new_path = '/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) )
172 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
173 return factory.d
+0
-278
python3/tests/DirectSMBTwistedTests/test_retrievefile.py less more
0 # -*- coding: utf-8 -*-
1
2 import os, tempfile
3 from nose.twistedtools import reactor, deferred
4 from twisted.internet import defer
5 from smb.SMBProtocol import SMBProtocolFactory
6 from smb import smb_structs
7 from .util import getConnectionInfo
8
9 try:
10 import hashlib
11 def MD5(): return hashlib.md5()
12 except ImportError:
13 import md5
14 def MD5(): return md5.new()
15
16
17 class RetrieveFileFactory(SMBProtocolFactory):
18
19 def __init__(self, *args, **kwargs):
20 SMBProtocolFactory.__init__(self, *args, **kwargs)
21 self.d = defer.Deferred()
22 self.d.addBoth(self.testDone)
23 self.temp_fh = tempfile.NamedTemporaryFile(prefix = 'pysmbtest-')
24 self.service = ''
25 self.path = ''
26 self.digest = ''
27 self.offset = 0
28 self.max_length = -1
29 self.filesize = 0
30
31 def testDone(self, r):
32 if self.instance:
33 self.instance.transport.loseConnection()
34 return r
35
36 def fileRetrieved(self, write_result):
37 file_obj, file_attributes, file_size = write_result
38 assert file_obj == self.temp_fh
39
40 md = MD5()
41 filesize = 0
42 self.temp_fh.seek(0)
43 while True:
44 s = self.temp_fh.read(8192)
45 if not s:
46 break
47 md.update(s)
48 filesize += len(s)
49
50 assert self.filesize == filesize
51 assert md.hexdigest() == self.digest
52
53 self.temp_fh.close()
54 self.d.callback(True)
55 self.instance.transport.loseConnection()
56
57 def onAuthOK(self):
58 assert self.service
59 assert self.path
60
61 d = self.retrieveFileFromOffset(self.service, self.path, self.temp_fh, self.offset, self.max_length, timeout = 15)
62 d.addCallback(self.fileRetrieved)
63 d.addErrback(self.d.errback)
64
65 def onAuthFailed(self):
66 self.d.errback('Auth failed')
67
68
69 @deferred(timeout=30.0)
70 def test_retr_multiplereads_SMB1():
71 # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes)
72 info = getConnectionInfo()
73 smb_structs.SUPPORT_SMB2 = False
74
75 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
76 factory.service = 'smbtest'
77 factory.path = '/rfc1001.txt'
78 factory.digest = '5367c2bbf97f521059c78eab65309ad3'
79 factory.filesize = 158437
80 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
81 return factory.d
82
83 @deferred(timeout=30.0)
84 def test_retr_multiplereads_SMB2():
85 # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes)
86 info = getConnectionInfo()
87 smb_structs.SUPPORT_SMB2 = True
88
89 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
90 factory.service = 'smbtest'
91 factory.path = '/rfc1001.txt'
92 factory.digest = '5367c2bbf97f521059c78eab65309ad3'
93 factory.filesize = 158437
94 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
95 return factory.d
96
97 @deferred(timeout=30.0)
98 def test_retr_longfilename_SMB1():
99 # Test file retrieval that has a long English filename
100 info = getConnectionInfo()
101 smb_structs.SUPPORT_SMB2 = False
102
103 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
104 factory.service = 'smbtest'
105 factory.path = '/Implementing CIFS - SMB.html'
106 factory.digest = '671c5700d279fcbbf958c1bba3c2639e'
107 factory.filesize = 421269
108 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
109 return factory.d
110
111 @deferred(timeout=30.0)
112 def test_retr_longfilename_SMB2():
113 # Test file retrieval that has a long English filename
114 info = getConnectionInfo()
115 smb_structs.SUPPORT_SMB2 = True
116
117 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
118 factory.service = 'smbtest'
119 factory.path = '/Implementing CIFS - SMB.html'
120 factory.digest = '671c5700d279fcbbf958c1bba3c2639e'
121 factory.filesize = 421269
122 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
123 return factory.d
124
125 @deferred(timeout=30.0)
126 def test_retr_unicodefilename_SMB1():
127 # Test file retrieval that has a long non-English filename inside a folder with a non-English name
128 info = getConnectionInfo()
129 smb_structs.SUPPORT_SMB2 = False
130
131 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
132 factory.service = 'smbtest'
133 factory.path = '/测试文件夹/垃圾文件.dat'
134 factory.digest = '8a44c1e80d55e91c92350955cdf83442'
135 factory.filesize = 256000
136 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
137 return factory.d
138
139 @deferred(timeout=30.0)
140 def test_retr_unicodefilename_SMB2():
141 # Test file retrieval that has a long non-English filename inside a folder with a non-English name
142 info = getConnectionInfo()
143 smb_structs.SUPPORT_SMB2 = True
144
145 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
146 factory.service = 'smbtest'
147 factory.path = '/测试文件夹/垃圾文件.dat'
148 factory.digest = '8a44c1e80d55e91c92350955cdf83442'
149 factory.filesize = 256000
150 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
151 return factory.d
152
153 @deferred(timeout=30.0)
154 def test_retr_offset_SMB1():
155 # Test file retrieval from offset to EOF
156 info = getConnectionInfo()
157 smb_structs.SUPPORT_SMB2 = False
158
159 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
160 factory.service = 'smbtest'
161 factory.path = '/测试文件夹/垃圾文件.dat'
162 factory.digest = 'a141bd8024571ce7cb5c67f2b0d8ea0b'
163 factory.filesize = 156000
164 factory.offset = 100000
165 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
166 return factory.d
167
168 @deferred(timeout=30.0)
169 def test_retr_offset_SMB2():
170 # Test file retrieval from offset to EOF
171 info = getConnectionInfo()
172 smb_structs.SUPPORT_SMB2 = True
173
174 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
175 factory.service = 'smbtest'
176 factory.path = '/测试文件夹/垃圾文件.dat'
177 factory.digest = 'a141bd8024571ce7cb5c67f2b0d8ea0b'
178 factory.filesize = 156000
179 factory.offset = 100000
180 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
181 return factory.d
182
183 @deferred(timeout=30.0)
184 def test_retr_offset_and_biglimit_SMB1():
185 # Test file retrieval from offset with a big max_length
186 info = getConnectionInfo()
187 smb_structs.SUPPORT_SMB2 = False
188
189 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
190 factory.service = 'smbtest'
191 factory.path = '/测试文件夹/垃圾文件.dat'
192 factory.digest = '83b7afd7c92cdece3975338b5ca0b1c5'
193 factory.filesize = 100000
194 factory.offset = 100000
195 factory.max_length = 100000
196 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
197 return factory.d
198
199 @deferred(timeout=30.0)
200 def test_retr_offset_and_biglimit_SMB2():
201 # Test file retrieval from offset with a big max_length
202 info = getConnectionInfo()
203 smb_structs.SUPPORT_SMB2 = True
204
205 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
206 factory.service = 'smbtest'
207 factory.path = '/测试文件夹/垃圾文件.dat'
208 factory.digest = '83b7afd7c92cdece3975338b5ca0b1c5'
209 factory.filesize = 100000
210 factory.offset = 100000
211 factory.max_length = 100000
212 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
213 return factory.d
214
215 @deferred(timeout=30.0)
216 def test_retr_offset_and_smalllimit_SMB1():
217 # Test file retrieval from offset with a small max_length
218 info = getConnectionInfo()
219 smb_structs.SUPPORT_SMB2 = False
220
221 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
222 factory.service = 'smbtest'
223 factory.path = '/测试文件夹/垃圾文件.dat'
224 factory.digest = '746f60a96b39b712a7b6e17ddde19986'
225 factory.filesize = 10
226 factory.offset = 100000
227 factory.max_length = 10
228 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
229 return factory.d
230
231 @deferred(timeout=30.0)
232 def test_retr_offset_and_smalllimit_SMB2():
233 # Test file retrieval from offset with a small max_length
234 info = getConnectionInfo()
235 smb_structs.SUPPORT_SMB2 = True
236
237 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
238 factory.service = 'smbtest'
239 factory.path = '/测试文件夹/垃圾文件.dat'
240 factory.digest = '746f60a96b39b712a7b6e17ddde19986'
241 factory.filesize = 10
242 factory.offset = 100000
243 factory.max_length = 10
244 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
245 return factory.d
246
247 @deferred(timeout=30.0)
248 def test_retr_offset_and_zerolimit_SMB1():
249 # Test file retrieval from offset to EOF with max_length=0
250 info = getConnectionInfo()
251 smb_structs.SUPPORT_SMB2 = False
252
253 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
254 factory.service = 'smbtest'
255 factory.path = '/测试文件夹/垃圾文件.dat'
256 factory.digest = 'd41d8cd98f00b204e9800998ecf8427e'
257 factory.filesize = 0
258 factory.offset = 100000
259 factory.max_length = 0
260 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
261 return factory.d
262
263 @deferred(timeout=30.0)
264 def test_retr_offset_and_zerolimit_SMB2():
265 # Test file retrieval from offset to EOF with max_length=0
266 info = getConnectionInfo()
267 smb_structs.SUPPORT_SMB2 = True
268
269 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
270 factory.service = 'smbtest'
271 factory.path = '/测试文件夹/垃圾文件.dat'
272 factory.digest = 'd41d8cd98f00b204e9800998ecf8427e'
273 factory.filesize = 0
274 factory.offset = 100000
275 factory.max_length = 0
276 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
277 return factory.d
+0
-141
python3/tests/DirectSMBTwistedTests/test_storefile.py less more
0 # -*- coding: utf-8 -*-
1
2 import os, time, random
3 from io import StringIO
4 from nose.twistedtools import reactor, deferred
5 from twisted.internet import defer
6 from smb.SMBProtocol import SMBProtocolFactory
7 from smb import smb_structs
8 from .util import getConnectionInfo
9
10 try:
11 import hashlib
12 def MD5(): return hashlib.md5()
13 except ImportError:
14 import md5
15 def MD5(): return md5.new()
16
17 class StoreFilesFactory(SMBProtocolFactory):
18 """
19 A super test factory that tests store file, list files, retrieve file and delete file functionlities in sequence.
20 """
21
22 TEST_FILENAME = os.path.join(os.path.dirname(__file__), os.pardir, 'SupportFiles', 'binary.dat')
23 TEST_FILESIZE = 256000
24 TEST_DIGEST = 'bb6303f76e29f354b6fdf6ef58587e48'
25
26 def __init__(self, *args, **kwargs):
27 SMBProtocolFactory.__init__(self, *args, **kwargs)
28 self.d = defer.Deferred()
29 self.d.addBoth(self.testDone)
30 self.service_name = ''
31 self.filename = ''
32
33 def testDone(self, r):
34 if self.instance:
35 self.instance.transport.loseConnection()
36 return r
37
38 def storeComplete(self, result):
39 file_obj, filesize = result
40 file_obj.close()
41 assert filesize == self.TEST_FILESIZE
42
43 d = self.listPath(self.service_name, os.path.dirname(self.filename.replace('/', os.sep)))
44 d.addCallback(self.listComplete)
45 d.addErrback(self.d.errback)
46
47 def listComplete(self, entries):
48 filenames = [e.filename for e in entries]
49 assert os.path.basename(self.filename.replace('/', os.sep)) in filenames
50
51 for entry in entries:
52 if os.path.basename(self.filename.replace('/', os.sep)) == entry.filename:
53 # The following asserts will fail if the remote machine's time is not in sync with the test machine's time
54 assert abs(entry.create_time - time.time()) < 3
55 assert abs(entry.last_access_time - time.time()) < 3
56 assert abs(entry.last_write_time - time.time()) < 3
57 assert abs(entry.last_attr_change_time - time.time()) < 3
58 break
59
60 d = self.retrieveFile(self.service_name, self.filename, StringIO())
61 d.addCallback(self.retrieveComplete)
62 d.addErrback(self.d.errback)
63
64 def retrieveComplete(self, result):
65 file_obj, file_attributes, file_size = result
66
67 md = MD5()
68 md.update(file_obj.getvalue())
69 file_obj.close()
70
71 assert file_size == self.TEST_FILESIZE
72 assert md.hexdigest() == self.TEST_DIGEST
73
74 d = self.deleteFiles(self.service_name, self.filename)
75 d.addCallback(self.deleteComplete)
76 d.addErrback(self.d.errback)
77
78 def deleteComplete(self, result):
79 d = self.listPath(self.service_name, os.path.dirname(self.filename.replace('/', os.sep)))
80 d.addCallback(self.list2Complete)
81 d.addErrback(self.d.errback)
82
83 def list2Complete(self, entries):
84 filenames = [e.filename for e in entries]
85 assert os.path.basename(self.filename.replace('/', os.sep)) not in filenames
86 self.d.callback(True)
87 self.instance.transport.loseConnection()
88
89 def onAuthOK(self):
90 d = self.storeFile(self.service_name, self.filename, open(self.TEST_FILENAME, 'rb'))
91 d.addCallback(self.storeComplete)
92 d.addErrback(self.d.errback)
93
94 def onAuthFailed(self):
95 self.d.errback('Auth failed')
96
97
98 @deferred(timeout=30.0)
99 def test_store_long_filename_SMB1():
100 info = getConnectionInfo()
101 smb_structs.SUPPORT_SMB2 = False
102
103 factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
104 factory.service_name = 'smbtest'
105 factory.filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
106 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
107 return factory.d
108
109 @deferred(timeout=30.0)
110 def test_store_long_filename_SMB2():
111 info = getConnectionInfo()
112 smb_structs.SUPPORT_SMB2 = True
113
114 factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
115 factory.service_name = 'smbtest'
116 factory.filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
117 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
118 return factory.d
119
120 @deferred(timeout=30.0)
121 def test_store_unicode_filename_SMB1():
122 info = getConnectionInfo()
123 smb_structs.SUPPORT_SMB2 = False
124
125 factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
126 factory.service_name = 'smbtest'
127 factory.filename = os.sep + '上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
128 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
129 return factory.d
130
131 @deferred(timeout=30.0)
132 def test_store_unicode_filename_SMB2():
133 info = getConnectionInfo()
134 smb_structs.SUPPORT_SMB2 = True
135
136 factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
137 factory.service_name = 'smbtest'
138 factory.filename = os.sep + '上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
139 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
140 return factory.d
+0
-19
python3/tests/DirectSMBTwistedTests/util.py less more
0
1 import os
2 from ConfigParser import SafeConfigParser
3
4 def getConnectionInfo():
5 config_filename = os.path.join(os.path.dirname(__file__), os.path.pardir, 'connection.ini')
6 cp = SafeConfigParser()
7 cp.read(config_filename)
8
9 info = {
10 'server_name': cp.get('server', 'name'),
11 'server_ip': cp.get('server', 'ip'),
12 'server_port': cp.getint('server', 'direct_port'),
13 'client_name': cp.get('client', 'name'),
14 'user': cp.get('user', 'name'),
15 'password': cp.get('user', 'password'),
16 'is_direct_tcp': True,
17 }
18 return info
00
11 from nmb.NetBIOS import NetBIOS
2 from nose.tools import with_setup
2 from nose2.tools.decorators import with_teardown
33
44 conn = None
55
77 global conn
88 conn.close()
99
10 @with_setup(teardown = teardown_func)
10 @with_teardown(teardown_func)
1111 def test_broadcast():
1212 global conn
1313 conn = NetBIOS()
+0
-0
python3/tests/NetBIOSTwistedTests/__init__.py less more
(Empty file)
+0
-21
python3/tests/NetBIOSTwistedTests/test_queryname.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from nmb.NetBIOSProtocol import NBNSProtocol
4 from nose.tools import with_setup
5
6
7 @deferred(timeout=15.0)
8 def test_broadcast():
9 def cb(results):
10 assert results
11
12 def cleanup(r):
13 p.transport.stopListening()
14
15 p = NBNSProtocol()
16 d = p.queryName('MICHAEL-I5PC', timeout = 10)
17 d.addCallback(cb)
18 d.addBoth(cleanup)
19
20 return d
0
1 Steps to Follow to Run the Unit Tests
2 =====================================
3
4 ## Step 1: Install system dependencies ##
5
6 If you are using Ubuntu 20.04 LTS, you can install the system dependencies with the following command
7 ```
8 $> apt-get install python3-dev python3-venv gcc g++ make automake autoconf
9 ```
10 For other distributions, you can use their package managers and install the system dependencies (although the package names might differ slightly).
11
12 ## Step 2: Setup python virtualenv ##
13
14 We will create a python3 virtualenv and install the python dependencies for testing in the "venv3" folder.
15
16 ```
17 $> cd <pysmb-home>/python3
18 $> virtualenv -p /usr/bin/python3 venv3
19 $> source venv3/bin/activate
20 $venv3> pip install nose2 pyasn1 twisted
21 ```
22
23 ## Step 3: Setup shared folder on your remote SMB server ##
24
25 Prepare a shared folder called "smbtest" on your remote SMB server (Windows or Samba).
26
27 Then, download [smbtest.zip](https://miketeo.net/files/Projects/pysmb/smbtest.zip) and unzip the contents of this zip file in the shared folder.
28
29 You should also configure a user on the SMB server with read-write access to the "smbtest" folder.
30
31 ## Step 4: Update connection details in connection.ini ##
32
33 In the same folder where you are viewing this readme file, there should be an ini file called "connection.ini". Edit this file's connection details to match the shared folder's access information.
34
35 ## Step 5: Run the unit tests in the python3 folder ##
36
37 Before running the tests, the venv3 virtualenv must be activated.
38 ```
39 $> cd <pysmb-home>/python3
40 $> source venv3/bin/activate
41 ```
42
43 To run all the tests:
44 ```
45 $venv3> nose2 -v tests
46 ```
47
48 To selectively run some tests:
49 ```
50 $venv3> nose2 -v tests.SMBConnectionTests
51 $venv3> nose2 -v tests.SMBConnectionTests.test_rename
52 $venv3> nose2 -v tests.SMBConnectionTests.test_rename.test_rename_english_file_SMB1
53 ```
54 For more information, please consult the [documentation for nose2](https://docs.nose2.io/).
55
56
11
22 import os, urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse, time, random
33 from smb.SMBHandler import SMBHandler
4 from . import util
4 import util
55
66
77 try:
00
1 from nose2.tools.decorators import with_teardown
12 from smb.SMBConnection import SMBConnection
3 from smb import smb_structs
24 from .util import getConnectionInfo
3 from nose.tools import with_setup
4 from smb import smb_structs
55
66 conn = None
77
99 global conn
1010 conn.close()
1111
12 @with_setup(teardown = teardown_func)
12 @with_teardown(teardown_func)
1313 def test_NTLMv1_auth_SMB1():
1414 global conn
1515 smb_structs.SUPPORT_SMB2 = False
1717 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], domain = info['domain'], use_ntlm_v2 = False)
1818 assert conn.connect(info['server_ip'], info['server_port'])
1919
20 @with_setup(teardown = teardown_func)
20 @with_teardown(teardown_func)
2121 def test_NTLMv2_auth_SMB1():
2222 global conn
2323 smb_structs.SUPPORT_SMB2 = False
2525 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], domain = info['domain'], use_ntlm_v2 = True)
2626 assert conn.connect(info['server_ip'], info['server_port'])
2727
28 @with_setup(teardown = teardown_func)
28 @with_teardown(teardown_func)
2929 def test_NTLMv1_auth_SMB2():
3030 global conn
3131 smb_structs.SUPPORT_SMB2 = True
3333 conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], domain = info['domain'], use_ntlm_v2 = False)
3434 assert conn.connect(info['server_ip'], info['server_port'])
3535
36 @with_setup(teardown = teardown_func)
36 @with_teardown(teardown_func)
3737 def test_NTLMv2_auth_SMB2():
3838 global conn
3939 smb_structs.SUPPORT_SMB2 = True
00 # -*- coding: utf-8 -*-
11
22 import os, time, random
3 from nose2.tools.decorators import with_setup, with_teardown
34 from smb.SMBConnection import SMBConnection
5 from smb import smb_structs
46 from .util import getConnectionInfo
5 from nose.tools import with_setup
6 from smb import smb_structs
77
88 conn = None
99
2727 global conn
2828 conn.close()
2929
30 @with_setup(setup_func_SMB1, teardown_func)
30 @with_setup(setup_func_SMB1)
31 @with_teardown(teardown_func)
3132 def test_english_directory_SMB1():
3233 global conn
3334
4445 names = [e.filename for e in entries]
4546 assert os.path.basename(path.replace('/', os.sep)) not in names
4647
47 @with_setup(setup_func_SMB2, teardown_func)
48 @with_setup(setup_func_SMB2)
49 @with_teardown(teardown_func)
4850 def test_english_directory_SMB2():
4951 global conn
5052
6163 names = [e.filename for e in entries]
6264 assert os.path.basename(path.replace('/', os.sep)) not in names
6365
64 @with_setup(setup_func_SMB1, teardown_func)
66 @with_setup(setup_func_SMB1)
67 @with_teardown(teardown_func)
6568 def test_unicode_directory_SMB1():
6669 global conn
6770
7881 names = [e.filename for e in entries]
7982 assert os.path.basename(path.replace('/', os.sep)) not in names
8083
81 @with_setup(setup_func_SMB2, teardown_func)
84 @with_setup(setup_func_SMB2)
85 @with_teardown(teardown_func)
8286 def test_unicode_directory_SMB2():
8387 global conn
8488
11
22 import os, time, random
33 from io import BytesIO
4 from nose2.tools.decorators import with_setup, with_teardown
45 from smb.SMBConnection import SMBConnection
6 from smb import smb_structs
57 from .util import getConnectionInfo
6 from nose.tools import with_setup
7 from smb import smb_structs
88
99 conn = None
1010
2828 global conn
2929 conn.close()
3030
31 @with_setup(setup_func_SMB1, teardown_func)
32 def test_delete_SMB1():
33 global conn
34
35 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
36 conn.createDirectory('smbtest', path)
37
38 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
39 conn.storeFile('smbtest', path+"/"+filename, BytesIO(b"0123456789"))
40
41 results = conn.listPath('smbtest', path)
42 filenames = list(map(lambda r: r.filename, results))
31 @with_setup(setup_func_SMB1)
32 @with_teardown(teardown_func)
33 def test_delete_without_subfolder_SMB1():
34 global conn
35
36 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
37 conn.createDirectory('smbtest', path)
38
39 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
40 conn.storeFile('smbtest', path+"/"+filename, BytesIO(b"0123456789"))
41
42 for p in [ 'aaTest.Folder', 'aaTest.Folder/xyz', 'bbTest.Folder' ]:
43 conn.createDirectory('smbtest', path+"/"+p)
44 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
45 conn.storeFile('smbtest', path+"/"+p+"/"+filename, BytesIO(b"0123456789"))
46
47 results = conn.listPath('smbtest', path)
48 filenames = list(map(lambda r: r.filename, results))
49 assert 'aaTest.Folder' in filenames
50 assert 'bbTest.Folder' in filenames
4351 assert 'aaTest.txt' in filenames
4452 assert 'aaBest.txt' in filenames
4553 assert 'aaTest.bin' in filenames
5058
5159 results = conn.listPath('smbtest', path)
5260 filenames = list(map(lambda r: r.filename, results))
61 assert 'aaTest.Folder' in filenames
62 assert 'bbTest.Folder' in filenames
5363 assert 'aaTest.txt' not in filenames
5464 assert 'aaBest.txt' not in filenames
5565 assert 'aaTest.bin' in filenames
6070
6171 results = conn.listPath('smbtest', path)
6272 filenames = list(map(lambda r: r.filename, results))
63 assert 'aaTest.bin' not in filenames
64 assert 'aaBest.bin' in filenames
65 assert 'random.txt' in filenames
66
67 conn.deleteFiles('smbtest', path+'/*')
68 conn.deleteDirectory('smbtest', path)
69
70 @with_setup(setup_func_SMB2, teardown_func)
71 def test_delete_SMB2():
72 global conn
73
74 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
75 conn.createDirectory('smbtest', path)
76
77 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
78 conn.storeFile('smbtest', path+"/"+filename, BytesIO(b"0123456789"))
79
80 results = conn.listPath('smbtest', path)
81 filenames = list(map(lambda r: r.filename, results))
73 assert 'aaTest.Folder' in filenames
74 assert 'bbTest.Folder' in filenames
75 assert 'aaTest.bin' not in filenames
76 assert 'aaBest.bin' in filenames
77 assert 'random.txt' in filenames
78
79
80 @with_setup(setup_func_SMB1)
81 @with_teardown(teardown_func)
82 def test_delete_with_subfolder_SMB1():
83 global conn
84
85 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
86 conn.createDirectory('smbtest', path)
87
88 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
89 conn.storeFile('smbtest', path+"/"+filename, BytesIO(b"0123456789"))
90
91 for p in [ 'aaTest.Folder', 'aaTest.Folder/xyz', 'bbTest.Folder' ]:
92 conn.createDirectory('smbtest', path+"/"+p)
93 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
94 conn.storeFile('smbtest', path+"/"+p+"/"+filename, BytesIO(b"0123456789"))
95
96 results = conn.listPath('smbtest', path)
97 filenames = list(map(lambda r: r.filename, results))
98 assert 'aaTest.Folder' in filenames
99 assert 'bbTest.Folder' in filenames
100 assert 'aaTest.txt' in filenames
101 assert 'aaBest.txt' in filenames
102 assert 'aaTest.bin' in filenames
103 assert 'aaBest.bin' in filenames
104 assert 'random.txt' in filenames
105
106 conn.deleteFiles('smbtest', path+'/aa*.txt', delete_matching_folders=True)
107
108 results = conn.listPath('smbtest', path)
109 filenames = list(map(lambda r: r.filename, results))
110 assert 'aaTest.Folder' in filenames
111 assert 'bbTest.Folder' in filenames
112 assert 'aaTest.txt' not in filenames
113 assert 'aaBest.txt' not in filenames
114 assert 'aaTest.bin' in filenames
115 assert 'aaBest.bin' in filenames
116 assert 'random.txt' in filenames
117
118 conn.deleteFiles('smbtest', path+'/aaTest.*', delete_matching_folders=True)
119
120 results = conn.listPath('smbtest', path)
121 filenames = list(map(lambda r: r.filename, results))
122 assert 'aaTest.Folder' not in filenames
123 assert 'bbTest.Folder' in filenames
124 assert 'aaTest.bin' not in filenames
125 assert 'aaBest.bin' in filenames
126 assert 'random.txt' in filenames
127
128
129 @with_setup(setup_func_SMB2)
130 @with_teardown(teardown_func)
131 def test_delete_without_subfolder_SMB2():
132 global conn
133
134 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
135 conn.createDirectory('smbtest', path)
136
137 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
138 conn.storeFile('smbtest', path+"/"+filename, BytesIO(b"0123456789"))
139
140 for p in [ 'aaTest.Folder', 'aaTest.Folder/xyz', 'bbTest.Folder' ]:
141 conn.createDirectory('smbtest', path+"/"+p)
142 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
143 conn.storeFile('smbtest', path+"/"+p+"/"+filename, BytesIO(b"0123456789"))
144
145 results = conn.listPath('smbtest', path)
146 filenames = list(map(lambda r: r.filename, results))
147 assert 'aaTest.Folder' in filenames
148 assert 'bbTest.Folder' in filenames
82149 assert 'aaTest.txt' in filenames
83150 assert 'aaBest.txt' in filenames
84151 assert 'aaTest.bin' in filenames
89156
90157 results = conn.listPath('smbtest', path)
91158 filenames = list(map(lambda r: r.filename, results))
159 assert 'aaTest.Folder' in filenames
160 assert 'bbTest.Folder' in filenames
92161 assert 'aaTest.txt' not in filenames
93162 assert 'aaBest.txt' not in filenames
94163 assert 'aaTest.bin' in filenames
99168
100169 results = conn.listPath('smbtest', path)
101170 filenames = list(map(lambda r: r.filename, results))
102 assert 'aaTest.bin' not in filenames
103 assert 'aaBest.bin' in filenames
104 assert 'random.txt' in filenames
171 assert 'aaTest.Folder' in filenames
172 assert 'bbTest.Folder' in filenames
173 assert 'aaTest.bin' not in filenames
174 assert 'aaBest.bin' in filenames
175 assert 'random.txt' in filenames
176
177 @with_setup(setup_func_SMB2)
178 @with_teardown(teardown_func)
179 def test_delete_with_subfolder_SMB2():
180 global conn
181
182 path = os.sep + u'testDelete %d-%d' % ( time.time(), random.randint(0, 1000) )
183 conn.createDirectory('smbtest', path)
184
185 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
186 conn.storeFile('smbtest', path+"/"+filename, BytesIO(b"0123456789"))
187
188 for p in [ 'aaTest.Folder', 'aaTest.Folder/xyz', 'bbTest.Folder' ]:
189 conn.createDirectory('smbtest', path+"/"+p)
190 for filename in [ 'aaTest.txt', 'aaBest.txt', 'aaTest.bin', 'aaBest.bin', 'random.txt' ]:
191 conn.storeFile('smbtest', path+"/"+p+"/"+filename, BytesIO(b"0123456789"))
192
193 results = conn.listPath('smbtest', path)
194 filenames = list(map(lambda r: r.filename, results))
195 assert 'aaTest.Folder' in filenames
196 assert 'bbTest.Folder' in filenames
197 assert 'aaTest.txt' in filenames
198 assert 'aaBest.txt' in filenames
199 assert 'aaTest.bin' in filenames
200 assert 'aaBest.bin' in filenames
201 assert 'random.txt' in filenames
202
203 conn.deleteFiles('smbtest', path+'/aa*.txt', delete_matching_folders=True)
204
205 results = conn.listPath('smbtest', path)
206 filenames = list(map(lambda r: r.filename, results))
207 assert 'aaTest.Folder' in filenames
208 assert 'bbTest.Folder' in filenames
209 assert 'aaTest.txt' not in filenames
210 assert 'aaBest.txt' not in filenames
211 assert 'aaTest.bin' in filenames
212 assert 'aaBest.bin' in filenames
213 assert 'random.txt' in filenames
214
215 conn.deleteFiles('smbtest', path+'/aaTest.*', delete_matching_folders=True)
216
217 results = conn.listPath('smbtest', path)
218 filenames = list(map(lambda r: r.filename, results))
219 assert 'aaTest.Folder' not in filenames
220 assert 'bbTest.Folder' in filenames
221 assert 'aaTest.bin' not in filenames
222 assert 'aaBest.bin' in filenames
223 assert 'random.txt' in filenames
00
11 import random
2 from nose2.tools.decorators import with_setup, with_teardown
23 from smb.SMBConnection import SMBConnection
34 from .util import getConnectionInfo
4 from nose.tools import with_setup
55
66 conn = None
77
1515 global conn
1616 conn.close()
1717
18 @with_setup(setup_func, teardown_func)
18 @with_setup(setup_func)
19 @with_teardown(teardown_func)
1920 def test_echo():
2021 global conn
2122
11
22 from smb.SMBConnection import SMBConnection
33 from .util import getConnectionInfo
4 from nose.tools import with_setup
4 from nose2.tools.decorators import with_setup, with_teardown
55 from smb import smb_structs
66
77 conn = None
2424 global conn
2525 conn.close()
2626
27 @with_setup(setup_func_SMB2, teardown_func)
27 @with_setup(setup_func_SMB2)
28 @with_teardown(teardown_func)
2829 def test_getAttributes_SMB2():
2930 global conn
3031 info = conn.getAttributes('smbtest', '/Test Folder with Long Name/')
3839 info = conn.getAttributes('smbtest', u'/\u6d4b\u8bd5\u6587\u4ef6\u5939')
3940 assert info.isDirectory
4041
41 @with_setup(setup_func_SMB1, teardown_func)
42 @with_setup(setup_func_SMB1)
43 @with_teardown(teardown_func)
4244 def test_getAttributes_SMB1():
4345 global conn
4446 info = conn.getAttributes('smbtest', '/Test Folder with Long Name/')
5153
5254 info = conn.getAttributes('smbtest', u'/\u6d4b\u8bd5\u6587\u4ef6\u5939')
5355 assert info.isDirectory
54
55
56
00 # -*- coding: utf-8 -*-
11
2 from nose2.tools.decorators import with_setup, with_teardown
23 from smb.SMBConnection import SMBConnection
4 from smb.smb_constants import *
5 from smb import smb_structs
36 from .util import getConnectionInfo
4 from nose.tools import with_setup
5 from smb import smb_structs
67
78 conn = None
89
2425 global conn
2526 conn.close()
2627
27 @with_setup(setup_func_SMB1, teardown_func)
28 @with_setup(setup_func_SMB1)
29 @with_teardown(teardown_func)
2830 def test_listPath_SMB1():
2931 global conn
3032 results = conn.listPath('smbtest', '/')
3537 assert ( 'Implementing CIFS - SMB.html', False ) in filenames # Test long English file names
3638 assert ( 'rfc1001.txt', False ) in filenames # Test short English file names
3739
38 @with_setup(setup_func_SMB1, teardown_func)
40 @with_setup(setup_func_SMB1)
41 @with_teardown(teardown_func)
3942 def test_listSubPath_SMB1():
4043 global conn
4144 results = conn.listPath('smbtest', '/Test Folder with Long Name/')
4447 assert ( 'Test Folder', True ) in filenames
4548 assert ( '子文件夹', True ) in filenames
4649
47 @with_setup(setup_func_SMB2, teardown_func)
50 @with_setup(setup_func_SMB1)
51 @with_teardown(teardown_func)
52 def test_listPathWithManyFiles_SMB1():
53 global conn
54 results = conn.listPath('smbtest', '/RFC Archive/')
55 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
56 assert len(list(filenames))==999
57
58 @with_setup(setup_func_SMB2)
59 @with_teardown(teardown_func)
4860 def test_listPath_SMB2():
4961 global conn
5062 results = conn.listPath('smbtest', '/')
5567 assert ( 'Implementing CIFS - SMB.html', False ) in filenames # Test long English file names
5668 assert ( 'rfc1001.txt', False ) in filenames # Test short English file names
5769
58 @with_setup(setup_func_SMB2, teardown_func)
70 @with_setup(setup_func_SMB2)
71 @with_teardown(teardown_func)
5972 def test_listSubPath_SMB2():
6073 global conn
6174 results = conn.listPath('smbtest', '/Test Folder with Long Name/')
6376 assert ( 'Test File.txt', False ) in filenames
6477 assert ( 'Test Folder', True ) in filenames
6578 assert ( '子文件夹', True ) in filenames
79
80 @with_setup(setup_func_SMB2)
81 @with_teardown(teardown_func)
82 def test_listPathWithManyFiles_SMB2():
83 global conn
84 results = conn.listPath('smbtest', '/RFC Archive/')
85 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
86 assert len(list(filenames))==999
87
88 @with_setup(setup_func_SMB1)
89 @with_teardown(teardown_func)
90 def test_listPathFilterForDirectory_SMB1():
91 global conn
92 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_DIRECTORY)
93 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
94 assert len(list(filenames)) > 0
95 for f, isDirectory in filenames:
96 assert isDirectory
97
98 @with_setup(setup_func_SMB2)
99 @with_teardown(teardown_func)
100 def test_listPathFilterForDirectory_SMB2():
101 global conn
102 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_DIRECTORY)
103 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
104 assert len(list(filenames)) > 0
105 for f, isDirectory in filenames:
106 assert isDirectory
107
108 @with_setup(setup_func_SMB1)
109 @with_teardown(teardown_func)
110 def test_listPathFilterForFiles_SMB1():
111 global conn
112 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL)
113 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
114 assert len(list(filenames)) > 0
115 for f, isDirectory in filenames:
116 assert not isDirectory
117
118 @with_setup(setup_func_SMB2)
119 @with_teardown(teardown_func)
120 def test_listPathFilterForFiles_SMB2():
121 global conn
122 results = conn.listPath('smbtest', '/Test Folder with Long Name', search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL)
123 filenames = map(lambda r: ( r.filename, r.isDirectory ), results)
124 assert len(list(filenames)) > 0
125 for f, isDirectory in filenames:
126 assert not isDirectory
127
128 @with_setup(setup_func_SMB1)
129 @with_teardown(teardown_func)
130 def test_listPathFilterPattern_SMB1():
131 global conn
132 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = 'Test*')
133 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
134 assert len(filenames) == 2
135 assert ( u'Test File.txt', False ) in filenames
136 assert ( u'Test Folder', True ) in filenames
137 assert ( u'子文件夹', True ) not in filenames
138
139 @with_setup(setup_func_SMB2)
140 @with_teardown(teardown_func)
141 def test_listPathFilterPattern_SMB2():
142 global conn
143 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = 'Test*')
144 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
145 assert len(filenames) == 2
146 assert ( u'Test File.txt', False ) in filenames
147 assert ( u'Test Folder', True ) in filenames
148 assert ( u'子文件夹', True ) not in filenames
149
150 @with_setup(setup_func_SMB1)
151 @with_teardown(teardown_func)
152 def test_listPathFilterUnicodePattern_SMB1():
153 global conn
154 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = u'*件夹')
155 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
156 assert len(filenames) == 1
157 assert ( u'Test File.txt', False ) not in filenames
158 assert ( u'Test Folder', True ) not in filenames
159 assert ( u'子文件夹', True ) in filenames
160
161 @with_setup(setup_func_SMB2)
162 @with_teardown(teardown_func)
163 def test_listPathFilterUnicodePattern_SMB2():
164 global conn
165 results = conn.listPath('smbtest', '/Test Folder with Long Name', pattern = u'*件夹')
166 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
167 assert len(filenames) == 1
168 assert ( u'Test File.txt', False ) not in filenames
169 assert ( u'Test Folder', True ) not in filenames
170 assert ( u'子文件夹', True ) in filenames
171
172 @with_setup(setup_func_SMB1)
173 @with_teardown(teardown_func)
174 def test_listPathFilterEmptyList_SMB1():
175 global conn
176 results = conn.listPath('smbtest', '/RFC Archive', pattern = '*.abc')
177 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
178
179 @with_setup(setup_func_SMB2)
180 @with_teardown(teardown_func)
181 def test_listPathFilterEmptyList_SMB2():
182 global conn
183 results = conn.listPath('smbtest', '/RFC Archive', pattern = '*.abc')
184 filenames = list(map(lambda r: ( r.filename, r.isDirectory ), results))
00
1 from nose2.tools.decorators import with_setup, with_teardown
12 from smb.SMBConnection import SMBConnection
3 from smb import smb_structs
24 from .util import getConnectionInfo
3 from nose.tools import with_setup
4 from smb import smb_structs
55
66 conn = None
77
2323 global conn
2424 conn.close()
2525
26 @with_setup(setup_func_SMB1, teardown_func)
26 @with_setup(setup_func_SMB1)
27 @with_teardown(teardown_func)
2728 def test_listshares_SMB1():
2829 global conn
2930 results = conn.listShares()
3031 assert 'smbtest' in [r.name.lower() for r in results]
3132
32 @with_setup(setup_func_SMB2, teardown_func)
33 @with_setup(setup_func_SMB2)
34 @with_teardown(teardown_func)
3335 def test_listshares_SMB2():
3436 global conn
3537 results = conn.listShares()
00
1 from nose2.tools.decorators import with_setup, with_teardown
12 from smb.SMBConnection import SMBConnection
3 from smb import smb_structs
24 from .util import getConnectionInfo
3 from nose.tools import with_setup
4 from smb import smb_structs
55
66 conn = None
77
2323 global conn
2424 conn.close()
2525
26 @with_setup(setup_func_SMB1, teardown_func)
26 @with_setup(setup_func_SMB1)
27 @with_teardown(teardown_func)
2728 def test_listsnapshots_SMB1():
2829 global conn
2930 results = conn.listSnapshots('smbtest', '/rfc1001.txt')
3031 assert len(results) > 0
3132
32 @with_setup(setup_func_SMB2, teardown_func)
33 @with_setup(setup_func_SMB2)
34 @with_teardown(teardown_func)
3335 def test_listsnapshots_SMB2():
3436 global conn
3537 results = conn.listSnapshots('smbtest', '/rfc1001.txt')
11
22 import os, time, random
33 from io import BytesIO
4 from nose2.tools.decorators import with_setup, with_teardown
45 from smb.SMBConnection import SMBConnection
6 from smb import smb_structs
57 from .util import getConnectionInfo
6 from nose.tools import with_setup
7 from smb import smb_structs
88
99 conn = None
1010
2626 global conn
2727 conn.close()
2828
29 @with_setup(setup_func_SMB1, teardown_func)
29 @with_setup(setup_func_SMB1)
30 @with_teardown(teardown_func)
3031 def test_rename_english_file_SMB1():
3132 global conn
3233
4950
5051 conn.deleteFiles('smbtest', new_path)
5152
52 @with_setup(setup_func_SMB2, teardown_func)
53 @with_setup(setup_func_SMB2)
54 @with_teardown(teardown_func)
5355 def test_rename_english_file_SMB2():
5456 global conn
5557
7274
7375 conn.deleteFiles('smbtest', new_path)
7476
75 @with_setup(setup_func_SMB1, teardown_func)
77 @with_setup(setup_func_SMB1)
78 @with_teardown(teardown_func)
7679 def test_rename_unicode_file_SMB1():
7780 global conn
7881
9598
9699 conn.deleteFiles('smbtest', new_path)
97100
98 @with_setup(setup_func_SMB2, teardown_func)
101 @with_setup(setup_func_SMB2)
102 @with_teardown(teardown_func)
99103 def test_rename_unicode_file_SMB2():
100104 global conn
101105
118122
119123 conn.deleteFiles('smbtest', new_path)
120124
121 @with_setup(setup_func_SMB1, teardown_func)
125 @with_setup(setup_func_SMB1)
126 @with_teardown(teardown_func)
122127 def test_rename_english_directory_SMB1():
123128 global conn
124129
141146
142147 conn.deleteDirectory('smbtest', new_path)
143148
144 @with_setup(setup_func_SMB2, teardown_func)
149 @with_setup(setup_func_SMB2)
150 @with_teardown(teardown_func)
145151 def test_rename_english_directory_SMB2():
146152 global conn
147153
164170
165171 conn.deleteDirectory('smbtest', new_path)
166172
167 @with_setup(setup_func_SMB1, teardown_func)
173 @with_setup(setup_func_SMB1)
174 @with_teardown(teardown_func)
168175 def test_rename_unicode_directory_SMB1():
169176 global conn
170177
187194
188195 conn.deleteDirectory('smbtest', new_path)
189196
190 @with_setup(setup_func_SMB2, teardown_func)
197 @with_setup(setup_func_SMB2)
198 @with_teardown(teardown_func)
191199 def test_rename_unicode_directory_SMB2():
192200 global conn
193201
11
22 import os, tempfile
33 from io import BytesIO
4 from nose2.tools.decorators import with_setup, with_teardown
45 from smb.SMBConnection import SMBConnection
6 from smb import smb_structs
57 from .util import getConnectionInfo
6 from nose.tools import with_setup
7 from smb import smb_structs
88
99 try:
1010 import hashlib
3333 global conn
3434 conn.close()
3535
36 @with_setup(setup_func_SMB1, teardown_func)
36 @with_setup(setup_func_SMB1)
37 @with_teardown(teardown_func)
3738 def test_retr_multiplereads_SMB1():
3839 # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes)
3940 global conn
4748
4849 temp_fh.close()
4950
50 @with_setup(setup_func_SMB2, teardown_func)
51 @with_setup(setup_func_SMB2)
52 @with_teardown(teardown_func)
5153 def test_retr_multiplereads_SMB2():
5254 # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes)
5355 global conn
6163
6264 temp_fh.close()
6365
64 @with_setup(setup_func_SMB1, teardown_func)
66 @with_setup(setup_func_SMB1)
67 @with_teardown(teardown_func)
6568 def test_retr_longfilename_SMB1():
6669 # Test file retrieval that has a long English filename
6770 global conn
7578
7679 temp_fh.close()
7780
78 @with_setup(setup_func_SMB2, teardown_func)
81 @with_setup(setup_func_SMB2)
82 @with_teardown(teardown_func)
7983 def test_retr_longfilename_SMB2():
8084 # Test file retrieval that has a long English filename
8185 global conn
8993
9094 temp_fh.close()
9195
92 @with_setup(setup_func_SMB1, teardown_func)
96 @with_setup(setup_func_SMB1)
97 @with_teardown(teardown_func)
9398 def test_retr_unicodefilename_SMB1():
9499 # Test file retrieval that has a long non-English filename inside a folder with a non-English name
95100 global conn
103108
104109 temp_fh.close()
105110
106 @with_setup(setup_func_SMB2, teardown_func)
111 @with_setup(setup_func_SMB2)
112 @with_teardown(teardown_func)
107113 def test_retr_unicodefilename_SMB2():
108114 # Test file retrieval that has a long non-English filename inside a folder with a non-English name
109115 global conn
117123
118124 temp_fh.close()
119125
120 @with_setup(setup_func_SMB1, teardown_func)
126 @with_setup(setup_func_SMB1)
127 @with_teardown(teardown_func)
121128 def test_retr_offset_SMB1():
122129 # Test file retrieval from offset to EOF
123130 global conn
131138
132139 temp_fh.close()
133140
134 @with_setup(setup_func_SMB2, teardown_func)
141 @with_setup(setup_func_SMB2)
142 @with_teardown(teardown_func)
135143 def test_retr_offset_SMB2():
136144 # Test file retrieval from offset to EOF
137145 global conn
145153
146154 temp_fh.close()
147155
148 @with_setup(setup_func_SMB1, teardown_func)
156 @with_setup(setup_func_SMB1)
157 @with_teardown(teardown_func)
149158 def test_retr_offset_and_biglimit_SMB1():
150159 # Test file retrieval from offset with a big max_length
151160 global conn
159168
160169 temp_fh.close()
161170
162 @with_setup(setup_func_SMB2, teardown_func)
171 @with_setup(setup_func_SMB2)
172 @with_teardown(teardown_func)
163173 def test_retr_offset_and_biglimit_SMB2():
164174 # Test file retrieval from offset with a big max_length
165175 global conn
173183
174184 temp_fh.close()
175185
176 @with_setup(setup_func_SMB1, teardown_func)
186 @with_setup(setup_func_SMB1)
187 @with_teardown(teardown_func)
177188 def test_retr_offset_and_smalllimit_SMB1():
178189 # Test file retrieval from offset with a small max_length
179190 global conn
187198
188199 temp_fh.close()
189200
190 @with_setup(setup_func_SMB2, teardown_func)
201 @with_setup(setup_func_SMB2)
202 @with_teardown(teardown_func)
191203 def test_retr_offset_and_smalllimit_SMB2():
192204 # Test file retrieval from offset with a small max_length
193205 global conn
201213
202214 temp_fh.close()
203215
204 @with_setup(setup_func_SMB1, teardown_func)
216 @with_setup(setup_func_SMB1)
217 @with_teardown(teardown_func)
205218 def test_retr_offset_and_zerolimit_SMB1():
206219 # Test file retrieval from offset to EOF with max_length=0
207220 global conn
215228
216229 temp_fh.close()
217230
218 @with_setup(setup_func_SMB2, teardown_func)
231 @with_setup(setup_func_SMB2)
232 @with_teardown(teardown_func)
219233 def test_retr_offset_and_zerolimit_SMB2():
220234 # Test file retrieval from offset to EOF with max_length=0
221235 global conn
11
22 import os, tempfile, random, time
33 from io import BytesIO
4 from nose2.tools.decorators import with_setup, with_teardown
45 from smb.SMBConnection import SMBConnection
6 from smb import smb_structs
57 from .util import getConnectionInfo
6 from nose.tools import with_setup
7 from smb import smb_structs
88
99 try:
1010 import hashlib
4040 conn.close()
4141
4242
43 @with_setup(setup_func_SMB1, teardown_func)
43 @with_setup(setup_func_SMB1)
44 @with_teardown(teardown_func)
4445 def test_store_long_filename_SMB1():
4546 filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
4647
6364 conn.deleteFiles('smbtest', filename)
6465
6566
66 @with_setup(setup_func_SMB2, teardown_func)
67 @with_setup(setup_func_SMB2)
68 @with_teardown(teardown_func)
6769 def test_store_long_filename_SMB2():
6870 filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
6971
8688 conn.deleteFiles('smbtest', filename)
8789
8890
89 @with_setup(setup_func_SMB1, teardown_func)
91 @with_setup(setup_func_SMB1)
92 @with_teardown(teardown_func)
9093 def test_store_unicode_filename_SMB1():
9194 filename = os.sep + '上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
9295
109112 conn.deleteFiles('smbtest', filename)
110113
111114
112 @with_setup(setup_func_SMB1, teardown_func)
115 @with_setup(setup_func_SMB1)
116 @with_teardown(teardown_func)
113117 def test_store_from_offset_SMB1():
114118 filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
115119
129133
130134 conn.deleteFiles('smbtest', filename)
131135
132 @with_setup(setup_func_SMB2, teardown_func)
136 @with_setup(setup_func_SMB2)
137 @with_teardown(teardown_func)
133138 def test_store_unicode_filename_SMB2():
134139 filename = os.sep + '上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
135140
151156
152157 conn.deleteFiles('smbtest', filename)
153158
154 @with_setup(setup_func_SMB2, teardown_func)
159 @with_setup(setup_func_SMB2)
160 @with_teardown(teardown_func)
155161 def test_store_from_offset_SMB2():
156162 filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
157163
0 # -*- coding: utf-8 -*-
1
2 from smb.SMBConnection import SMBConnection
3 from .util import getConnectionInfo
4
5 def test_context():
6 info = getConnectionInfo()
7 with SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) as conn:
8 assert conn.connect(info['server_ip'], info['server_port'])
9
10 assert conn.sock is None
+0
-0
python3/tests/SMBTwistedTests/__init__.py less more
(Empty file)
+0
-77
python3/tests/SMBTwistedTests/test_auth.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from smb import smb_structs
5 from .util import getConnectionInfo
6
7
8 class AuthFactory(SMBProtocolFactory):
9
10 def __init__(self, *args, **kwargs):
11 SMBProtocolFactory.__init__(self, *args, **kwargs)
12 self.d = defer.Deferred()
13 self.d.addBoth(self.testDone)
14
15 def testDone(self, r):
16 if self.instance:
17 self.instance.transport.loseConnection()
18 return r
19
20 def onAuthOK(self):
21 self.d.callback(True)
22
23 def onAuthFailed(self):
24 self.d.callback(False)
25
26
27 @deferred(timeout=5.0)
28 def test_NTLMv1_auth_SMB1():
29 def result(auth_passed):
30 assert auth_passed
31
32 smb_structs.SUPPORT_SMB2 = False
33 info = getConnectionInfo()
34 factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False)
35 factory.d.addCallback(result)
36 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
37 return factory.d
38
39
40 @deferred(timeout=5.0)
41 def test_NTLMv2_auth_SMB1():
42 def result(auth_passed):
43 assert auth_passed
44
45 smb_structs.SUPPORT_SMB2 = False
46 info = getConnectionInfo()
47 factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
48 factory.d.addCallback(result)
49 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
50 return factory.d
51
52
53 @deferred(timeout=5.0)
54 def test_NTLMv1_auth_SMB2():
55 def result(auth_passed):
56 assert auth_passed
57
58 smb_structs.SUPPORT_SMB2 = True
59 info = getConnectionInfo()
60 factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False)
61 factory.d.addCallback(result)
62 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
63 return factory.d
64
65
66 @deferred(timeout=5.0)
67 def test_NTLMv2_auth_SMB2():
68 def result(auth_passed):
69 assert auth_passed
70
71 smb_structs.SUPPORT_SMB2 = True
72 info = getConnectionInfo()
73 factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
74 factory.d.addCallback(result)
75 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
76 return factory.d
+0
-99
python3/tests/SMBTwistedTests/test_createdeletedirectory.py less more
0 # -*- coding: utf-8 -*-
1
2 import os, random, time
3 from nose.twistedtools import reactor, deferred
4 from twisted.internet import defer
5 from smb.SMBProtocol import SMBProtocolFactory
6 from smb import smb_structs
7 from .util import getConnectionInfo
8
9
10 class DirectoryFactory(SMBProtocolFactory):
11
12 def __init__(self, *args, **kwargs):
13 SMBProtocolFactory.__init__(self, *args, **kwargs)
14 self.d = defer.Deferred()
15 self.d.addBoth(self.testDone)
16 self.service_name = ''
17 self.path = ''
18
19 def testDone(self, r):
20 if self.instance:
21 self.instance.transport.loseConnection()
22 return r
23
24 def createDone(self, result):
25 d = self.listPath(self.service_name, os.path.dirname(self.path.replace('/', os.sep)))
26 d.addCallback(self.listComplete)
27 d.addErrback(self.d.errback)
28
29 def listComplete(self, entries):
30 names = [e.filename for e in entries]
31 assert os.path.basename(self.path.replace('/', os.sep)) in names
32
33 d = self.deleteDirectory(self.service_name, self.path)
34 d.addCallback(self.deleteDone)
35 d.addErrback(self.d.errback)
36
37 def deleteDone(self, result):
38 d = self.listPath(self.service_name, os.path.dirname(self.path.replace('/', os.sep)))
39 d.addCallback(self.list2Complete)
40 d.addErrback(self.d.errback)
41
42 def list2Complete(self, entries):
43 names = [e.filename for e in entries]
44 assert os.path.basename(self.path.replace('/', os.sep)) not in names
45 self.d.callback(True)
46
47 def onAuthOK(self):
48 d = self.createDirectory(self.service_name, self.path)
49 d.addCallback(self.createDone)
50 d.addErrback(self.d.errback)
51
52 def onAuthFailed(self):
53 self.d.errback('Auth failed')
54
55
56 @deferred(timeout=15.0)
57 def test_english_directory_SMB1():
58 info = getConnectionInfo()
59 smb_structs.SUPPORT_SMB2 = False
60
61 factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
62 factory.service_name = 'smbtest'
63 factory.path = os.sep + 'TestDir %d-%d' % ( time.time(), random.randint(0, 1000) )
64 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
65 return factory.d
66
67 @deferred(timeout=15.0)
68 def test_english_directory_SMB2():
69 info = getConnectionInfo()
70 smb_structs.SUPPORT_SMB2 = True
71
72 factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
73 factory.service_name = 'smbtest'
74 factory.path = os.sep + 'TestDir %d-%d' % ( time.time(), random.randint(0, 1000) )
75 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
76 return factory.d
77
78 @deferred(timeout=15.0)
79 def test_unicode_directory_SMB1():
80 info = getConnectionInfo()
81 smb_structs.SUPPORT_SMB2 = False
82
83 factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
84 factory.service_name = 'smbtest'
85 factory.path = os.sep + '文件夹创建 %d-%d' % ( time.time(), random.randint(0, 1000) )
86 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
87 return factory.d
88
89 @deferred(timeout=15.0)
90 def test_unicode_directory_SMB2():
91 info = getConnectionInfo()
92 smb_structs.SUPPORT_SMB2 = True
93
94 factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
95 factory.service_name = 'smbtest'
96 factory.path = os.sep + '文件夹创建 %d-%d' % ( time.time(), random.randint(0, 1000) )
97 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
98 return factory.d
+0
-39
python3/tests/SMBTwistedTests/test_echo.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from .util import getConnectionInfo
5
6
7 class EchoFactory(SMBProtocolFactory):
8
9 def __init__(self, *args, **kwargs):
10 SMBProtocolFactory.__init__(self, *args, **kwargs)
11 self.d = defer.Deferred()
12 self.d.addBoth(self.testDone)
13 self.echo_data = 'This is an echo test'
14
15 def testDone(self, r):
16 if self.instance:
17 self.instance.transport.loseConnection()
18 return r
19
20 def onAuthOK(self):
21 def cb(data):
22 assert data == self.echo_data
23 self.d.callback(True)
24
25 d = self.echo(self.echo_data)
26 d.addCallback(cb)
27 d.addErrback(self.d.errback)
28
29 def onAuthFailed(self):
30 self.d.errback('Auth failed')
31
32
33 @deferred(timeout=15.0)
34 def test_echo():
35 info = getConnectionInfo()
36 factory = EchoFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
37 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
38 return factory.d
+0
-100
python3/tests/SMBTwistedTests/test_getattributes.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from smb import smb_structs
5 from util import getConnectionInfo
6
7
8 class GetAttributesFactory(SMBProtocolFactory):
9
10 def __init__(self, *args, **kwargs):
11 SMBProtocolFactory.__init__(self, *args, **kwargs)
12 self.d = defer.Deferred()
13 self.d.addBoth(self.testDone)
14 self.path = ''
15 self.is_directory = False
16
17 def testDone(self, r):
18 if self.instance:
19 self.instance.transport.loseConnection()
20 return r
21
22 def onAuthOK(self):
23 def cb(info):
24 assert info.isDirectory == self.is_directory
25 self.d.callback(True)
26
27 d = self.getAttributes('smbtest', self.path, timeout = 15)
28 d.addCallback(cb)
29 d.addErrback(self.d.errback)
30
31 def onAuthFailed(self):
32 self.d.errback('Auth failed')
33
34
35 @deferred(timeout=15.0)
36 def test_getAttributes_SMB1_test1():
37 info = getConnectionInfo()
38 smb_structs.SUPPORT_SMB2 = False
39
40 factory = GetAttributesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
41 factory.path = '/Test Folder with Long Name/'
42 factory.is_directory = True
43 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
44 return factory.d
45
46 @deferred(timeout=15.0)
47 def test_getAttributes_SMB1_test2():
48 info = getConnectionInfo()
49 smb_structs.SUPPORT_SMB2 = False
50
51 factory = GetAttributesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
52 factory.path = '/rfc1001.txt'
53 factory.is_directory = False
54 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
55 return factory.d
56
57 @deferred(timeout=15.0)
58 def test_getAttributes_SMB1_test3():
59 info = getConnectionInfo()
60 smb_structs.SUPPORT_SMB2 = False
61
62 factory = GetAttributesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
63 factory.path = u'/\u6d4b\u8bd5\u6587\u4ef6\u5939'
64 factory.is_directory = True
65 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
66 return factory.d
67
68 @deferred(timeout=15.0)
69 def test_getAttributes_SMB2_test1():
70 info = getConnectionInfo()
71 smb_structs.SUPPORT_SMB2 = True
72
73 factory = GetAttributesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
74 factory.path = '/Test Folder with Long Name/'
75 factory.is_directory = True
76 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
77 return factory.d
78
79 @deferred(timeout=15.0)
80 def test_getAttributes_SMB2_test2():
81 info = getConnectionInfo()
82 smb_structs.SUPPORT_SMB2 = True
83
84 factory = GetAttributesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
85 factory.path = '/rfc1001.txt'
86 factory.is_directory = False
87 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
88 return factory.d
89
90 @deferred(timeout=15.0)
91 def test_getAttributes_SMB2_test3():
92 info = getConnectionInfo()
93 smb_structs.SUPPORT_SMB2 = True
94
95 factory = GetAttributesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
96 factory.path = u'/\u6d4b\u8bd5\u6587\u4ef6\u5939'
97 factory.is_directory = True
98 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
99 return factory.d
+0
-56
python3/tests/SMBTwistedTests/test_listpath.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from smb import smb_structs
5 from .util import getConnectionInfo
6
7
8 class ListPathFactory(SMBProtocolFactory):
9
10 def __init__(self, *args, **kwargs):
11 SMBProtocolFactory.__init__(self, *args, **kwargs)
12 self.d = defer.Deferred()
13 self.d.addBoth(self.testDone)
14
15 def testDone(self, r):
16 if self.instance:
17 self.instance.transport.loseConnection()
18 return r
19
20 def onAuthOK(self):
21 def cb(results):
22 filenames = [( r.filename, r.isDirectory ) for r in results]
23 assert ( '\u6d4b\u8bd5\u6587\u4ef6\u5939', True ) in filenames # Test non-English folder names
24 assert ( 'Test Folder with Long Name', True ) in filenames # Test long English folder names
25 assert ( 'TestDir1', True ) in filenames # Test short English folder names
26 assert ( 'Implementing CIFS - SMB.html', False ) in filenames # Test long English file names
27 assert ( 'rfc1001.txt', False ) in filenames # Test short English file names
28
29 self.d.callback(True)
30
31 d = self.listPath('smbtest', '/', timeout = 15)
32 d.addCallback(cb)
33 d.addErrback(self.d.errback)
34
35 def onAuthFailed(self):
36 self.d.errback('Auth failed')
37
38
39 @deferred(timeout=15.0)
40 def test_listPath_SMB1():
41 info = getConnectionInfo()
42 smb_structs.SUPPORT_SMB2 = False
43
44 factory = ListPathFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
45 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
46 return factory.d
47
48 @deferred(timeout=15.0)
49 def test_listPath_SMB2():
50 info = getConnectionInfo()
51 smb_structs.SUPPORT_SMB2 = True
52
53 factory = ListPathFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
54 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
55 return factory.d
+0
-51
python3/tests/SMBTwistedTests/test_listshares.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from smb import smb_structs
5 from .util import getConnectionInfo
6
7
8 class ListSharesFactory(SMBProtocolFactory):
9
10 def __init__(self, *args, **kwargs):
11 SMBProtocolFactory.__init__(self, *args, **kwargs)
12 self.d = defer.Deferred()
13 self.d.addBoth(self.testDone)
14
15 def testDone(self, r):
16 if self.instance:
17 self.instance.transport.loseConnection()
18 return r
19
20 def onAuthOK(self):
21 def cb(results):
22 assert 'smbtest' in [r.name.lower() for r in results]
23 self.d.callback(True)
24 self.instance.transport.loseConnection()
25
26 d = self.listShares(timeout = 15)
27 d.addCallback(cb)
28 d.addErrback(self.d.errback)
29
30 def onAuthFailed(self):
31 self.d.errback('Auth failed')
32
33
34 @deferred(timeout=15.0)
35 def test_listshares_SMB1():
36 info = getConnectionInfo()
37 smb_structs.SUPPORT_SMB2 = False
38
39 factory = ListSharesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
40 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
41 return factory.d
42
43 @deferred(timeout=15.0)
44 def test_listshares_SMB2():
45 info = getConnectionInfo()
46 smb_structs.SUPPORT_SMB2 = True
47
48 factory = ListSharesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
49 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
50 return factory.d
+0
-57
python3/tests/SMBTwistedTests/test_listsnapshots.py less more
0
1 from nose.twistedtools import reactor, deferred
2 from twisted.internet import defer
3 from smb.SMBProtocol import SMBProtocolFactory
4 from smb import smb_structs
5 from .util import getConnectionInfo
6
7
8 class ListSnapshotsFactory(SMBProtocolFactory):
9
10 def __init__(self, *args, **kwargs):
11 SMBProtocolFactory.__init__(self, *args, **kwargs)
12 self.d = defer.Deferred()
13 self.d.addBoth(self.testDone)
14 self.service_name = None
15 self.path = None
16
17 def testDone(self, r):
18 if self.instance:
19 self.instance.transport.loseConnection()
20 return r
21
22 def onAuthOK(self):
23 def cb(results):
24 assert len(results) > 0
25 self.d.callback(True)
26 self.instance.transport.loseConnection()
27
28 d = self.listSnapshots(self.service_name, self.path, timeout = 15)
29 d.addCallback(cb)
30 d.addErrback(self.d.errback)
31
32 def onAuthFailed(self):
33 self.d.errback('Auth failed')
34
35
36 @deferred(timeout=15.0)
37 def test_listshares_SMB1():
38 info = getConnectionInfo()
39 smb_structs.SUPPORT_SMB2 = False
40
41 factory = ListSnapshotsFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
42 factory.service_name = 'smbtest'
43 factory.path = '/rfc1001.txt'
44 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
45 return factory.d
46
47 @deferred(timeout=15.0)
48 def test_listshares_SMB2():
49 info = getConnectionInfo()
50 smb_structs.SUPPORT_SMB2 = True
51
52 factory = ListSnapshotsFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
53 factory.service_name = 'smbtest'
54 factory.path = '/rfc1001.txt'
55 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
56 return factory.d
+0
-174
python3/tests/SMBTwistedTests/test_rename.py less more
0 # -*- coding: utf-8 -*-
1
2 import os, random, time
3 from io import StringIO
4 from nose.twistedtools import reactor, deferred
5 from twisted.internet import defer
6 from smb.SMBProtocol import SMBProtocolFactory
7 from smb import smb_structs
8 from .util import getConnectionInfo
9
10
11 class RenameFactory(SMBProtocolFactory):
12
13 def __init__(self, *args, **kwargs):
14 SMBProtocolFactory.__init__(self, *args, **kwargs)
15 self.d = defer.Deferred()
16 self.d.addBoth(self.testDone)
17 self.service = ''
18 self.new_path = ''
19 self.old_path = ''
20
21 def testDone(self, r):
22 if self.instance:
23 self.instance.transport.loseConnection()
24 return r
25
26 def pathCreated(self, result):
27 d = self.listPath(self.service, os.path.dirname(self.old_path.replace('/', os.sep)))
28 d.addCallback(self.listComplete)
29 d.addErrback(self.d.errback)
30
31 def listComplete(self, entries):
32 filenames = [e.filename for e in entries]
33 assert os.path.basename(self.old_path.replace('/', os.sep)) in filenames
34 assert os.path.basename(self.new_path.replace('/', os.sep)) not in filenames
35
36 d = self.rename(self.service, self.old_path, self.new_path)
37 d.addCallback(self.renameComplete)
38 d.addErrback(self.d.errback)
39
40 def renameComplete(self, result):
41 d = self.listPath(self.service, os.path.dirname(self.new_path.replace('/', os.sep)))
42 d.addCallback(self.list2Complete)
43 d.addErrback(self.d.errback)
44
45 def list2Complete(self, entries):
46 filenames = [e.filename for e in entries]
47 assert os.path.basename(self.new_path.replace('/', os.sep)) in filenames
48 assert os.path.basename(self.old_path.replace('/', os.sep)) not in filenames
49 self.cleanup()
50
51 def onAuthFailed(self):
52 self.d.errback('Auth failed')
53
54
55 class RenameFileFactory(RenameFactory):
56
57 def onAuthOK(self):
58 d = self.storeFile(self.service, self.old_path, StringIO('Rename file test'))
59 d.addCallback(self.pathCreated)
60 d.addErrback(self.d.errback)
61
62 def cleanup(self):
63 d = self.deleteFiles(self.service, self.new_path)
64 d.chainDeferred(self.d)
65
66
67 class RenameDirectoryFactory(RenameFactory):
68
69 def onAuthOK(self):
70 d = self.createDirectory(self.service, self.old_path)
71 d.addCallback(self.pathCreated)
72 d.addErrback(self.d.errback)
73
74 def cleanup(self):
75 d = self.deleteDirectory(self.service, self.new_path)
76 d.chainDeferred(self.d)
77
78
79 @deferred(timeout=30.0)
80 def test_rename_english_file_SMB1():
81 info = getConnectionInfo()
82 smb_structs.SUPPORT_SMB2 = False
83
84 factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
85 factory.service = 'smbtest'
86 factory.old_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
87 factory.new_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
88 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
89 return factory.d
90
91 @deferred(timeout=30.0)
92 def test_rename_english_file_SMB2():
93 info = getConnectionInfo()
94 smb_structs.SUPPORT_SMB2 = True
95
96 factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
97 factory.service = 'smbtest'
98 factory.old_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
99 factory.new_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
100 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
101 return factory.d
102
103 @deferred(timeout=30.0)
104 def test_rename_unicode_file_SMB1():
105 info = getConnectionInfo()
106 smb_structs.SUPPORT_SMB2 = False
107
108 factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
109 factory.service = 'smbtest'
110 factory.old_path = '/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
111 factory.new_path = '/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
112 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
113 return factory.d
114
115 @deferred(timeout=30.0)
116 def test_rename_unicode_file_SMB2():
117 info = getConnectionInfo()
118 smb_structs.SUPPORT_SMB2 = True
119
120 factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
121 factory.service = 'smbtest'
122 factory.old_path = '/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
123 factory.new_path = '/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) )
124 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
125 return factory.d
126
127 @deferred(timeout=30.0)
128 def test_rename_english_directory_SMB1():
129 info = getConnectionInfo()
130 smb_structs.SUPPORT_SMB2 = False
131
132 factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
133 factory.service = 'smbtest'
134 factory.old_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) )
135 factory.new_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) )
136 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
137 return factory.d
138
139 @deferred(timeout=30.0)
140 def test_rename_english_directory_SMB2():
141 info = getConnectionInfo()
142 smb_structs.SUPPORT_SMB2 = True
143
144 factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
145 factory.service = 'smbtest'
146 factory.old_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) )
147 factory.new_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) )
148 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
149 return factory.d
150
151 @deferred(timeout=30.0)
152 def test_rename_unicode_directory_SMB1():
153 info = getConnectionInfo()
154 smb_structs.SUPPORT_SMB2 = False
155
156 factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
157 factory.service = 'smbtest'
158 factory.old_path = '/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) )
159 factory.new_path = '/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) )
160 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
161 return factory.d
162
163 @deferred(timeout=30.0)
164 def test_rename_unicode_directory_SMB2():
165 info = getConnectionInfo()
166 smb_structs.SUPPORT_SMB2 = True
167
168 factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
169 factory.service = 'smbtest'
170 factory.old_path = '/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) )
171 factory.new_path = '/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) )
172 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
173 return factory.d
+0
-278
python3/tests/SMBTwistedTests/test_retrievefile.py less more
0 # -*- coding: utf-8 -*-
1
2 import os, tempfile
3 from nose.twistedtools import reactor, deferred
4 from twisted.internet import defer
5 from smb.SMBProtocol import SMBProtocolFactory
6 from smb import smb_structs
7 from .util import getConnectionInfo
8
9 try:
10 import hashlib
11 def MD5(): return hashlib.md5()
12 except ImportError:
13 import md5
14 def MD5(): return md5.new()
15
16
17 class RetrieveFileFactory(SMBProtocolFactory):
18
19 def __init__(self, *args, **kwargs):
20 SMBProtocolFactory.__init__(self, *args, **kwargs)
21 self.d = defer.Deferred()
22 self.d.addBoth(self.testDone)
23 self.temp_fh = tempfile.NamedTemporaryFile(prefix = 'pysmbtest-')
24 self.service = ''
25 self.path = ''
26 self.digest = ''
27 self.offset = 0
28 self.max_length = -1
29 self.filesize = 0
30
31 def testDone(self, r):
32 if self.instance:
33 self.instance.transport.loseConnection()
34 return r
35
36 def fileRetrieved(self, write_result):
37 file_obj, file_attributes, file_size = write_result
38 assert file_obj == self.temp_fh
39
40 md = MD5()
41 filesize = 0
42 self.temp_fh.seek(0)
43 while True:
44 s = self.temp_fh.read(8192)
45 if not s:
46 break
47 md.update(s)
48 filesize += len(s)
49
50 assert self.filesize == filesize
51 assert md.hexdigest() == self.digest
52
53 self.temp_fh.close()
54 self.d.callback(True)
55 self.instance.transport.loseConnection()
56
57 def onAuthOK(self):
58 assert self.service
59 assert self.path
60
61 d = self.retrieveFileFromOffset(self.service, self.path, self.temp_fh, self.offset, self.max_length, timeout = 15)
62 d.addCallback(self.fileRetrieved)
63 d.addErrback(self.d.errback)
64
65 def onAuthFailed(self):
66 self.d.errback('Auth failed')
67
68
69 @deferred(timeout=30.0)
70 def test_retr_multiplereads_SMB1():
71 # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes)
72 info = getConnectionInfo()
73 smb_structs.SUPPORT_SMB2 = False
74
75 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
76 factory.service = 'smbtest'
77 factory.path = '/rfc1001.txt'
78 factory.digest = '5367c2bbf97f521059c78eab65309ad3'
79 factory.filesize = 158437
80 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
81 return factory.d
82
83 @deferred(timeout=30.0)
84 def test_retr_multiplereads_SMB2():
85 # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes)
86 info = getConnectionInfo()
87 smb_structs.SUPPORT_SMB2 = True
88
89 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
90 factory.service = 'smbtest'
91 factory.path = '/rfc1001.txt'
92 factory.digest = '5367c2bbf97f521059c78eab65309ad3'
93 factory.filesize = 158437
94 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
95 return factory.d
96
97 @deferred(timeout=30.0)
98 def test_retr_longfilename_SMB1():
99 # Test file retrieval that has a long English filename
100 info = getConnectionInfo()
101 smb_structs.SUPPORT_SMB2 = False
102
103 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
104 factory.service = 'smbtest'
105 factory.path = '/Implementing CIFS - SMB.html'
106 factory.digest = '671c5700d279fcbbf958c1bba3c2639e'
107 factory.filesize = 421269
108 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
109 return factory.d
110
111 @deferred(timeout=30.0)
112 def test_retr_longfilename_SMB2():
113 # Test file retrieval that has a long English filename
114 info = getConnectionInfo()
115 smb_structs.SUPPORT_SMB2 = True
116
117 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
118 factory.service = 'smbtest'
119 factory.path = '/Implementing CIFS - SMB.html'
120 factory.digest = '671c5700d279fcbbf958c1bba3c2639e'
121 factory.filesize = 421269
122 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
123 return factory.d
124
125 @deferred(timeout=30.0)
126 def test_retr_unicodefilename_SMB1():
127 # Test file retrieval that has a long non-English filename inside a folder with a non-English name
128 info = getConnectionInfo()
129 smb_structs.SUPPORT_SMB2 = False
130
131 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
132 factory.service = 'smbtest'
133 factory.path = '/测试文件夹/垃圾文件.dat'
134 factory.digest = '8a44c1e80d55e91c92350955cdf83442'
135 factory.filesize = 256000
136 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
137 return factory.d
138
139 @deferred(timeout=30.0)
140 def test_retr_unicodefilename_SMB2():
141 # Test file retrieval that has a long non-English filename inside a folder with a non-English name
142 info = getConnectionInfo()
143 smb_structs.SUPPORT_SMB2 = True
144
145 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
146 factory.service = 'smbtest'
147 factory.path = '/测试文件夹/垃圾文件.dat'
148 factory.digest = '8a44c1e80d55e91c92350955cdf83442'
149 factory.filesize = 256000
150 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
151 return factory.d
152
153 @deferred(timeout=30.0)
154 def test_retr_offset_SMB1():
155 # Test file retrieval from offset to EOF
156 info = getConnectionInfo()
157 smb_structs.SUPPORT_SMB2 = False
158
159 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
160 factory.service = 'smbtest'
161 factory.path = '/测试文件夹/垃圾文件.dat'
162 factory.digest = 'a141bd8024571ce7cb5c67f2b0d8ea0b'
163 factory.filesize = 156000
164 factory.offset = 100000
165 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
166 return factory.d
167
168 @deferred(timeout=30.0)
169 def test_retr_offset_SMB2():
170 # Test file retrieval from offset to EOF
171 info = getConnectionInfo()
172 smb_structs.SUPPORT_SMB2 = True
173
174 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
175 factory.service = 'smbtest'
176 factory.path = '/测试文件夹/垃圾文件.dat'
177 factory.digest = 'a141bd8024571ce7cb5c67f2b0d8ea0b'
178 factory.filesize = 156000
179 factory.offset = 100000
180 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
181 return factory.d
182
183 @deferred(timeout=30.0)
184 def test_retr_offset_and_biglimit_SMB1():
185 # Test file retrieval from offset with a big max_length
186 info = getConnectionInfo()
187 smb_structs.SUPPORT_SMB2 = False
188
189 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
190 factory.service = 'smbtest'
191 factory.path = '/测试文件夹/垃圾文件.dat'
192 factory.digest = '83b7afd7c92cdece3975338b5ca0b1c5'
193 factory.filesize = 100000
194 factory.offset = 100000
195 factory.max_length = 100000
196 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
197 return factory.d
198
199 @deferred(timeout=30.0)
200 def test_retr_offset_and_biglimit_SMB2():
201 # Test file retrieval from offset with a big max_length
202 info = getConnectionInfo()
203 smb_structs.SUPPORT_SMB2 = True
204
205 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
206 factory.service = 'smbtest'
207 factory.path = '/测试文件夹/垃圾文件.dat'
208 factory.digest = '83b7afd7c92cdece3975338b5ca0b1c5'
209 factory.filesize = 100000
210 factory.offset = 100000
211 factory.max_length = 100000
212 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
213 return factory.d
214
215 @deferred(timeout=30.0)
216 def test_retr_offset_and_smalllimit_SMB1():
217 # Test file retrieval from offset with a small max_length
218 info = getConnectionInfo()
219 smb_structs.SUPPORT_SMB2 = False
220
221 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
222 factory.service = 'smbtest'
223 factory.path = '/测试文件夹/垃圾文件.dat'
224 factory.digest = '746f60a96b39b712a7b6e17ddde19986'
225 factory.filesize = 10
226 factory.offset = 100000
227 factory.max_length = 10
228 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
229 return factory.d
230
231 @deferred(timeout=30.0)
232 def test_retr_offset_and_smalllimit_SMB2():
233 # Test file retrieval from offset with a small max_length
234 info = getConnectionInfo()
235 smb_structs.SUPPORT_SMB2 = True
236
237 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
238 factory.service = 'smbtest'
239 factory.path = '/测试文件夹/垃圾文件.dat'
240 factory.digest = '746f60a96b39b712a7b6e17ddde19986'
241 factory.filesize = 10
242 factory.offset = 100000
243 factory.max_length = 10
244 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
245 return factory.d
246
247 @deferred(timeout=30.0)
248 def test_retr_offset_and_zerolimit_SMB1():
249 # Test file retrieval from offset to EOF with max_length=0
250 info = getConnectionInfo()
251 smb_structs.SUPPORT_SMB2 = False
252
253 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
254 factory.service = 'smbtest'
255 factory.path = '/测试文件夹/垃圾文件.dat'
256 factory.digest = 'd41d8cd98f00b204e9800998ecf8427e'
257 factory.filesize = 0
258 factory.offset = 100000
259 factory.max_length = 0
260 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
261 return factory.d
262
263 @deferred(timeout=30.0)
264 def test_retr_offset_and_zerolimit_SMB2():
265 # Test file retrieval from offset to EOF with max_length=0
266 info = getConnectionInfo()
267 smb_structs.SUPPORT_SMB2 = True
268
269 factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
270 factory.service = 'smbtest'
271 factory.path = '/测试文件夹/垃圾文件.dat'
272 factory.digest = 'd41d8cd98f00b204e9800998ecf8427e'
273 factory.filesize = 0
274 factory.offset = 100000
275 factory.max_length = 0
276 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
277 return factory.d
+0
-141
python3/tests/SMBTwistedTests/test_storefile.py less more
0 # -*- coding: utf-8 -*-
1
2 import os, time, random
3 from io import StringIO
4 from nose.twistedtools import reactor, deferred
5 from twisted.internet import defer
6 from smb.SMBProtocol import SMBProtocolFactory
7 from smb import smb_structs
8 from .util import getConnectionInfo
9
10 try:
11 import hashlib
12 def MD5(): return hashlib.md5()
13 except ImportError:
14 import md5
15 def MD5(): return md5.new()
16
17 class StoreFilesFactory(SMBProtocolFactory):
18 """
19 A super test factory that tests store file, list files, retrieve file and delete file functionlities in sequence.
20 """
21
22 TEST_FILENAME = os.path.join(os.path.dirname(__file__), os.pardir, 'SupportFiles', 'binary.dat')
23 TEST_FILESIZE = 256000
24 TEST_DIGEST = 'bb6303f76e29f354b6fdf6ef58587e48'
25
26 def __init__(self, *args, **kwargs):
27 SMBProtocolFactory.__init__(self, *args, **kwargs)
28 self.d = defer.Deferred()
29 self.d.addBoth(self.testDone)
30 self.service_name = ''
31 self.filename = ''
32
33 def testDone(self, r):
34 if self.instance:
35 self.instance.transport.loseConnection()
36 return r
37
38 def storeComplete(self, result):
39 file_obj, filesize = result
40 file_obj.close()
41 assert filesize == self.TEST_FILESIZE
42
43 d = self.listPath(self.service_name, os.path.dirname(self.filename.replace('/', os.sep)))
44 d.addCallback(self.listComplete)
45 d.addErrback(self.d.errback)
46
47 def listComplete(self, entries):
48 filenames = [e.filename for e in entries]
49 assert os.path.basename(self.filename.replace('/', os.sep)) in filenames
50
51 for entry in entries:
52 if os.path.basename(self.filename.replace('/', os.sep)) == entry.filename:
53 # The following asserts will fail if the remote machine's time is not in sync with the test machine's time
54 assert abs(entry.create_time - time.time()) < 3
55 assert abs(entry.last_access_time - time.time()) < 3
56 assert abs(entry.last_write_time - time.time()) < 3
57 assert abs(entry.last_attr_change_time - time.time()) < 3
58 break
59
60 d = self.retrieveFile(self.service_name, self.filename, StringIO())
61 d.addCallback(self.retrieveComplete)
62 d.addErrback(self.d.errback)
63
64 def retrieveComplete(self, result):
65 file_obj, file_attributes, file_size = result
66
67 md = MD5()
68 md.update(file_obj.getvalue())
69 file_obj.close()
70
71 assert file_size == self.TEST_FILESIZE
72 assert md.hexdigest() == self.TEST_DIGEST
73
74 d = self.deleteFiles(self.service_name, self.filename)
75 d.addCallback(self.deleteComplete)
76 d.addErrback(self.d.errback)
77
78 def deleteComplete(self, result):
79 d = self.listPath(self.service_name, os.path.dirname(self.filename.replace('/', os.sep)))
80 d.addCallback(self.list2Complete)
81 d.addErrback(self.d.errback)
82
83 def list2Complete(self, entries):
84 filenames = [e.filename for e in entries]
85 assert os.path.basename(self.filename.replace('/', os.sep)) not in filenames
86 self.d.callback(True)
87 self.instance.transport.loseConnection()
88
89 def onAuthOK(self):
90 d = self.storeFile(self.service_name, self.filename, open(self.TEST_FILENAME, 'rb'))
91 d.addCallback(self.storeComplete)
92 d.addErrback(self.d.errback)
93
94 def onAuthFailed(self):
95 self.d.errback('Auth failed')
96
97
98 @deferred(timeout=30.0)
99 def test_store_long_filename_SMB1():
100 info = getConnectionInfo()
101 smb_structs.SUPPORT_SMB2 = False
102
103 factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
104 factory.service_name = 'smbtest'
105 factory.filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
106 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
107 return factory.d
108
109 @deferred(timeout=30.0)
110 def test_store_long_filename_SMB2():
111 info = getConnectionInfo()
112 smb_structs.SUPPORT_SMB2 = True
113
114 factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
115 factory.service_name = 'smbtest'
116 factory.filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
117 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
118 return factory.d
119
120 @deferred(timeout=30.0)
121 def test_store_unicode_filename_SMB1():
122 info = getConnectionInfo()
123 smb_structs.SUPPORT_SMB2 = False
124
125 factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
126 factory.service_name = 'smbtest'
127 factory.filename = os.sep + '上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
128 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
129 return factory.d
130
131 @deferred(timeout=30.0)
132 def test_store_unicode_filename_SMB2():
133 info = getConnectionInfo()
134 smb_structs.SUPPORT_SMB2 = True
135
136 factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True)
137 factory.service_name = 'smbtest'
138 factory.filename = os.sep + '上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) )
139 reactor.connectTCP(info['server_ip'], info['server_port'], factory)
140 return factory.d
+0
-19
python3/tests/SMBTwistedTests/util.py less more
0
1 import os
2 from configparser import SafeConfigParser
3
4 def getConnectionInfo():
5 config_filename = os.path.join(os.path.dirname(__file__), os.path.pardir, 'connection.ini')
6 cp = SafeConfigParser()
7 cp.read(config_filename)
8
9 info = {
10 'server_name': cp.get('server', 'name'),
11 'server_ip': cp.get('server', 'ip'),
12 'server_port': cp.getint('server', 'port'),
13 'client_name': cp.get('client', 'name'),
14 'user': cp.get('user', 'name'),
15 'password': cp.get('user', 'password'),
16 }
17 return info
18
22 name = SERVER
33 ip = 192.168.1.1
44 port = 139
5 direct_port = 445
56
67 [client]
78 name = TESTCLIENT
python3/tests/smbtest.7z less more
Binary diff not shown
0 from smb.utils.md4 import MD4
1
2 _md4_test_data = [
3 ("", 0x31d6cfe0d16ae931b73c59d7e0c089c0),
4 ("a", 0xbde52cb31de33e46245e05fbdbd6fb24),
5 ("abc", 0xa448017aaf21d8525fc10ae87aa6729d),
6 ("message digest", 0xd9130a8164549fe818874806e1c7014b),
7 ("abcdefghijklmnopqrstuvwxyz", 0xd79e1c308aa5bbcdeea8ed63df412da9),
8 (
9 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
10 0x043f8582f241db351ce627e153e7f0e4),
11 (
12 "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
13 0xe33b4ddc9c38f2199c3e7b164fcc0536),
14 ("The quick brown fox jumps over the lazy dog", 0x1bee69a46ba811185c194762abaeae90),
15 ("The quick brown fox jumps over the lazy cog", 0xb86e130ce7028da59e672d56ad0113df)
16 ]
17
18
19 def test_md4():
20 for input_data, expected_result in _md4_test_data:
21 expected_digest = expected_result.to_bytes(16, byteorder="big", signed=False)
22 md4 = MD4()
23 md4.update(input_data)
24 computed_digest = md4.digest()
25 assert computed_digest == expected_digest
0 import binascii
1
2 from smb import security_descriptors as sd
3 from smb import smb_constants as sc
4
5
6 def test_sid_string_representation():
7 sid = sd.SID(1, 5, [2, 3, 4])
8 assert str(sid) == "S-1-5-2-3-4"
9 sid = sd.SID(1, 2**32 + 3, [])
10 assert str(sid) == "S-1-0x100000003"
11 sid = sd.SID(1, 2**32, [3, 2, 1])
12 assert str(sid) == "S-1-0x100000000-3-2-1"
13
14
15 def test_sid_binary_parsing():
16 raw_sid = binascii.unhexlify(b"""
17 01 05 00 00 00 00 00 05 15 00 00 00 de 53 c1 2a
18 2a 4f da ca c1 79 a6 32 b1 04 00 00
19 """.translate(None, b' \n'))
20 assert str(sd.SID.from_bytes(raw_sid)) == "S-1-5-21-717312990-3403304746-849770945-1201"
21 raw_sid += b"garbage"
22 assert str(sd.SID.from_bytes(raw_sid)) == "S-1-5-21-717312990-3403304746-849770945-1201"
23 sid, tail = sd.SID.from_bytes(raw_sid, return_tail=True)
24 assert str(sid) == "S-1-5-21-717312990-3403304746-849770945-1201"
25 assert tail == b"garbage"
26
27
28 def test_ace_binary_parsing():
29 raw_ace = binascii.unhexlify(b"""
30 00 10 24 00 ff 01 1f 00 01 05 00 00 00 00 00 05
31 15 00 00 00 de 53 c1 2a 2a 4f da ca c1 79 a6 32
32 6e 04 00 00
33 """.translate(None, b' \n'))
34 ace = sd.ACE.from_bytes(raw_ace)
35 assert str(ace.sid) == "S-1-5-21-717312990-3403304746-849770945-1134"
36 assert ace.type == sd.ACE_TYPE_ACCESS_ALLOWED
37 assert ace.flags == sd.ACE_FLAG_INHERITED
38 assert ace.mask == (sc.SYNCHRONIZE | sc.WRITE_OWNER | sc.WRITE_DAC
39 | sc.READ_CONTROL | sc.DELETE | sc.FILE_READ_DATA
40 | sc.FILE_WRITE_DATA | sc.FILE_APPEND_DATA
41 | sc.FILE_READ_EA | sc.FILE_WRITE_EA | sc.FILE_EXECUTE
42 | sc.FILE_DELETE_CHILD | sc.FILE_READ_ATTRIBUTES
43 | sc.FILE_WRITE_ATTRIBUTES)
44 assert not ace.additional_data
45
46 raw_ace = binascii.unhexlify(b"""
47 00 13 18 00 a9 00 12 00 01 02 00 00 00 00 00 05
48 20 00 00 00 21 02 00 00
49 """.translate(None, b' \n'))
50 ace = sd.ACE.from_bytes(raw_ace)
51 assert str(ace.sid) == "S-1-5-32-545"
52 assert ace.type == sd.ACE_TYPE_ACCESS_ALLOWED
53 assert ace.flags == (sd.ACE_FLAG_INHERITED | sd.ACE_FLAG_CONTAINER_INHERIT
54 | sd.ACE_FLAG_OBJECT_INHERIT)
55 assert ace.mask == (sc.SYNCHRONIZE | sc.READ_CONTROL | sc.FILE_READ_DATA
56 | sc.FILE_READ_EA | sc.FILE_EXECUTE
57 | sc.FILE_READ_ATTRIBUTES)
58 assert not ace.additional_data
59
60 raw_ace = binascii.unhexlify(b"""
61 01 03 24 00 a9 00 02 00 01 05 00 00 00 00 00 05
62 15 00 00 00 de 53 c1 2a 2a 4f da ca c1 79 a6 32
63 6c 04 00 00
64 """.translate(None, b' \n'))
65 ace = sd.ACE.from_bytes(raw_ace)
66 assert str(ace.sid) == "S-1-5-21-717312990-3403304746-849770945-1132"
67 assert ace.type == sd.ACE_TYPE_ACCESS_DENIED
68 assert ace.flags == (sd.ACE_FLAG_CONTAINER_INHERIT
69 | sd.ACE_FLAG_OBJECT_INHERIT)
70 assert ace.mask == (sc.READ_CONTROL | sc.FILE_READ_DATA | sc.FILE_READ_EA
71 | sc.FILE_EXECUTE | sc.FILE_READ_ATTRIBUTES)
72 assert not ace.additional_data
73
74
75 def test_acl_binary_parsing():
76 raw_acl = binascii.unhexlify(b"""
77 02 00 70 00 04 00 00 00 00 10 18 00 89 00 10 00
78 01 02 00 00 00 00 00 05 20 00 00 00 21 02 00 00
79 00 10 14 00 ff 01 1f 00 01 01 00 00 00 00 00 05
80 12 00 00 00 00 10 18 00 ff 01 1f 00 01 02 00 00
81 00 00 00 05 20 00 00 00 20 02 00 00 00 10 24 00
82 ff 01 1f 00 01 05 00 00 00 00 00 05 15 00 00 00
83 de 53 c1 2a 2a 4f da ca c1 79 a6 32 b1 04 00 00
84 """.translate(None, b' \n'))
85 acl = sd.ACL.from_bytes(raw_acl)
86 assert acl.revision == 2
87 assert len(acl.aces) == 4
88
89 ace = acl.aces[0]
90 assert ace.type == sd.ACE_TYPE_ACCESS_ALLOWED
91 assert str(ace.sid) == "S-1-5-32-545"
92 assert ace.flags == sd.ACE_FLAG_INHERITED
93 assert ace.mask == (sc.SYNCHRONIZE | sc.FILE_READ_DATA | sc.FILE_READ_EA
94 | sc.FILE_READ_ATTRIBUTES)
95
96 ace = acl.aces[3]
97 assert ace.type == sd.ACE_TYPE_ACCESS_ALLOWED
98 assert str(ace.sid) == "S-1-5-21-717312990-3403304746-849770945-1201"
99 assert ace.flags == sd.ACE_FLAG_INHERITED
100 assert ace.mask == (sc.SYNCHRONIZE | sc.WRITE_OWNER | sc.WRITE_DAC
101 | sc.READ_CONTROL | sc.DELETE | sc.FILE_READ_DATA
102 | sc.FILE_WRITE_DATA | sc.FILE_APPEND_DATA
103 | sc.FILE_READ_EA | sc.FILE_WRITE_EA | sc.FILE_EXECUTE
104 | sc.FILE_DELETE_CHILD | sc.FILE_READ_ATTRIBUTES
105 | sc.FILE_WRITE_ATTRIBUTES)
106
107
108 def test_descriptor_binary_parsing():
109 raw_descriptor = binascii.unhexlify(b"""
110 01 00 04 84 14 00 00 00 30 00 00 00 00 00 00 00
111 4c 00 00 00 01 05 00 00 00 00 00 05 15 00 00 00
112 de 53 c1 2a 2a 4f da ca c1 79 a6 32 b1 04 00 00
113 01 05 00 00 00 00 00 05 15 00 00 00 de 53 c1 2a
114 2a 4f da ca c1 79 a6 32 01 02 00 00 02 00 70 00
115 04 00 00 00 00 10 18 00 89 00 10 00 01 02 00 00
116 00 00 00 05 20 00 00 00 21 02 00 00 00 10 14 00
117 ff 01 1f 00 01 01 00 00 00 00 00 05 12 00 00 00
118 00 10 18 00 ff 01 1f 00 01 02 00 00 00 00 00 05
119 20 00 00 00 20 02 00 00 00 10 24 00 ff 01 1f 00
120 01 05 00 00 00 00 00 05 15 00 00 00 de 53 c1 2a
121 2a 4f da ca c1 79 a6 32 b1 04 00 00
122 """.translate(None, b' \n'))
123 descriptor = sd.SecurityDescriptor.from_bytes(raw_descriptor)
124 assert descriptor.flags == (sd.SECURITY_DESCRIPTOR_SELF_RELATIVE
125 | sd.SECURITY_DESCRIPTOR_DACL_PRESENT
126 | sd.SECURITY_DESCRIPTOR_DACL_AUTO_INHERITED)
127 assert descriptor.dacl is not None
128 assert descriptor.sacl is None
129 assert str(descriptor.owner) == "S-1-5-21-717312990-3403304746-849770945-1201"
130 assert str(descriptor.group) == "S-1-5-21-717312990-3403304746-849770945-513"
131
132 acl = descriptor.dacl
133 assert acl.revision == 2
134 assert len(acl.aces) == 4
135 assert str(acl.aces[0].sid) == sd.SID_BUILTIN_USERS
136 assert str(acl.aces[1].sid) == sd.SID_LOCAL_SYSTEM
137 assert str(acl.aces[2].sid) == sd.SID_BUILTIN_ADMINISTRATORS
138 assert str(acl.aces[3].sid) == "S-1-5-21-717312990-3403304746-849770945-1201"
0 [egg_info]
1 tag_build =
2 tag_date = 0
3
77
88 setup(
99 name = "pysmb",
10 version = "1.1.19",
10 version = "1.2.8",
1111 author = "Michael Teo",
1212 author_email = "[email protected]",
1313 license = "zlib/libpng",
0 twisted>=15.0.0
1 pyasn1>=0.3.0
55
66 Notes
77 -----
8 * Note that you need to pass in a valid hostname or IP address for the host component of the URL.
9 Do not use the Windows/NetBIOS machine name for the host component.
8 * The host component of the URL must be one of the following:
9
10 * A fully-qualified hostname that can be resolved by your local DNS service. Example: myserver.test.com
11 * An IP address. Example: 192.168.1.1
12 * A comma-separated string "<NBName>,<IP>" where *<NBName>* is the Windows/NetBIOS machine name for remote SMB service, and *<IP>* is the service's IP address. Example: MYSERVER,192.168.1.1
13
1014 * The first component of the path in the URL points to the name of the shared folder.
1115 Subsequent path components will point to the directory/folder of the file.
1216 * You can retrieve and upload files, but you cannot delete files/folders or create folders.
1519 Example
1620 -------
1721
18 The following code snippet illustrates file retrieval.::
22 The following code snippet illustrates file retrieval with Python 2.::
1923
2024 # -*- coding: utf-8 -*-
2125 import urllib2
3337 # Process fh2 like a file-like object and then close it.
3438 fh2.close()
3539
36 The following code snippet illustrates file upload. You need to provide a file-like object for the *data* parameter in the *open()* method::
40 The following code snippet illustrates file upload with Python 2. You need to provide a file-like object for the *data* parameter in the *open()* method::
3741
3842 import urllib2
3943 from smb.SMBHandler import SMBHandler
4549
4650 # Reading from fh will only return an empty string
4751 fh.close()
52
53
54 The following code snippet illustrates file retrieval with Python 3.::
55
56 import urllib
57 from smb.SMBHandler import SMBHandler
58
59 director = urllib.request.build_opener(SMBHandler)
60 fh = director.open('smb://myuserID:[email protected]/sharedfolder/rfc1001.txt')
61
62 # Process fh like a file-like object and then close it.
63 fh.close()
64
65 # For paths/files with unicode characters, simply pass in the URL as an unicode string
66 fh2 = director.open(u'smb://myuserID:[email protected]/sharedfolder/测试文件夹/垃圾文件.dat')
67
68 # Process fh2 like a file-like object and then close it.
69 fh2.close()
70
71 The following code snippet illustrates file upload with Python 3. You need to provide a file-like object for the *data* parameter in the *open()* method::
72
73 import urllib
74 from smb.SMBHandler import SMBHandler
75
76 file_fh = open('local_file.dat', 'rb')
77
78 director = urllib.request.build_opener(SMBHandler)
79 fh = director.open('smb://myuserID:[email protected]/sharedfolder/upload_file.dat', data = file_fh)
80
81 # Reading from fh will only return an empty string
82 fh.close()
0
1 Security Descriptors
2 ====================
3
4 .. module:: smb.security_descriptors
5 :synopsis: Data structures used in Windows security descriptors.
6
7 This module implements security descriptors, and associated data
8 structures, as specified in `[MS-DTYP]`_.
9
10 .. autoclass:: SID
11 :members:
12
13 .. autoclass:: ACE
14 :members:
15
16 .. autoclass:: ACL
17 :members:
18
19 .. autoclass:: SecurityDescriptor
20 :members:
21
22 .. _[MS-DTYP]: https://msdn.microsoft.com/en-us/library/cc230273.aspx
00 # -*- coding: utf-8 -*-
1 #
2 # pysmb documentation build configuration file, created by
3 # sphinx-quickstart on Sun Dec 18 15:54:40 2011.
4 #
5 # This file is execfile()d with the current directory set to its containing dir.
6 #
7 # Note that not all possible configuration values are present in this
8 # autogenerated file.
91 #
102 # All configuration values have a default; values that are commented out
113 # serve to show the default.
168 # add these directories to sys.path here. If the directory is relative to the
179 # documentation root, use os.path.abspath to make it absolute, like shown here.
1810 #sys.path.insert(0, os.path.abspath('.'))
19 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'python2'))
11 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'python3'))
2012
2113 # -- General configuration -----------------------------------------------------
2214
4133
4234 # General information about the project.
4335 project = u'pysmb'
44 copyright = u'2001-2015, Michael Teo http://miketeo.net/'
36 copyright = u'2001-2021, Michael Teo https://miketeo.net/'
4537
4638 # The version info for the project you're documenting, acts as replacement for
4739 # |version| and |release|, also used in various other places throughout the
4840 # built documents.
4941 #
5042 # The short X.Y version.
51 version = '1.1.18'
43 version = '1.2.8'
5244 # The full version, including alpha/beta/rc tags.
53 release = '1.1.18'
45 release = '1.2.8'
5446
5547 # The language for content autogenerated by Sphinx. Refer to documentation
5648 # for a list of supported languages.
1313 3. Write your own loop handling method to read data from the socket. Once data have been read, call *feedData* method with the parameter.
1414 The *feedData* method has its own internal buffer, so it can accept incomplete NetBIOS session packet data.
1515 4. Override
16
1617 * *onAuthOK* method to include your own operations to perform when authentication is successful. You can initiate file operations in this method.
1718 * *onAuthFailed* method to include your own processing on what to do when authentication fails. You can report this as an error, or to try a different NTLM authentication algorithm (*use_ntlm_v2* parameter in the constructor).
1819 * *onNMBSessionFailed* method to include your own processing on what to do when pysmb fails to setup the NetBIOS session with the remote server. Usually, this is due to a wrong *remote_name* parameter in the constructor.
0 .. pysmb documentation master file, created by
1 sphinx-quickstart on Sun Dec 18 15:54:40 2011.
2 You can adapt this file completely to your liking, but it should at least
3 contain the root `toctree` directive.
4
50 Welcome to pysmb's documentation!
61 =================================
72
83 pysmb is a pure Python implementation of the client-side SMB/CIFS protocol (SMB1 and SMB2) which is the underlying protocol
94 that facilitates file sharing and printing between Windows machines, as well as with Linux machines via the Samba server application.
10 pysmb is developed in Python 2.4.6, Python 2.7.1 and Python 3.2.3 and has been tested against shared folders on Windows XP SP3, Windows Vista, Windows 7 and Samba 3.x.
5 pysmb is developed in Python 2.7.x and Python 3.8.x and has been tested against shared folders on Windows 7, Windows 10 and Samba 4.x.
116
12 The latest version of pysmb is always available at the pysmb project page at `miketeo.net <http://miketeo.net/wp/index.php/projects/pysmb>`_.
7 The latest version of pysmb is always available at the pysmb project page at `miketeo.net <http://miketeo.net/projects/pysmb>`_.
138
149 License
1510 -------
8984 As a software developer who is looking to modify pysmb so that you can integrate it to other network frameworks:
9085 * Read :doc:`extending`
9186
87 If you are upgrading from older pysmb versions:
88 * Read :doc:`upgrading`
9289
9390
9491 Indices and tables
10097
10198 api/*
10299 extending
100 upgrading
103101
104102 * :ref:`genindex`
105103 * :ref:`search`
0 Upgrading from older pysmb versions
1 ====================================
2
3 This page documents the improvements and changes to the API that could be incompatible with previous releases.
4
5 pysmb 1.2.0
6 -----------
7 - Add new `delete_matching_folders` parameter to `deleteFiles()` method in SMBProtocolFactory and SMBConnection
8 class to support deletion of sub-folders. If you are passing timeout parameter to the `deleteFiles()` method
9 in your application, please switch to using named parameter for timeout.
10
11 pysmb 1.1.28
12 ------------
13 - SharedFile instances returned from the `listPath()` method now has a new property
14 `file_id` attribute which represents the file reference number given by the remote SMB server.
15
16 pysmb 1.1.26
17 ------------
18 - SMBConnection class can now be used as a context manager
19
20 pysmb 1.1.25
21 ------------
22 - SharedFile class has a new property `isNormal` which will be True if the file is a
23 'normal' file. pysmb defines a 'normal' file as a file entry that is not
24 read-only, not hidden, not system, not archive and not a directory;
25 it ignores other attributes like compression, indexed, sparse, temporary and encryption.
26 - `listPath()` method in SMBProtocolFactory and SMBConnection class will now include
27 'normal' files by default if you do not specify the `search` parameter.
28
29 pysmb 1.1.20
30 ------------
31 - A new method `getSecurity()` was added to SMBConnection and SMBProtocolFactory class.
32
33 pysmb 1.1.15
34 ------------
35 - Add new `truncate` parameter to `storeFileFromOffset()` in SMBProtocolFactory and SMBConnection
36 class to support truncation of the file before writing. If you are passing timeout parameter
37 to the `storeFileFromOffset()` method in your application, please switch to using named parameter for timeout.
38
39 pysmb 1.1.11
40 ------------
41 - A new method `storeFileFromOffset()` was added to SMBConnection and SMBProtocolFactory class.
42
43 pysmb 1.1.10
44 ------------
45 - A new method `getAttributes()` was added to SMBConnection and SMBProtocolFactory class
46 - SharedFile class has a new property `isReadOnly` to indicate the file is read-only on the remote filesystem.
47
48 pysmb 1.1.2
49 -----------
50 - `queryIPForName()` method in nmb.NetBIOS and nmb.NBNSProtocol class will now return only the server machine name and ignore workgroup names.
51
52 pysmb 1.0.3
53 -----------
54 - Two new methods were added to NBNSProtocol class: `queryIPForName()` and `NetBIOS.queryIPForName()`
55 to support querying for a machine's NetBIOS name at the given IP address.
56 - A new method `retrieveFileFromOffset()` was added to SMBProtocolFactory and SMBConnection
57 to support finer control of file retrieval operation.
58
59 pysmb 1.0.0
60 -----------
61 pysmb was completely rewritten in version 1.0.0.
62 If you are upgrading from pysmb 0.x, you most likely have to rewrite your application for the new 1.x API.