
    Vhh                         d dl mZmZmZ eZdZdZdZd dl	Z	d dl
mZ d dlmZmZ d dlmZ d d	lmZmZ d
ZdZdZdZdZdZdZdZd Zd!dZd Zd"dZd Z d Z!d Z"d Z#d Z$d Z%d Z&d Z'd Z(d Z)e*d k(  r e)        yy)#    )absolute_importdivisionprint_functiona`  
---
module: ome_firmware
short_description: Update firmware on PowerEdge devices and its components through OpenManage Enterprise
version_added: "2.0.0"
description: This module updates the firmware of PowerEdge devices and all its components through OpenManage Enterprise.
extends_documentation_fragment:
  - dellemc.openmanage.ome_auth_options
options:
  device_service_tag:
    description:
      - List of service tags of the targeted devices.
      - Either I(device_id) or I(device_service_tag) can be used individually or together.
      - This option is mutually exclusive with I(device_group_names) and I(devices).
    type: list
    elements: str
  device_id:
    description:
      - List of ids of the targeted device.
      - Either I(device_id) or I(device_service_tag) can be used individually or together.
      - This option is mutually exclusive with I(device_group_names) and I(devices).
    type: list
    elements: int
  device_group_names:
    description:
      - Enter the name of the device group that contains the devices on which firmware needs to be updated.
      - This option is mutually exclusive with I(device_id) and I(device_service_tag).
    type: list
    elements: str
  dup_file:
    description:
      - "The path of the Dell Update Package (DUP) file that contains the firmware or drivers required to update the
      target system device or individual device components."
      - This is mutually exclusive with I(baseline_name), I(components), and I(devices).
    type: path
  baseline_name:
    description:
      - Enter the baseline name to update the firmware of all devices or list of devices that are not complaint.
      - This option is mutually exclusive with I(dup_file) and I(device_group_names).
    type: str
  components:
    description:
      - List of components to be updated.
      - If not provided, all components applicable are considered.
      - This option is case sensitive.
      - This is applicable to I(device_service_tag), I(device_id), and I(baseline_name).
    type: list
    default: []
    elements: str
  devices:
    description:
      - This option allows to select components on each device for firmware update.
      - This option is mutually exclusive with I(dup_file), I(device_group_names), I(device_id), and I(device_service_tag).
    type: list
    elements: dict
    suboptions:
      id:
        type: int
        description:
          - The id of the target device to be updated.
          - This option is mutually exclusive with I(service_tag).
      service_tag:
        type: str
        description:
          - The service tag of the target device to be updated.
          - This option is mutually exclusive with I(id).
      components:
        description: The target components to be updated. If not specified, all applicable device components are considered.
        type: list
        default: []
        elements: str
  schedule:
    type: str
    description:
      - Select the schedule for the firmware update.
      - if C(StageForNextReboot) is chosen, the firmware will be staged and updated during the next reboot
        of the target device.
      - if C(RebootNow) will apply the firmware updates immediately.
    choices:
      - RebootNow
      - StageForNextReboot
    default: RebootNow
  reboot_type:
    version_added: '8.3.0'
    type: str
    description:
      - This option provides the choices to reboot the server immediately after the firmware update.
      - This is applicable when I(schedule) is C(RebootNow).
      - C(GracefulRebootForce) performs a graceful reboot with forced shutdown.
      - C(GracefulReboot) performs a graceful reboot without forced shutdown.
      - C(PowerCycle) performs a power cycle for a hard reset on the device.
    choices:
      - GracefulReboot
      - GracefulRebootForce
      - PowerCycle
    default: GracefulRebootForce
requirements:
    - "python >= 3.9.6"
author:
    - "Felix Stephen (@felixs88)"
    - "Jagadeesh N V (@jagadeeshnv)"
    - "Abhishek Sinha (@ABHISHEK-SINHA10)"
notes:
    - Run this module from a system that has direct access to Dell OpenManage Enterprise.
    - This module supports C(check_mode).
a  
---
- name: Update firmware from DUP file using device ids
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    device_id:
      - 11111
      - 22222
    dup_file: "/path/Chassis-System-Management_Firmware_6N9WN_WN64_1.00.01_A00.EXE"

- name: Update firmware from a DUP file using a device service tags
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    device_service_tag:
      - KLBR111
      - KLBR222
    dup_file: "/path/Network_Firmware_NTRW0_WN64_14.07.07_A00-00_01.EXE"

- name: Update firmware from a DUP file using a device group names
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    device_group_names:
      - servers
    dup_file: "/path/BIOS_87V69_WN64_2.4.7.EXE"

- name: Update firmware using baseline name
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    baseline_name: baseline_devices

- name: Stage firmware for the next reboot using baseline name
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    baseline_name: baseline_devices
    schedule: StageForNextReboot

- name: "Update firmware using baseline name and components."
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    baseline_name: baseline_devices
    components:
      - BIOS

- name: Update firmware of device components from a DUP file using a device ids in a baseline
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    baseline_name: baseline_devices
    device_id:
      - 11111
      - 22222
    components:
      - iDRAC with Lifecycle Controller

- name: Update firmware of device components from a baseline using a device service tags under a baseline
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    baseline_name: baseline_devices
    device_service_tag:
      - KLBR111
      - KLBR222
    components:
      - IOM-SAS

- name: Update firmware using baseline name with a device id and required components
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    baseline_name: baseline_devices
    devices:
      - id: 12345
        components:
          - Lifecycle Controller
      - id: 12346
        components:
          - Enterprise UEFI Diagnostics
          - BIOS

- name: "Update firmware using baseline name with a device service tag and required components."
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    baseline_name: baseline_devices
    devices:
      - service_tag: ABCDE12
        components:
          - PERC H740P Adapter
          - BIOS
      - service_tag: GHIJK34
        components:
          - OS Drivers Pack

- name: "Update firmware using baseline name with a device service tag or device id and required components."
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    baseline_name: baseline_devices
    devices:
      - service_tag: ABCDE12
        components:
          - BOSS-S1 Adapter
          - PowerEdge Server BIOS
      - id: 12345
        components:
          - iDRAC with Lifecycle Controller

- name: "Update firmware using baseline name and components and perform Powercycle."
  dellemc.openmanage.ome_firmware:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    baseline_name: baseline_devices
    components:
      - BIOS
    reboot_type: PowerCycle
a  
---
msg:
  type: str
  description: "Overall firmware update status."
  returned: always
  sample: Successfully submitted the firmware update job.
update_status:
  type: dict
  description: The firmware update job and progress details from the OME.
  returned: success
  sample: {
    'LastRun': None,
    'CreatedBy': 'user',
    'Schedule': 'startnow',
    'LastRunStatus': {
      'Id': 1111,
      'Name': 'NotRun'
    },
    'Builtin': False,
    'Editable': True,
    'NextRun': None,
    'JobStatus': {
      'Id': 1111,
      'Name': 'New'
    },
    'JobName': 'Firmware Update Task',
    'Visible': True,
    'State': 'Enabled',
    'JobDescription': 'dup test',
    'Params': [{
      'Value': 'true',
      'Key': 'signVerify',
      'JobId': 11111}, {
      'Value': 'false',
      'Key': 'stagingValue',
      'JobId': 11112}, {
      'Value': 'false',
      'Key': 'complianceUpdate',
      'JobId': 11113}, {
      'Value': 'INSTALL_FIRMWARE',
      'Key': 'operationName',
      'JobId': 11114}],
    'Targets': [{
      'TargetType': {
      'Id': 1000,
      'Name': 'DEVICE'},
      'Data': 'DCIM:INSTALLED#701__NIC.Mezzanine.1A-1-1=1234567654321',
      'Id': 11115,
      'JobId': 11116}],
    'StartTime': None,
    'UpdatedBy': None,
    'EndTime': None,
    'Id': 11117,
    'JobType': {
      'Internal': False,
      'Id': 5,
      'Name': 'Update_Task'}
}
error_info:
  description: Details of the HTTP Error.
  returned: on HTTP error
  type: dict
  sample: {
    "error": {
      "code": "Base.1.0.GeneralError",
      "message": "A general error has occurred. See ExtendedInfo for more information.",
      "@Message.ExtendedInfo": [
        {
          "MessageId": "GEN1234",
          "RelatedProperties": [],
          "Message": "Unable to process the request because an error occurred.",
          "MessageArgs": [],
          "Severity": "Critical",
          "Resolution": "Retry the operation. If the issue persists, contact your system administrator."
        }
      ]
    }
  }
N)SSLError)RestOMEOmeAnsibleModule)ConnectionError)URLError	HTTPErrorz4UpdateService/Baselines({0})/DeviceComplianceReportszUpdateService/BaselineszIFirmware update task initiated from OpenManage Ansible Module collectionszzNo changes found to be applied. Either there are no updates present or components specified are not found in the baseline.z!Failed to read compliance report.zdParameter 'dup_file' to be provided along with 'device_id'|'device_service_tag'|'device_group_names'z(Unable to get applicable components DUP.zChanges found to be applied.c                 l    di }}| j                  d||      }|j                  dk(  r|j                  }|S )z1Spawns an update job and tracks it to completion.zJobService/JobsPOST)data   )invoke_requeststatus_code	json_data)rest_objjob_payloadjob_urijob_detailsjob_resps        s/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/dellemc/openmanage/plugins/modules/ome_firmware.pyspawn_update_jobr   r  sA    ,b[G&&vw[&IHs"((    c           	      |   | j                  d      }||j                  d       ddd}|j                  d   }dd	d
d||   d
ddd
g}|dk(  r,dddd}|j                  d   }	|j                  d||	   d
       ddt        dd|dd||d}
||
d   j                  ddj                  |d         d
       |
d   j                  ddj                  |d         d
       |
d   j                  d dj                  |d!         d
       |
d   j                  d"dd
       |
S |
d   j                  dd"dd#       |
S )$z8Formulate the payload to initiate a firmware update job.Update_Taskz Unable to fetch the job type Id.msgtruefalse)StageForNextReboot	RebootNowscheduleoperationNameINSTALL_FIRMWARE)KeyValuestagingValue
signVerifyr"   123
PowerCycleGracefulRebootGracefulRebootForcereboot_type
rebootTyper   zFirmware Update TaskstartnowEnabledIdName)r6   JobNameJobDescriptionScheduleStateJobTypeTargetsParamsr>   complianceReportIdz{0}baseline_idrepositoryIdrepo_id	catalogId
catalog_idcomplianceUpdate)JobIdr&   r'   )get_job_type_id	fail_jsonparamsappendFW_JOB_DESCformat)r   moduletarget_databaselineresp
stage_dictr#   rI   reboot_dictr1   payloads              r   job_payload_for_updaterT   {  s   ##M2D|?@(.WEJ}}Z(H%0BC$z(/CD"V46F ;%(),.13 mmM2l[5MNO2%:dM'JG   )=U]^kUlHm!no  %,,xXaObBc!de  u||HUaLb?c!de  );f!MN N 	  15GRY!Z[Nr   c                    g }d}ddd}| j                  d|||d      }|j                  dk(  r|j                  }t        |d         }|D ]u  }	|	d	   d
   D ]h  }
i }|	d   |d<   dj	                  |
d   |      |d<   i |d<   t        |	d	   d         |d   d<   t        |	d	   d         |d   d<   |j                  |       j w |S |j                  t               |S )z<Get the target array to be used in spawning jobs for update.z6UpdateService/Actions/UpdateService.GetSingleDupReportzapplication/jsonzContent-TypeAcceptr   <   )r   headersapi_timeout   SingleUpdateReportFileTokenDeviceReport
ComponentsDeviceIdr6   z{0}={1}ComponentSourceNameData
TargetTypeDeviceTypeIdDeviceTypeNamer7   r   )	r   r   r   strrL   intrJ   rH   APPLICABLE_DUP)r   dup_payloadrM   rN   dup_urlrY   dup_respdup_data
file_tokendevice	componenttemp_maps               r   get_applicable_componentsrp     s0   KFG1=OPG&&vw[/6B ' HHs"%%%BCD
 	-F#N3LA -	!'
!3#,#3#3I>S4TV`#a )+&/26.3I.3Y/Z&t,14VN5KL\5]1^&v.""8,-	-  	^,r   c           	      $   g g g | d}|,|j                  dt        t        t        |            i       |S |,|j                  dt        t        t        |            i       |S |*|j                  dt        t        t        |            i       |S )z+Returns the DUP applicability JSON payload.)SingleUpdateReportBaselineSingleUpdateReportGroupSingleUpdateReportTargetsr\   rt   rs   rr   )updatelistmaprf   )rl   
device_ids	group_idsbaseline_idsdup_applicability_payloads        r   get_dup_applicability_payloadr|     s    ?A<>>@@J!L !((*EtCPSU_L`Ga)bc
 %$	 
	!((*CT#cS\J]E^)_` %$ 
	!!((*FSQTVbMcHd)ef$$r   c           	         d}ddd}d\  }}|j                   d   }t        |d      5 }|j                         }| j                  d|||dd	
      }|j                  dk(  rd}t        |j                        }n/|j                  dj                  ||j                   d                ddd       ||fS # 1 sw Y   ||fS xY w)z,Upload DUP file to OME and get a file token.z.UpdateService/Actions/UpdateService.UploadFilezapplication/octet-streamrV   )FNdup_filerbr   d   F)r   rY   rZ   dumpr[   TzUnable to upload {0} to {1}hostnamer   N)	rI   openreadr   r   re   r   rH   rL   )	r   rM   
upload_urirY   upload_successtokenr~   rS   responses	            r   upload_dup_filer     s    AJ9E_`G'NE}}Z(H	h	 l,,.**6:GU\7: + H3&!N**+E!>!E!EhPVP]P]^hPi!jkl 5  l 5  s   A>B22B>c           	         g }| j                  d      }|j                  d      r t        |d   D cg c]  }t        |d         |d   f c}      }t	        t        |      }g }|D ]  }	|	|j                         v r|j                  |	       '|	|j                         v rTt        |j                               t        |j                               j                  |	         }
|j                  |
       |j                  |	        |r9|j                  dj                  dj                  t        |                         ||fS |j                  d       |fS c c}w )	zBGetting the list of device ids filtered from the device inventory.zDeviceService/Devicesreport_listr6   DeviceServiceTagztUnable to complete the operation because the entered target device service tag(s) or device id(s) '{0}' are invalid.,r   z!Failed to fetch the device facts.)get_all_report_detailsgetdictre   rw   keysrJ   valuesrv   indexrH   rL   joinset)r   rM   device_id_tags	device_idrP   rm   device_respdevice_tagsinvalid_tagstagidss              r   get_device_idsr     s^   I**+BCDxxZ^_lZmnPVS.7I0JKno#~. 	)Ck&&((  %**,,;++-.tK4F4F4H/I/O/OPS/TU  %##C(	) AAGQTUaQbHcAd  f
 k!! 	@Ak!!# os   Ec           	         | j                  d      }|j                  j                  d      }|d   r|d   D cg c]  }|D ]  }|d   |k(  s|d     }}}t        t	        |            t        t	        |            k7  r9|j                  dj                  dj                  t	        |                         S c c}}w )	7Getting the list of group ids filtered from the groups.zGroupService/Groupsdevice_group_namesr   r7   r6   zcUnable to complete the operation because the entered target device group name(s) '{0}' are invalid.r   r   )r   rI   r   lenr   rH   rL   r   )r   rM   rP   
group_namegrpgrpnamegrp_idss          r   get_group_idsr     s    **+@AD""#78JM(,](;p:pY\]cYdhoYo3t9p9pps:3s7|#44**0&#j/1J*K  M N qs   B=	B=c                 8   | j                  t              }|j                  j                  d      i }}|d   rP|d   D ]#  }|d   |k(  s|d   |d<   |d   |d<   |d   |d	<   % |s!|j	                  d
j                  |             |S |j	                  d       |S )r   baseline_namer   r7   r6   r@   RepositoryIdrB   	CatalogIdrD   z[Unable to complete the operation because the entered target baseline name '{0}' is invalid.r   zYUnable to complete the operation because the entered target baseline name does not exist.)r   BASELINE_URIrI   r   rH   rL   )r   rM   rP   rO   baseline_detailsbses         r   get_baseline_idsr     s    **<8D!'!2!2?!CRHM& 	BC6{h&25d) /.1..A +14[1A .		B
  ))/)9  ;  	 D 	Er   c                 >   d\  }}}}|j                   j                  d      t        | |      }nt        |      }t	        | ||      \  }}|j
                  r|j                  t        d       t        | |      \  }}	|rt        |	|||      }
|
rt        | |
|      }|S )N)NNNNr   Tr   changed)rx   ry   rz   )rI   r   r   _validate_device_attributesr   
check_mode	exit_jsonCHANGES_FOUNDr   r|   rp   )r   rM   rN   rx   ry   rz   r   
id_tag_mapupload_statusr   report_payloads              r   single_dup_updater     s    7M4KY}}-.:!(F3	4V<!/&.!Q
J]D9*8V<M56u_hDPR3HnfUKr   c           	      4   t         j                  |d         }| j                  |      }g }ddg|d   r
g |sE|j                  j	                  d      t        |d   D cg c]  }t        |d         f c}      }|d   D ]  }|d   }	t        |	      |v s|j	                  t        |	      g       |j	                  d      }
|
Ei }g }st        fd|
D              }nt        fd	|
D              }|sx|	|d
<   t        d      j                  |      |d<   |d   |d   d|d<   |j                  |        n|j                  t               |s|j                  t               |j                  r|j                  t        d       |S c c}w )Nr@   UPGRADE	DOWNGRADEr   
componentsr_   ComponentComplianceReportsc              3   6   K   | ]  }|d    v r|d     yw)UpdateAction
SourceNameN ).0icompupdate_actionss     r   	<genexpr>z(baseline_based_update.<locals>.<genexpr>6  s,      )U,1.,A^,S */|)< )Us   c              3   \   K   | ]#  }|d    v r|j                  d      v r|d    % yw)r   r7   r   N)r   )r   r   compsr   s     r   r   z(baseline_based_update.<locals>.<genexpr>9  s=      )H.3N.C~.U*/))F*;u*D */|)< )Hs   ),r6   ;ra   rc   rd   r5   rb   r   Tr   )COMPLIANCE_URIrL   r   rI   r   r   re   rv   r   rJ   rH   COMPLIANCE_READ_FAILr   NO_CHANGES_MSGr   r   )r   rM   rO   dev_comp_mapcompliance_urirP   compliance_report_listdevdvcdev_idcompliance_report	data_dict	comp_listr   r   s                @@r   baseline_based_updater   #  s   #**8M+BCN**>:D-NMMM%%l3E$}J] ^3#c*o"6!> ^_L& 	AC_F6{l*$((Vb9$'GG,H$I!$0 "I "I $( )UJ[ )U %U	 %) )HJ[ )H %H	 !*0	$,/HMM),D	&)9<^9LVYZjVk2l	,/.55i@'	A* 	12!^,]D9!!7 !_s   #Fc                    g }| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }|rY|D ]T  }|j                  d      r!|j                  |j                  d             5|j                  |j                  d             V ||j                  |       ||j                  |       |S )Ndevice_service_tagr   devicesidservice_tag)rI   r   rJ   extend)rM   r   r   r   r   r   s         r   r   r   J  s    N--##$89K!!+.Imm	*G 	>Cwwt}%%cggdm4%%cggm&<=		>
 i(k*r   c                 Z   t        |      }t        | ||      \  }}|j                  j                  d      }i }|rt	        |D cg c]  }||f c}      }|j                  j                  d      }|r|D ]  }|j                  d      r-|j                  d      |t        |j                  d            <   At        |j                               t        |j                               j                  |j                  d               }	|j                  d      |t        |	      <    |S c c}w )Nr   r   r   r   )
r   r   rI   r   r   re   rv   r   r   r   )
r   rM   r   rx   r   r   r   r   r   r   s
             r   get_device_component_mapr   \  s   08N+HfnMJ
MMl+ELZ@cc5\@Amm	*G 	>Cwwt}3677<3HS/0*//+,T*2C2C2E-F-L-LSWWUbMc-de(+(=SW%	>  As   D(c                     | j                   }|j                  d      rSt        |j                  d      |j                  d      |j                  d      g      s| j                  t               y y y )Nr~   r   r   r   r   )rI   r   anyrH   DUP_REQ_MSG)rM   params     r   validate_inputsr   n  s_    MMEyyEIIk*EII6J,KUYYWkMlmn- o r   c                     ddddddddidddddg dddiddd	gdd
dg ddd
ddddiddiddg dddgdgdd	} t        | ddggddgg dg dddgg dgd      }t        |       i d }}	 t        |j                  d      5 }|j                  j	                  d      r't        ||      }t        ||      }t        ||||      }nt        ||      }t        ||||      }t        ||      }d d d        |j#                  d|d        y # 1 sw Y   xY w# t        $ r9}|j                  t        |      t        j                  |             Y d }~^d }~wt         $ r&}|j#                  t        |      d       Y d }~d }~wt$        t&        t(        t*        t,        t.        t0        f$ r%}|j                  t        |             Y d }~d }~ww xY w)!Nrv   re   )typeelementsrf   r   path)r   r   defaultr"   r!   )r   choicesr   r-   r0   r   )r   r   r   )r   r   )r   r   optionsmutually_exclusiverequired_one_of)	r   r   r~   r   r   r   r#   r1   r   r~   r   )r   r   r   )r   r   r   r   )r~   r   r   T)argument_specr   r   supports_check_mode)req_session)rO   )r   
error_info)r   unreachabler   z/Successfully submitted the firmware update job.)r   update_statusr   )r   r   r   rI   r   r   r   r   r   rT   r   r   rH   re   jsonloadr
   r   IOError
ValueErrorr   	TypeErrorr	   AttributeErrorOSError)	specsrM   r   r   r   device_comp_maprN   r   errs	            r   mainr   u  s   '-5A$%8V$'-5A%5RH %"=Q/R_jk %#Z#8: uo &'-5RP
 $9"9 56	
E. $o67j):C2313 !
F F&($#M'V]]5 	D}}  1#3Hf#E ":8V"L3HfFVXgh/&A06;YijK,X{CM	D JZgquv	D 	D  BSX$))C.AA 9SX488Z9o~W^_ 'SX&&'sI   /D A*D0D DD 	G"/EG"F+G.GG__main__)N)NNN)+
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNr   sslr   ?ansible_collections.dellemc.openmanage.plugins.module_utils.omer   r   ansible.module_utils.urlsr	   +ansible.module_utils.six.moves.urllib.errorr
   r   r   r   rK   r   r   r   rg   r   r   rT   rp   r|   r   r   r   r   r   r   r   r   r   r   __name__r   r   r   <module>r	     s    C BiVQfO
d   e 5 K H(Y+: t;. F0%!$"2
($$"N$$.5wp zF r   